# scatteredInterpolant: what is linear interpolation in 2d?

13 views (last 30 days)
SA-W on 1 Jul 2023
Commented: Torsten on 5 Jul 2023
%coords
supportPts = [3 3; 3.3 3; 3 3.25; 3.3 3.25; 3.6 3; 3.6 3.25; 3 3.5; 3.3 3.5; 3.6 3.5];
%values
Fval = [0 0.1121 0.064604 0.184942 0.233029 0.352622 0.121444 0.206496 0.375685]';
%interpolation object
Interp = scatteredInterpolant(supportPts(:,1),supportPts(:,2),Fval);
%evaluate at center of bottom left element
Interp(3.15, 3.125)
ans = 0.0884
See the above example with nine points that represent four axis-parrallel elements.
I would have expected that the value of the interpoland at the center of the bottom left element is the mean value of the coresponding four corner values, i.e.,
%expected value at (3.15,3.125)
0.25*(0+0.064604+0.184942+0.1121)
ans = 0.0904
but this is clearly not so.
So what interpolation scheme is scatteredInterpoland using (linear) to calculate values in the interior of the elements? At the element boundaries, I double-checked that there is just 1d interpolation involved.
##### 0 CommentsShow -2 older commentsHide -2 older comments

Sign in to comment.

### Accepted Answer

Matt J on 1 Jul 2023
Edited: Matt J on 1 Jul 2023
No, the support points are being divided into triangular elements, not rectangles. It is puzzling that you would be using scatteredInterpolant instead of griddedInterpolant for data like this.
##### 31 CommentsShow 29 older commentsHide 29 older comments
Bruno Luong on 5 Jul 2023
Edited: Bruno Luong on 5 Jul 2023
@SA-W I think the basis functions are not wrong, but finding the reference coordinates of a point in real space and working just with the basis functions on (-1,1)x(-1,1) is an alternative to your bilinearformula(x, y, Z, xq, yq), right?
Right. When I make the comment I overlook the fsolve part to map the rectangle to (-1,1)x(-1x1).
I would never do that. You want to know the formula for bilinear interpolation to understand how it works, and then you use a numerical function that does not provide any formula. Fortunately @Stephen23 give you a big help to figure out the problem of your code.
But more interesting, I just think you approach could be applied where the grid is topological equivalent to generic quadrilateral mesh, such as pixels of some non-linear camera projection (fisheye) and not grided data.
BTW for rectangular gridded the cross-term x*y of the mapping vanish, and essentially the solution of fsolve can be determined separately for x and y, and if you plug the formula together you find my formula, consist, compact and fast to compute.
For quatrilateral I would look for analytical inversion rather than a big fsolve hammer, if it exists.
Torsten on 5 Jul 2023
syms x_left x_right y_low y_high
syms u_left_low u_right_low u_left_high u_right_high
syms x y
% First way
% Linearly interpolate between (x_left,y_low,u_left_low) and (x_right,y_low,u_right_low);
f_low(x) = u_left_low*(x-x_right)/(x_left-x_right) + u_right_low*(x-x_left)/(x_right-x_left);
% Linearly interpolate between (x_left,y_high,u_left_high) and (x_right,y_high,u_right_high);
f_high(x) = u_left_high*(x-x_right)/(x_left-x_right) + u_right_high*(x-x_left)/(x_right-x_left);
% Linearly interpolate between f_low(x) and f_high(x)
f1_inter(x,y) = f_low(x)*(y-y_high)/(y_low-y_high) + f_high(x)*(y-y_low)/(y_high-y_low)
f1_inter(x, y) =
% Second way
% Linearly interpolate between (x_left,y_low,u_left_low) and (x_left,y_high,u_left_high);
f_left(y) = u_left_low*(y-y_high)/(y_low-y_high) + u_left_high*(y-y_low)/(y_high-y_low);
% Linearly interpolate between (x_right,y_low,u_right_low) and (x_right,y_high,u_right_high);
f_right(y) = u_right_low*(y-y_high)/(y_low-y_high) + u_right_high*(y-y_low)/(y_high-y_low);
% Linearly interpolate between f_left(y) and f_right(y)
f2_inter(x,y) = f_left(y)*(x-x_right)/(x_left-x_right) + f_right(y)*(x-x_left)/(x_right-x_left)
f2_inter(x, y) =
x_left = 3;
x_right = 3.3;
y_low = 3;
y_high = 3.25;
u_left_low = 0;
u_right_low = 0.1121;
u_left_high = 0.064604;
u_right_high = 0.184942;
xq = 3.15;
yq = 3.125;
double(subs(f1_inter(xq,yq)))
ans = 0.0904
double(subs(f2_inter(xq,yq)))
ans = 0.0904
xq = 3.2;
yq = 3.2;
double(subs(f1_inter(xq,yq)))
ans = 0.1308
double(subs(f2_inter(xq,yq)))
ans = 0.1308

Sign in to comment.

### Categories

Find more on Interpolation in Help Center and File Exchange

### Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!