Mercurial > octave-nkf
diff scripts/geometry/delaunay.m @ 19198:ba167badef9f
Deprecate delaunay3 and extend delaunay to 3-D inputs.
* NEWS: Announce deprecation of delaunay3. Announce extension of delaunay to
3-D inputs.
* scripts/deprecated/delaunay3.m: Moved from geometry/. Print warning about
deprecation when executing function for the first time.
* scripts/deprecated/module.mk: Add deprecated delaunay3.m to build system.
* scripts/geometry/module.mk: Remove from geometry directory build system
* delaunay.m: Redo docstring to mention 2-D and 3-D inputs.
Overhaul function to accept 3-D inputs. Add %!error input validation tests.
* delaunayn, tetramesh.m: Remove seealso reference to delaunay3.
* geometry.txi, install.txi: Remove delaunay3 from manual.
author | Rik <rik@octave.org> |
---|---|
date | Fri, 26 Sep 2014 09:02:53 -0700 |
parents | d63878346099 |
children | 0e1f5a750d00 |
line wrap: on
line diff
--- a/scripts/geometry/delaunay.m Fri Sep 26 08:54:40 2014 -0700 +++ b/scripts/geometry/delaunay.m Fri Sep 26 09:02:53 2014 -0700 @@ -17,22 +17,32 @@ ## <http://www.gnu.org/licenses/>. ## -*- texinfo -*- -## @deftypefn {Function File} {} delaunay (@var{x}, @var{y}) -## @deftypefnx {Function File} {} delaunay (@var{x}) -## @deftypefnx {Function File} {} delaunay (@dots{}, @var{options}) -## @deftypefnx {Function File} {@var{tri} =} delaunay (@dots{}) -## Compute the Delaunay triangulation for a 2-D set of points. -## The return value @var{tri} is a set of triangles which satisfies the -## Delaunay circum-circle criterion, i.e., only a single data point from -## [@var{x}, @var{y}] is within the circum-circle of the defining triangle. -## The input @var{x} may also be a matrix with two columns where the first -## column contains x-data and the second y-data. +## @deftypefn {Function File} {@var{tri} =} delaunay (@var{x}, @var{y}) +## @deftypefnx {Function File} {@var{tetr} =} delaunay (@var{x}, @var{y}, @var{z}) +## @deftypefnx {Function File} {@var{tri} =} delaunay (@var{x}) +## @deftypefnx {Function File} {@var{tri} =} delaunay (@dots{}, @var{options}) +## Compute the Delaunay triangulation for a 2-D or 3-D set of points. ## -## The set of triangles @var{tri} is a matrix of size [n, 3]. Each -## row defines a triangle and the three columns are the three vertices -## of the triangle. The value of @code{@var{tri}(i,j)} is an index into -## @var{x} and @var{y} for the location of the j-th vertex of the i-th -## triangle. +## For 2-D sets, the return value @var{tri} is a set of triangles which +## satisfies the Delaunay circum-circle criterion, i.e., only a single data +## point from [@var{x}, @var{y}] is within the circum-circle of the defining +## triangle. The set of triangles @var{tri} is a matrix of size [n, 3]. Each +## row defines a triangle and the three columns are the three vertices of the +## triangle. The value of @code{@var{tri}(i,j)} is an index into @var{x} and +## @var{y} for the location of the j-th vertex of the i-th triangle. +## +## For 3-D sets, the return value @var{tetr} is a set of tetrahedrons which +## satisfies the Delaunay circum-circle criterion, i.e., only a single data +## point from [@var{x}, @var{y}, @var{z}] is within the circum-circle of the +## defining tetrahedron. The set of tetrahedrons is a matrix of size [n, 4]. +## Each row defines a tetrahedron and the four columns are the four vertices of +## the tetrahedron. The value of @code{@var{tetr}(i,j)} is an index into +## @var{x}, @var{y}, @var{z} for the location of the j-th vertex of the i-th +## tetrahedron. +## +## The input @var{x} may also be a matrix with two or three columns where the +## first column contains x-data, the second y-data, and the optional third +## column contains z-data. ## ## The optional last argument, which must be a string or cell array of strings, ## contains options passed to the underlying qhull command. @@ -45,63 +55,84 @@ ## To append user options to the defaults it is necessary to repeat the ## default arguments in @var{options}. Use a null string to pass no arguments. ## -## If no output argument is specified the resulting Delaunay triangulation -## is plotted along with the original set of points. -## ## @example ## @group ## x = rand (1, 10); ## y = rand (1, 10); -## T = delaunay (x, y); -## VX = [ x(T(:,1)); x(T(:,2)); x(T(:,3)); x(T(:,1)) ]; -## VY = [ y(T(:,1)); y(T(:,2)); y(T(:,3)); y(T(:,1)) ]; +## tri = delaunay (x, y); +## triplot (tri, x, y); +## hold on; +## plot (x, y, "r*"); ## axis ([0,1,0,1]); -## plot (VX, VY, "b", x, y, "r*"); ## @end group ## @end example -## @seealso{delaunay3, delaunayn, convhull, voronoi, triplot, trimesh, trisurf} +## @seealso{delaunayn, convhull, voronoi, triplot, trimesh, tetramesh, trisurf} ## @end deftypefn ## Author: Kai Habel <kai.habel@gmx.de> function tri = delaunay (varargin) - if (nargin < 1 || nargin > 3) + if (nargin < 1 || nargin > 4) print_usage (); endif + z = []; options = []; switch (nargin) case 1 - if (! ismatrix (varargin{1}) || columns (varargin{1}) != 2) - error ("delaunay: X must be a matrix with 2 columns"); + if (! ismatrix (varargin{1}) + || (columns (varargin{1}) != 2 && columns (varargin{1}) != 3)) + error ("delaunay: X must be a matrix with 2 or 3 columns"); else x = varargin{1}(:,1); y = varargin{1}(:,2); + if (columns (varargin{1}) == 3) + z = varargin{1}(:,3); + endif endif case 2 if (isnumeric (varargin{2})) x = varargin{1}; y = varargin{2}; - elseif (ischar (varargin{2}) || iscellstr (varargin{2})) + elseif (! (ischar (varargin{2}) || iscellstr (varargin{2}))) + error ("delaunay: OPTIONS must be a string or cell array of strings"); + else options = varargin{2}; - if (! ismatrix (varargin{1}) && columns (varargin{1}) != 2) - error ("delaunay: X must be a matrix with 2 columns"); + ncols = columns (varargin{1}); + + if (! ismatrix (varargin{1}) || (ncols != 2 && ncols != 3)) + error ("delaunay: X must be a matrix with 2 or 3 columns"); else x = varargin{1}(:,1); y = varargin{1}(:,2); + if (ncols == 3) + z = varargin{1}(:,3); + endif endif - else - error ("delaunay: OPTIONS must be a string or cell array of strings"); endif case 3 + if (isnumeric (varargin{3})) + x = varargin{1}; + y = varargin{2}; + z = varargin{3}; + elseif (! (ischar (varargin{3}) || iscellstr (varargin{3}))) + error ("delaunay: OPTIONS must be a string or cell array of strings"); + else + x = varargin{1}; + y = varargin{2}; + options = varargin{3}; + endif + + case 4 x = varargin{1}; y = varargin{2}; - options = varargin{3}; + z = varargin{3}; + options = varargin{4}; if (! (ischar (options) || iscellstr (options))) error ("delaunay: OPTIONS must be a string or cell array of strings"); @@ -109,20 +140,16 @@ endswitch - if (! (isequal(size(x),size(y)))) - error ("delaunay: X and Y must be the same size"); - endif - - T = delaunayn ([x(:), y(:)], options); - - if (nargout == 0) - x = x(:).'; - y = y(:).'; - VX = [ x(T(:,1)); x(T(:,2)); x(T(:,3)); x(T(:,1)) ]; - VY = [ y(T(:,1)); y(T(:,2)); y(T(:,3)); y(T(:,1)) ]; - plot (VX, VY, "b", x, y, "r*"); + if (isempty (z)) + if (! size_equal (x, y)) + error ("delaunay: X and Y must be the same size"); + endif + tri = delaunayn ([x(:), y(:)], options); else - tri = T; + if (! size_equal (x, y, z)) + error ("delaunay: X, Y, and Z must be the same size"); + endif + tri = delaunayn ([x(:), y(:), z(:)], options); endif endfunction @@ -134,11 +161,11 @@ %! rand ("state", 1); %! x = rand (1,10); %! y = rand (1,10); -%! T = delaunay (x,y); -%! VX = [ x(T(:,1)); x(T(:,2)); x(T(:,3)); x(T(:,1)) ]; -%! VY = [ y(T(:,1)); y(T(:,2)); y(T(:,3)); y(T(:,1)) ]; +%! tri = delaunay (x,y); %! clf; -%! plot (VX,VY,"b", x,y,"r*"); +%! triplot (tri, x, y); +%! hold on; +%! plot (x, y, "r*"); %! axis ([0,1,0,1]); %!testif HAVE_QHULL @@ -165,5 +192,19 @@ %! y = [5 7 8; 1 2 3]; %! assert (sortrows (sort (delaunay (x, y), 2)), [1,2,4;1,3,4;1,3,5;3,4,6]); -%% FIXME: Need input validation tests +## Test 3-D input +%!testif HAVE_QHULL +%! x = [-1, -1, 1, 0, -1]; y = [-1, 1, 1, 0, -1]; z = [0, 0, 0, 1, 1]; +%! assert (sortrows (sort (delaunay (x, y, z), 2)), [1,2,3,4;1,2,4,5]) +%% Input validation tests +%!error delaunay () +%!error delaunay (1,2,3,4,5) +%!error <X must be a matrix with 2 or 3 columns> delaunay (ones (2,4)) +%!error <OPTIONS must be a string or cell array> delaunay (ones (2,2), struct()) +%!error <X must be a matrix with 2 or 3 columns> delaunay (ones (2,4), "") +%!error <OPTIONS must be a string or cell array> delaunay (ones (2,2), ones (2,2), struct()) +%!error <OPTIONS must be a string or cell array> delaunay (ones (2,2), ones (2,2), ones (2,2), struct()) +%!error <X and Y must be the same size> delaunay (1, [1 2]) +%!error <X, Y, and Z must be the same size> delaunay (1, [1 2], [1 2]) +