1## Copyright (C) 1999, 2000, 2007, 2008, 2009 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## The interpolation points are all @code{(@var{xi}, @var{yi})}. If
26## @var{xi}, @var{yi} are vectors then they are made into a 2D mesh.
28## The interpolation method can be @code{"nearest"}, @code{"cubic"} or
29## @code{"linear"}. If method is omitted it defaults to @code{"linear"}.
33## Author: Kai Habel <kai.habel@gmx.de>
34## Adapted-by: Alexander Barth <barth.alexander@gmail.com>
35## xi and yi are not "meshgridded" if both are vectors
36## of the same size (for compatibility)
38function [rx, ry, rz] = griddata (x, y, z, xi, yi, method)
43 if (nargin < 5 || nargin > 7)
48 method = tolower (method);
50 if (! all (size (x) == size (y) & size (x) == size (z)))
51 error ("griddata: x, y, and z must be vectors of same length");
54 ## Meshgrid xi and yi if they are a row and column vector.
55 if (rows (xi) == 1 && columns (yi) == 1)
56 [xi, yi] = meshgrid (xi, yi);
59 if (! size_equal (xi, yi))
60 error ("griddata: xi and yi must be vectors or matrices of same size");
70 tri = delaunay (x, y);
73 if (strcmp (method, "cubic"))
74 error ("griddata: cubic interpolation not yet implemented");
76 elseif (strcmp (method, "nearest"))
77 ## Search index of nearest point.
78 idx = dsearch (x, y, tri, xi, yi);
80 zi(valid) = z(idx(valid));
82 elseif (strcmp (method, "linear"))
83 ## Search for every point the enclosing triangle.
84 tri_list = tsearch (x, y, tri, xi(:), yi(:));
86 ## Only keep the points within triangles.
87 valid = !isnan (tri_list);
88 tri_list = tri_list(valid);
89 nr_t = rows (tri_list);
91 tri = tri(tri_list,:);
93 ## Assign x,y,z for each point of triangle.
106 ## Calculate norm vector.
107 N = cross ([x2-x1, y2-y1, z2-z1], [x3-x1, y3-y1, z3-z1]);
109 N = diag (norm (N, "rows")) \ N;
111 ## Calculate D of plane equation
113 D = -(N(:,1) .* x1 + N(:,2) .* y1 + N(:,3) .* z1);
115 ## Calculate zi by solving plane equation for xi, yi.
116 zi(valid) = -(N(:,1).*xi(:)(valid) + N(:,2).*yi(:)(valid) + D) ./ N(:,3);
119 error ("griddata: unknown interpolation method");
126 elseif (nargout == 1)
128 elseif (nargout == 0)
134%! [xx,yy]=meshgrid(linspace(-1,1,32));
136%! x = x + 10 * (2 * round(rand(size(x))) - 1) * eps;
138%! y = y + 10 * (2 * round(rand(size(y))) - 1) * eps;
139%! z = sin(2*(x.^2+y.^2));
140%! zz = griddata(x,y,z,xx,yy,'linear');
141%! zz2 = sin(2*(xx.^2+yy.^2));
142%! zz2(isnan(zz)) = NaN;
143%! assert (zz, zz2, 100 * eps)
147%! y=2*rand(size(x))-1;
148%! z=sin(2*(x.^2+y.^2));
149%! [xx,yy]=meshgrid(linspace(-1,1,32));
150%! griddata(x,y,z,xx,yy);
151%! title('nonuniform grid sampled at 100 points');
154%! x=2*rand(1000,1)-1;
155%! y=2*rand(size(x))-1;
156%! z=sin(2*(x.^2+y.^2));
157%! [xx,yy]=meshgrid(linspace(-1,1,32));
158%! griddata(x,y,z,xx,yy);
159%! title('nonuniform grid sampled at 1000 points');
162%! x=2*rand(1000,1)-1;
163%! y=2*rand(size(x))-1;
164%! z=sin(2*(x.^2+y.^2));
165%! [xx,yy]=meshgrid(linspace(-1,1,32));
166%! griddata(x,y,z,xx,yy,'nearest');
167%! title('nonuniform grid sampled at 1000 points with nearest neighbor');