[Pkg-octave-devel] Bug#365757: closed by Rafael Laboissiere
<rafael@debian.org> (Bug#365757: fixed in octave-epstk 2.1-4)
Francesco Potorti
Potorti at isti.cnr.it
Sat Aug 12 16:26:39 UTC 2006
> [ Thomas Weber ]
> * Add plotcollapse.m script from Francesco Potorti` (Closes: #365757)
> Update copyright file accordingly.
In the meantime, I have improved the script (significantly faster and
more robust) and have renamed it, as it turns out that "decimating" is
the common term for referring to such algorithms. Here is the improved
program:
===File /home/pot/math/octavelib/graph/plotdecimate.m=======
## Copyright © 2006 Francesco Potortì
##
## This program 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 of the License, or
## (at your option) any later version.
##
## This program 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 this program; if not, write to the Free Software Foundation,
## Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301, USA.
## -*- texinfo -*-
## @deftypefn {Function File} {} plotdecimate (@var{P})
## @deftypefnx {Function File} {} plotdecimate (@var{P}, @var{so})
## @deftypefnx {Function File} {} plotdecimate (@var{P}, @var{so}, @var{res})
##
## Optimise plot data by removing redundant points and segments
##
## The first parameter @var{P} is a two-column matrix to be plotted as X and
## Y coordinates. The second optional argument @var{so} disables segment
## optimisation when set to @var{false} (default is @var{true}). The third
## optional argument @var{res} is the size of the largest error on the plot:
## if it is a scalar, it is meant relative to the range of X and Y values
## (default 1e-3); if it is a 2x1 array, it contains the absolute errors for
## X and Y. Returns a two-column matrix containing a subset of the rows of
## @var{P}. A line plot of @var{P} has the same appearance as a line plot of
## the output, with errors smaller than @var{res}. When creating point
## plots, set @var{so} to @var{false}.
## @end deftypefn
## Author: Francesco Potortì <Potorti at isti.cnr.it>
## $Revision: 2.7 $
## Usage: plotdecimate(P[, so[, res]])
## Description: Optimise plot data by removing redundant points and segments
function C = plotdecimate (P, so, res)
if (!ismatrix(P) || columns(P) != 2)
error("P must be a matrix with two columns");
endif
if (nargin < 2)
so = true; # do segment optimisation
endif
if (nargin < 3)
res = 1e-3; # default resolution is 1000 dots/axis
endif
## Slack: admissible error on coordinates on the output plot
if (isscalar(res))
if (res <= 0)
error("res must be positive");
endif
E = range(P)' * res; # build error vector using range of data
elseif (ismatrix(res))
if (!all(size(res) == [2 1]) || any(res <= 0))
error("res must be a 2x1 matrix with positive values");
endif
E = res; # take error vector as it is
else
error("res should be a scalar or matrix");
endif
if (rows(P) < 3)
C = P;
return; # nothing to do
endif
P ./= repmat(E',rows(P),1); # normalize P
rot = [0,-1;1,0]; # rotate a vector pi/4 anticlockwise
## Iteratively remove points too near to the previous point
while (1)
V = [true; sumsq(diff(P),2) > 1]; # points far from the previous ones
if (all(V)) break; endif
V = [true; diff(V) >= 0]; # identify the sequence leaders
P = P(V,:); # remove them
endwhile
## Remove points laying near to a segment: for each segment R->S, build a
## unitary-lenght projection vector D perpendicular to R->S, and project
## R->T over D to compute the distance ot T from R->S.
if (so) # segment optimisation
## For each segment, r and s are its extremes
r = 1; R = P(1,:)'; # start of segment
s = 2; S = P(2,:)'; # end of the segment
rebuild = true; # build first projection vector
for t = 3:rows(P)
if (rebuild) # build projection vector
D = rot*(S-R)/sqrt(sumsq(S-R)); # projection vector for distance
rebuild = false; # keep current projection vector
endif
T = P(t,:)'; # next point
if (abs(sum((T-R).*D)) < 1 # T is aligned
&& sum((T-R).*(S-R)) > 0) # going forward
V(s) = false; # do not plot s
else # set a new segment
r = s; R = S; # new start of segment
rebuild = true; # rebuild projection vector
endif
s = t; S = T; # new end of segment
endfor
endif
C = P(V,:) .* repmat(E',sum(V),1); # denormalize P
endfunction
============================================================
More information about the Pkg-octave-devel
mailing list