1 ## Copyright (C) 1999-2012 Kai Habel
3 ## This file is part of Octave.
5 ## Octave is free software; you can redistribute it and/or modify it
6 ## under the terms of the GNU General Public License as published by
7 ## the Free Software Foundation; either version 3 of the License, or (at
8 ## your option) any later version.
10 ## Octave is distributed in the hope that it will be useful, but
11 ## WITHOUT ANY WARRANTY; without even the implied warranty of
12 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 ## General Public License for more details.
15 ## You should have received a copy of the GNU General Public License
16 ## along with Octave; see the file COPYING. If not, see
17 ## <http://www.gnu.org/licenses/>.
20 ## @deftypefn {Function File} {@var{zi} =} griddata (@var{x}, @var{y}, @var{z}, @var{xi}, @var{yi}, @var{method})
21 ## @deftypefnx {Function File} {[@var{xi}, @var{yi}, @var{zi}] =} griddata (@var{x}, @var{y}, @var{z}, @var{xi}, @var{yi}, @var{method})
23 ## Generate a regular mesh from irregular data using interpolation.
24 ## The function is defined by @code{@var{z} = f (@var{x}, @var{y})}.
25 ## Inputs @code{@var{x}, @var{y}, @var{z}} are vectors of the same length
26 ## or @code{@var{x}, @var{y}} are vectors and @code{@var{z}} is matrix.
28 ## The interpolation points are all @code{(@var{xi}, @var{yi})}. If
29 ## @var{xi}, @var{yi} are vectors then they are made into a 2-D mesh.
31 ## The interpolation method can be @code{"nearest"}, @code{"cubic"} or
32 ## @code{"linear"}. If method is omitted it defaults to @code{"linear"}.
36 ## Author: Kai Habel <kai.habel@gmx.de>
37 ## Adapted-by: Alexander Barth <barth.alexander@gmail.com>
38 ## xi and yi are not "meshgridded" if both are vectors
39 ## of the same size (for compatibility)
41 function [rx, ry, rz] = griddata (x, y, z, xi, yi, method)
46 if (nargin < 5 || nargin > 7)
51 method = tolower (method);
54 if (isvector (x) && isvector (y) && all ([numel(y), numel(x)] == size (z)))
55 [x, y] = meshgrid (x, y);
56 elseif (! all (size (x) == size (y) & size (x) == size (z)))
58 error ("griddata: X, Y, and Z, be vectors of same length");
60 error ("griddata: lengths of X, Y must match the columns and rows of Z");
64 ## Meshgrid xi and yi if they are a row and column vector.
65 if (rows (xi) == 1 && columns (yi) == 1)
66 [xi, yi] = meshgrid (xi, yi);
69 if (! size_equal (xi, yi))
70 error ("griddata: XI and YI must be vectors or matrices of same size");
80 tri = delaunay (x, y);
83 if (strcmp (method, "cubic"))
84 error ("griddata: cubic interpolation not yet implemented");
86 elseif (strcmp (method, "nearest"))
87 ## Search index of nearest point.
88 idx = dsearch (x, y, tri, xi, yi);
90 zi(valid) = z(idx(valid));
92 elseif (strcmp (method, "linear"))
93 ## Search for every point the enclosing triangle.
94 tri_list = tsearch (x, y, tri, xi(:), yi(:));
96 ## Only keep the points within triangles.
97 valid = !isnan (tri_list);
98 tri_list = tri_list(valid);
99 nr_t = rows (tri_list);
101 tri = tri(tri_list,:);
103 ## Assign x,y,z for each point of triangle.
116 ## Calculate norm vector.
117 N = cross ([x2-x1, y2-y1, z2-z1], [x3-x1, y3-y1, z3-z1]);
119 N = diag (norm (N, "rows")) \ N;
121 ## Calculate D of plane equation
123 D = -(N(:,1) .* x1 + N(:,2) .* y1 + N(:,3) .* z1);
125 ## Calculate zi by solving plane equation for xi, yi.
126 zi(valid) = -(N(:,1).*xi(:)(valid) + N(:,2).*yi(:)(valid) + D) ./ N(:,3);
129 error ("griddata: unknown interpolation METHOD");
136 elseif (nargout == 1)
138 elseif (nargout == 0)
144 %! [xx,yy]=meshgrid(linspace(-1,1,32));
146 %! x = x + 10 * (2 * round(rand(size(x))) - 1) * eps;
148 %! y = y + 10 * (2 * round(rand(size(y))) - 1) * eps;
149 %! z = sin(2*(x.^2+y.^2));
150 %! zz = griddata(x,y,z,xx,yy,'linear');
151 %! zz2 = sin(2*(xx.^2+yy.^2));
152 %! zz2(isnan(zz)) = NaN;
153 %! assert (zz, zz2, 100 * eps)
156 %! x=2*rand(100,1)-1;
157 %! y=2*rand(size(x))-1;
158 %! z=sin(2*(x.^2+y.^2));
159 %! [xx,yy]=meshgrid(linspace(-1,1,32));
160 %! griddata(x,y,z,xx,yy);
161 %! title('nonuniform grid sampled at 100 points');
164 %! x=2*rand(1000,1)-1;
165 %! y=2*rand(size(x))-1;
166 %! z=sin(2*(x.^2+y.^2));
167 %! [xx,yy]=meshgrid(linspace(-1,1,32));
168 %! griddata(x,y,z,xx,yy);
169 %! title('nonuniform grid sampled at 1000 points');
172 %! x=2*rand(1000,1)-1;
173 %! y=2*rand(size(x))-1;
174 %! z=sin(2*(x.^2+y.^2));
175 %! [xx,yy]=meshgrid(linspace(-1,1,32));
176 %! griddata(x,y,z,xx,yy,'nearest');
177 %! title('nonuniform grid sampled at 1000 points with nearest neighbor');