Mercurial > octave
view scripts/geometry/convhull.m @ 28214:0e0e0de09f1e
griddata.m: Overhaul function.
* griddata.m: Rewrite documentation for clarity. Place all input validation
before calculations. Validate METHOD input more precisely. Don't calculate
Delaunay triangulation for "v4" method as it is unnecessary. Update BIST tests.
author | Rik <rik@octave.org> |
---|---|
date | Mon, 13 Apr 2020 18:07:28 -0700 |
parents | bd51beb6205e |
children | 90fea9cc9caa 0a5b15007766 |
line wrap: on
line source
######################################################################## ## ## Copyright (C) 2000-2020 The Octave Project Developers ## ## See the file COPYRIGHT.md in the top-level directory of this ## distribution or <https://octave.org/copyright/>. ## ## This file is part of Octave. ## ## Octave is free software: you can redistribute it and/or modify it ## under the terms of the GNU General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## Octave is distributed in the hope that it will be useful, but ## WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with Octave; see the file COPYING. If not, see ## <https://www.gnu.org/licenses/>. ## ######################################################################## ## -*- texinfo -*- ## @deftypefn {} {@var{H} =} convhull (@var{x}, @var{y}) ## @deftypefnx {} {@var{H} =} convhull (@var{x}, @var{y}, @var{z}) ## @deftypefnx {} {@var{H} =} convhull (@var{x}) ## @deftypefnx {} {@var{H} =} convhull (@dots{}, @var{options}) ## @deftypefnx {} {[@var{H}, @var{V}] =} convhull (@dots{}) ## Compute the convex hull of a 2-D or 3-D set of points. ## ## The hull @var{H} is a linear index vector into the original set of points ## that specifies which points form the enclosing hull. For 2-D inputs only, ## the output is ordered in a counterclockwise manner around the hull. ## ## 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. ## ## An optional final argument, which must be a string or cell array of strings, ## contains options passed to the underlying qhull command. ## See the documentation for the Qhull library for details ## @url{http://www.qhull.org/html/qh-quick.htm#options}. ## The default option is @code{@{"Qt"@}}. ## ## If @var{options} is not present or @code{[]} then the default arguments are ## used. Otherwise, @var{options} replaces the default argument list. ## 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 the second output @var{V} is requested the volume of the enclosing ## convex hull is calculated. ## ## @seealso{convhulln, delaunay, voronoi} ## @end deftypefn function [H, V] = convhull (varargin) if (nargin < 1 || nargin > 4) print_usage (); endif z = []; options = []; switch (nargin) case 1 if (! ismatrix (varargin{1}) || (columns (varargin{1}) != 2 && columns (varargin{1}) != 3)) error ("convhull: 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}))) error ("convhull: OPTIONS must be a string or cell array of strings"); else options = varargin{2}; ncols = columns (varargin{1}); if (! ismatrix (varargin{1}) || (ncols != 2 && ncols != 3)) error ("convhull: 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 endif case 3 if (isnumeric (varargin{3})) x = varargin{1}; y = varargin{2}; z = varargin{3}; elseif (! (ischar (varargin{3}) || iscellstr (varargin{3}))) error ("convhull: 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}; z = varargin{3}; options = varargin{4}; if (! (ischar (options) || iscellstr (options))) error ("convhull: OPTIONS must be a string or cell array of strings"); endif endswitch if (isempty (z)) x = x(:); y = y(:); if (! size_equal (x, y)) error ("convhull: X and Y must be the same size"); endif if (nargout > 1) [Htmp, V] = convhulln ([x, y], options); else Htmp = convhulln ([x, y], options); endif else x = x(:); y = y(:); z = z(:); if (! size_equal (x, y, z)) error ("convhull: X, Y, and Z must be the same size"); endif if (nargout > 1) [H, V] = convhulln ([x, y, z], options); else H = convhulln ([x, y, z], options); endif endif if (isempty (z)) ## Order 2-D convex hull in a counter-clockwise manner. n = rows (Htmp); Htmp = Htmp.'(:); H = zeros (n + 1, 1); H(1) = Htmp(1); next_pt = Htmp(2); Htmp(2) = 0; for k = 2:n next_idx = find (Htmp == next_pt); H(k) = Htmp(next_idx); if (rem (next_idx, 2) == 0) next_pt = Htmp(next_idx - 1); Htmp(next_idx - 1) = 0; else next_pt = Htmp(next_idx + 1); Htmp(next_idx + 1) = 0; endif endfor H(n + 1) = H(1); endif endfunction %!demo %! clf; %! x = -3:0.05:3; %! y = abs (sin (x)); %! k = convhull (x, y); %! plot (x(k),y(k),"r-;convex hull;", x,y,"b+;points;"); %! axis ([-3.05, 3.05, -0.05, 1.05]); %!testif HAVE_QHULL %! x = -3:0.5:3; %! y = abs (sin (x)); %! assert (convhull (x, y), [1;7;13;12;11;10;4;3;2;1]); %!testif HAVE_QHULL %! [~, V] = convhull ([0,2,2,0], [0,0,1,1]); %! assert (V == 2); ## Input validation tests %!error convhull () %!error convhull (1,2,3,4,5) %!error <X must be a matrix with 2 or 3 columns> convhull (ones (2,4)) %!error <OPTIONS must be a string or cell array> convhull (ones (2,2), struct()) %!error <X must be a matrix with 2 or 3 columns> convhull (ones (2,4), "") %!error <OPTIONS must be a string or cell array> convhull (ones (2,2), ones (2,2), struct()) %!error <OPTIONS must be a string or cell array> convhull (ones (2,2), ones (2,2), ones (2,2), struct()) %!error <X and Y must be the same size> convhull (1, [1 2]) %!error <X, Y, and Z must be the same size> convhull (1, [1 2], [1 2])