Mercurial > hg > octave-lyh
view scripts/geometry/voronoi.m @ 6852:a34d59fc7a91
[project @ 2007-08-31 20:51:58 by dbateman]
author | dbateman |
---|---|
date | Fri, 31 Aug 2007 20:51:58 +0000 |
parents | 8618f29520c6 |
children | 93c65f2a5668 |
line wrap: on
line source
## Copyright (C) 2000 Kai Habel ## ## 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 2, 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, write to the Free ## Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA ## 02110-1301, USA. ## -*- texinfo -*- ## @deftypefn {Function File} {} voronoi (@var{x}, @var{y}) ## @deftypefnx {Function File} {} voronoi (@var{x}, @var{y}, "plotstyle") ## @deftypefnx {Function File} {} voronoi (@var{x}, @var{y}, "plotstyle", @var{options}) ## @deftypefnx {Function File} {[@var{vx}, @var{vy}] =} voronoi (@dots{}) ## plots voronoi diagram of points @code{(@var{x}, @var{y})}. ## The voronoi facets with points at infinity are not drawn. ## [@var{vx}, @var{vy}] = voronoi(...) returns the vertices instead plotting the ## diagram. plot (@var{vx}, @var{vy}) shows the voronoi diagram. ## ## A fourth optional argument, which must be a string, contains extra options ## passed to the underlying qhull command. See the documentation for the ## Qhull library for details. ## ## @example ## @group ## x = rand (10, 1); ## y = rand (size (x)); ## h = convhull (x, y); ## [vx, vy] = voronoi (x, y); ## plot (vx, vy, "-b", x, y, "o", x(h), y(h), "-g") ## legend ("", "points", "hull"); ## @end group ## @end example ## ## @seealso{voronoin, delaunay, convhull} ## @end deftypefn ## Author: Kai Habel <kai.habel@gmx.de> ## First Release: 20/08/2000 ## 2002-01-04 Paul Kienzle <pkienzle@users.sf.net> ## * limit the default graph to the input points rather than the whole diagram ## * provide example ## * use unique(x,"rows") rather than __unique_rows__ ## 2003-12-14 Rafael Laboissiere <rafael@laboissiere.net> ## Added optional fourth argument to pass options to the underlying ## qhull command function [vvx, vvy] = voronoi (varargin) if (nargin < 1) print_usage (); endif narg = 1; if (isscalar (varargin{1}) && ishandle (varargin{1})) handl = varargin{1}; narg++; if (! strcmp (get (handl, "type"), "axes")) error ("voronoi: expecting first argument to be an axes object"); endif else if (nargout < 2) handl = gca (); endif endif if (nargin < 1 + narg || nargin > 3 + narg) print_usage (); endif x = varargin{narg++}; y = varargin{narg++}; opts = {}; if (narg <= nargin) if (iscell (varargin{narg})) opts = varargin(narg++); elseif (ismatrix (varargin{narg})) ## Accept but ignore the triangulation narg++; endif endif linespec = {"b"}; if (narg <= nargin) if (ischar (varargin{narg})) linespec = varargin(narg); endif endif lx = length (x); ly = length (y); if (lx != ly) error ("voronoi: arguments must be vectors of same length"); endif ## Add big box to approximate rays to infinity xmax = max (x(:)); xmin = min (x(:)); ymax = max (y(:)); ymin = min (y(:)); xdelta = xmax - xmin; ydelta = ymax - ymin; scale = 10e4; xbox = [xmin - scale * xdelta; xmin - scale * xdelta; ... xmax + scale * xdelta; xmax + scale * xdelta]; ybox = [xmin - scale * xdelta; xmax + scale * xdelta; ... xmax + scale * xdelta; xmin - scale * xdelta]; x = [x(:) ; xbox(:)]; y = [y(:) ; ybox(:)]; [p, c, infi] = __voronoi__ ([x(:), y(:)], opts{:}); idx = find (!infi); ll = length (idx); k = 0;r = 1; for i = 1 : ll k += length (c{idx(i)}); endfor edges = zeros (2, k); for i = 1 : ll fac = c {idx(i)}; lf = length (fac); fac = [fac, fac(1)]; fst = fac (1 : length(fac) - 1); sec = fac(2 : length(fac)); edges (:, r : r + lf - 1) = [fst; sec]; r += lf; endfor ## Identify the unique edges of the Voronoi diagram edges = sortrows (sort (edges).').'; edges = edges (:, [(edges(1, 1: end - 1) != edges(1, 2 : end) | ... edges(2, 1 :end - 1) != edges(2, 2 : end)), true]); ## Eliminate the edges of the diagram representing the box poutside = (1 : rows(p)) ... (p (:, 1) < xmin - xdelta | p (:, 1) > xmax + xdelta | ... p (:, 2) < ymin - ydelta | p (:, 2) > ymax + ydelta); edgeoutside = ismember (edges (1, :), poutside) & ... ismember (edges (2, :), poutside); edges (:, edgeoutside) = []; ## Get points of the diagram vx = reshape (p (edges, 1), size(edges)); vy = reshape (p (edges, 2), size(edges)); if (nargout < 2) lim = [xmin, xmax, ymin, ymax]; h = plot (handl, vx, vy, linespec{:}, x, y, '+'); axis (lim + 0.1 * [[-1, 1] * (lim (2) - lim (1)), ... [-1, 1] * (lim (4) - lim (3))]); if (nargout == 1) vxx = h; endif elseif (nargout == 2) vvx = vx; vvy = vy; else error ("voronoi: only two or zero output arguments supported") endif endfunction