Mercurial > hg > octave-lyh
diff scripts/geometry/voronoi.m @ 6823:9fddcc586065
[project @ 2007-08-24 08:27:27 by dbateman]
author | dbateman |
---|---|
date | Fri, 24 Aug 2007 08:27:29 +0000 |
parents | |
children | 8618f29520c6 |
line wrap: on
line diff
new file mode 100644 --- /dev/null +++ b/scripts/geometry/voronoi.m @@ -0,0 +1,156 @@ +## 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++; + obj = get (handl); + if (! strcmp (obj.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 + + [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]); + + ## Get points of the diagram + vx = reshape(p(edges, 1), size(edges)); + vy = reshape(p(edges, 2), size(edges)); + + if (nargout < 2) + lim = [min(x(:)), max(x(:)), min(y(:)), max(y(:))]; + 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