]> Creatis software - CreaPhase.git/blob - octave_packages/m/geometry/griddata.m
update packages
[CreaPhase.git] / octave_packages / m / geometry / griddata.m
1 ## Copyright (C) 1999-2012 Kai Habel
2 ##
3 ## This file is part of Octave.
4 ##
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.
9 ##
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.
14 ##
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/>.
18
19 ## -*- texinfo -*-
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})
22 ##
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.
27 ##
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.
30 ##
31 ## The interpolation method can be @code{"nearest"}, @code{"cubic"} or
32 ## @code{"linear"}.  If method is omitted it defaults to @code{"linear"}.
33 ## @seealso{delaunay}
34 ## @end deftypefn
35
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)
40
41 function [rx, ry, rz] = griddata (x, y, z, xi, yi, method)
42
43   if (nargin == 5)
44     method = "linear";
45   endif
46   if (nargin < 5 || nargin > 7)
47     print_usage ();
48   endif
49
50   if (ischar (method))
51     method = tolower (method);
52   endif
53
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)))
57     if (isvector (z))
58       error ("griddata: X, Y, and Z, be vectors of same length");
59     else
60       error ("griddata: lengths of X, Y must match the columns and rows of Z");
61     endif
62   endif
63
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);
67   endif
68
69   if (! size_equal (xi, yi))
70     error ("griddata: XI and YI must be vectors or matrices of same size");
71   endif
72
73   [nr, nc] = size (xi);
74
75   x = x(:);
76   y = y(:);
77   z = z(:);
78
79   ## Triangulate data.
80   tri = delaunay (x, y);
81   zi = NaN (size (xi));
82
83   if (strcmp (method, "cubic"))
84     error ("griddata: cubic interpolation not yet implemented");
85
86   elseif (strcmp (method, "nearest"))
87     ## Search index of nearest point.
88     idx = dsearch (x, y, tri, xi, yi);
89     valid = !isnan (idx);
90     zi(valid) = z(idx(valid));
91
92   elseif (strcmp (method, "linear"))
93     ## Search for every point the enclosing triangle.
94     tri_list = tsearch (x, y, tri, xi(:), yi(:));
95
96     ## Only keep the points within triangles.
97     valid = !isnan (tri_list);
98     tri_list = tri_list(valid);
99     nr_t = rows (tri_list);
100
101     tri = tri(tri_list,:);
102
103     ## Assign x,y,z for each point of triangle.
104     x1 = x(tri(:,1));
105     x2 = x(tri(:,2));
106     x3 = x(tri(:,3));
107
108     y1 = y(tri(:,1));
109     y2 = y(tri(:,2));
110     y3 = y(tri(:,3));
111
112     z1 = z(tri(:,1));
113     z2 = z(tri(:,2));
114     z3 = z(tri(:,3));
115
116     ## Calculate norm vector.
117     N = cross ([x2-x1, y2-y1, z2-z1], [x3-x1, y3-y1, z3-z1]);
118     ## Normalize.
119     N = diag (norm (N, "rows")) \ N;
120
121     ## Calculate D of plane equation
122     ## Ax+By+Cz+D = 0;
123     D = -(N(:,1) .* x1 + N(:,2) .* y1 + N(:,3) .* z1);
124
125     ## Calculate zi by solving plane equation for xi, yi.
126     zi(valid) = -(N(:,1).*xi(:)(valid) + N(:,2).*yi(:)(valid) + D) ./ N(:,3);
127
128   else
129     error ("griddata: unknown interpolation METHOD");
130   endif
131
132   if (nargout == 3)
133     rx = xi;
134     ry = yi;
135     rz = zi;
136   elseif (nargout == 1)
137     rx = zi;
138   elseif (nargout == 0)
139     mesh (xi, yi, zi);
140   endif
141 endfunction
142
143 %!testif HAVE_QHULL
144 %! [xx,yy]=meshgrid(linspace(-1,1,32));
145 %! x = xx(:);
146 %! x = x + 10 * (2 * round(rand(size(x))) - 1) * eps;
147 %! y = yy(:);
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)
154
155 %!demo
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');
162
163 %!demo
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');
170
171 %!demo
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');