From: <jpi...@us...> - 2012-04-15 15:23:02
|
Revision: 10230 http://octave.svn.sourceforge.net/octave/?rev=10230&view=rev Author: jpicarbajal Date: 2012-04-15 15:22:55 +0000 (Sun, 15 Apr 2012) Log Message: ----------- geometry: Ramer-Douglas-Peucker algorithm to simplify polylines and polygons. Modified Paths: -------------- trunk/octave-forge/main/geometry/inst/polygons2d/simplifypolygon.m trunk/octave-forge/main/geometry/inst/polygons2d/simplifypolyline.m trunk/octave-forge/main/geometry/inst/shape2d/curve2polyline.m Modified: trunk/octave-forge/main/geometry/inst/polygons2d/simplifypolygon.m =================================================================== --- trunk/octave-forge/main/geometry/inst/polygons2d/simplifypolygon.m 2012-04-15 15:18:34 UTC (rev 10229) +++ trunk/octave-forge/main/geometry/inst/polygons2d/simplifypolygon.m 2012-04-15 15:22:55 UTC (rev 10230) @@ -15,37 +15,32 @@ %% -*- texinfo -*- %% @deftypefn {Function File} {@var{spoly} = } simplifypolygon (@var{poly}) -%% Filter colinear vertex from a 2D polygon. +%% Simplify a polygon using the Ramer-Douglas-Peucker algorithm. %% %% @var{poly} is a N-by-2 matrix, each row representing a vertex. %% -%% @seealso{shape2polygon} +%% @seealso{simplifypolyline, shape2polygon} %% @end deftypefn -function polygonsimp = simplifypolygon (polygon) +function polygonsimp = simplifypolygon (polygon, varargin) - # Filter colinear points - edges = diff(polygon([1:end 1],:)); - ned = size(edges,1); - nxt = [2:ned 1]; + polygonsimp = simplifypolyline (polygon,varargin{:}); - # check if consecutive edges are parallel - para = edges(:,1).*edges(nxt,2) - edges(:,2).*edges(nxt,1); - ind = abs(para) > sqrt(eps); + # Remove parrallel consecutive edges + PL = polygonsimp(1:end-1,:); + PC = polygonsimp(2:end,:); + PR = polygonsimp([3:end 1],:); + a = PL - PC; + b = PR - PC; + tf = find(isParallel(a,b))+1; + polygonsimp (tf,:) = []; - polygonsimp = polygon(circshift (ind,1),:); - - if isempty(polygonsimp) - warning('simplifypolygon:devel',"The simplification gives an empty polygon. Returning original\n"); - polygonsimp = polygon; - end - endfunction %!test %! P = [0 0; 1 0; 0 1]; %! P2 = [0 0; 0.1 0; 0.2 0; 0.25 0; 1 0; 0 1; 0 0.7; 0 0.6; 0 0.3; 0 0.1]; -%! assert(P,simplifypolygon (P2)) +%! assert(simplifypolygon (P2),P,min(P2(:))*eps) %!demo %! Modified: trunk/octave-forge/main/geometry/inst/polygons2d/simplifypolyline.m =================================================================== --- trunk/octave-forge/main/geometry/inst/polygons2d/simplifypolyline.m 2012-04-15 15:18:34 UTC (rev 10229) +++ trunk/octave-forge/main/geometry/inst/polygons2d/simplifypolyline.m 2012-04-15 15:22:55 UTC (rev 10230) @@ -48,7 +48,8 @@ parser = inputParser (); parser.FunctionName = "simplifypolyline"; parser = addParamValue (parser,'Nmax', 100, @(x)x>0); - parser = addParamValue (parser,'Tol', 1e-4, @(x)x>0); + toldef = 1e-4;%max(sumsq(diff(pline_o),2))*2; + parser = addParamValue (parser,'Tol', toldef, @(x)x>0); parser = addParamValue (parser,'MaxIter', 100, @(x)x>0); parser = parse(parser,varargin{:}); @@ -56,7 +57,7 @@ tol = parser.Results.Tol; MaxIter = parser.Results.MaxIter; - clear parser + clear parser toldef msg = ["Maximum number of points reached with maximal error %g." ... " Increase '%s' if the result is not satisfactory."]; # ------ # @@ -108,8 +109,6 @@ function [dist ii] = dd (p,e,idx) [d pos] = distancePointEdge(p,e); - tf = abs(pos) <= abs(pos*eps) | abs(pos-1) <= abs((pos-1)*eps); - d(tf) = -1; [dist ii] = max(d); ii = idx(ii); endfunction @@ -137,3 +136,20 @@ %! %! % --------------------------------------------------------- %! % Four approximations of the initial polyline with decreasing tolerances. + +%!demo +%! P = [0 0; 3 1; 3 4; 1 3; 2 2; 1 1]; +%! func = @(x,y) linspace(x,y,5); +%! P2(:,1) = cell2mat( ... +%! arrayfun (func, P(1:end-1,1),P(2:end,1), ... +%! 'uniformoutput',false))'(:); +%! P2(:,2) = cell2mat( ... +%! arrayfun (func, P(1:end-1,2),P(2:end,2), ... +%! 'uniformoutput',false))'(:); +%! +%! P2s = simplifypolyline (P2); +%! +%! plot(P(:,1),P(:,2),'s',P2(:,1),P2(:,2),'o',P2s(:,1),P2s(:,2),'-ok'); +%! +%! % --------------------------------------------------------- +%! % Simplification of a polyline in the plane. Modified: trunk/octave-forge/main/geometry/inst/shape2d/curve2polyline.m =================================================================== --- trunk/octave-forge/main/geometry/inst/shape2d/curve2polyline.m 2012-04-15 15:18:34 UTC (rev 10229) +++ trunk/octave-forge/main/geometry/inst/shape2d/curve2polyline.m 2012-04-15 15:22:55 UTC (rev 10230) @@ -100,6 +100,7 @@ %% -- abs(p0-pt) + abs(pt-p1) - abs(p0-p1) almost zero. %% -- Curve's tange at 0,t,1 are almost parallel. %% -- pt is in chord p0 -> p1. +%% Do this in isParallel.m and remove this function PL = p(1:2:end-2,:); PC = p(2:2:end-1,:); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |