scatteredInterpolant: what is linear interpolation in 2d?

8 vues (au cours des 30 derniers jours)
SA-W
SA-W le 1 Juil 2023
Commenté : Torsten le 5 Juil 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.

Réponse acceptée

Matt J
Matt J le 1 Juil 2023
Modifié(e) : Matt J le 1 Juil 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 commentaires
Bruno Luong
Bruno Luong le 5 Juil 2023
Modifié(e) : Bruno Luong le 5 Juil 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
Torsten le 5 Juil 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

Connectez-vous pour commenter.

Plus de réponses (0)

Catégories

En savoir plus sur Interpolation dans Help Center et File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by