diff options
author | Rafael Laboissiere <rafael@laboissiere.net> | 2012-03-25 08:39:47 +0200 |
---|---|---|
committer | Rafael Laboissiere <rafael@laboissiere.net> | 2012-03-25 08:39:47 +0200 |
commit | 12579fb532c3764c177809794131873bfa91b055 (patch) | |
tree | 0ff332ec85954417eeb7be3277d19e74b9550af1 | |
parent | b78bdf8180be1f4c86452ab46a7fc663e3472d0a (diff) |
Imported Upstream version 1.4.1
43 files changed, 1598 insertions, 266 deletions
diff --git a/DESCRIPTION b/DESCRIPTION index 4c51344..42f0e16 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,11 +1,11 @@ Name: Geometry -Version: 1.4.0 -Date: 2012-01-25 +Version: 1.4.1 +Date: 2012-03-24 Author: David Legland <david.legland@grignon.inra.fr>, José Luis García Pallero <jgpallero@gmail.com>, Juan Pablo Carbajal <carbajal@ifi.uzh.ch> Maintainer: Juan Pablo Carbajal <carbajal@ifi.uzh.ch> Title: Computational Geometry Description: Library for geometric computing extending MatGeom functions. Useful to create, transform, manipulate and display geometric primitives. Depends: octave (>= 3.4.0) Autoload: yes -License: GPL version 3 and BSD (see files) +License: GPLv3+, FreeBSD Url: http://octave.sf.net, http://matgeom.sf.net, http://davis.wpi.edu/~matt/courses/clipping/, https://bitbucket.org/jgpallero/octclip @@ -1,6 +1,6 @@ geometry >> Computational Geometry 2D Descriptive - Contents + geom2d_Contents points2d vectors2d angles2d @@ -144,9 +144,6 @@ Geometric graphs visualization drawGraph.m Geometric graphs manipulation Input - svgload - svgnormalize - svgpath2polygon @svg/svg @svg/plot @svg/getpath @@ -1,6 +1,27 @@ Summary of important user-visible changes for releases of the geometry package =============================================================================== +geometry-1.4.1 Release Date: 2012-03-24 Release Manager: Juan Pablo Carbajal +=============================================================================== + +* Renamed functions + - Contents.m renamed to geom2d_Contents to avoid clashes. + +* Deprecated functions + - svgload, svgnormalize, svgpath2polygon: Use the methods in class svg. + +* Bug fixes + - @svg/path2polygon.m + - Fix addpath/rmpath installation warnings + - Fix octclip/src/Makefile + - Fix shapecentriod.m for piece-wise polynomial shapes. + +* Known issues + - simplifypolygon.m returns empty polygons when points are repeated, i.e when + the polygon is not correctly formed. + + +=============================================================================== geometry-1.4.0 Release Date: 2012-01-25 Release Manager: Juan Pablo Carbajal =============================================================================== @@ -1,20 +1,30 @@ %1 dirlist = {"geom2d","io","polygons2d","shape2d","octclip", "graphs"}; dirname = fileparts (canonicalize_file_name (mfilename ("fullpath"))); +pp = strsplit (dirname,filesep (), true); + +%% Check if prefix was used +[pkg_folder dep_folder] = pkg ("prefix"); +pkg_folder = [pkg_folder filesep() strcat(filesep(),{pp{end-1:end}}){:} ]; +dep_folder = [dep_folder filesep() strcat(filesep(),{pp{end-1:end}}){:} ]; %% If we are in Architecture dependent folder add from outside arch = cstrcat (octave_config_info ("canonical_host_type"), "-", octave_config_info ("api_version")); -pp = strsplit (dirname,filesep (), true); -if strcmp(arch , pp{end}) +if strcmp (arch , pp{end}) dirname = [strcat(filesep(),{pp{1:end-1}}){:}]; + pkg_folder = strsplit (pkg_folder,filesep (), true); + pkg_folder = [strcat(filesep(),{pkg_folder{1:end-1}}){:}]; end if (! exist (fullfile (dirname, "inst"), "dir")) +%% Installing for ii=1:length (dirlist) - addpath ( [ dirname filesep dirlist{ii}],"-end") + addpath ( [ pkg_folder filesep() dirlist{ii}],"-end") endfor + else +%% Testing warning("geometry:Devel","Adding path for testing."); for ii=1:length(dirlist) addpath ([ dirname "/inst/" dirlist{ii}]) @@ -1,20 +1,28 @@ %1 dirlist = {"geom2d","io","polygons2d","shape2d","octclip","graphs"}; dirname = fileparts (canonicalize_file_name (mfilename ("fullpath"))); +pp = strsplit (dirname,filesep (), true); + +%% Check if prefix was used +[pkg_folder dep_folder] = pkg ("prefix"); +pkg_folder = [pkg_folder filesep() strcat(filesep(),{pp{end-1:end}}){:} ]; +dep_folder = [dep_folder filesep() strcat(filesep(),{pp{end-1:end}}){:} ]; %% If we are not in Architecture dependent folder arch = cstrcat (octave_config_info ("canonical_host_type"), "-", octave_config_info ("api_version")); pp = strsplit (dirname,filesep (), true); if strcmp(arch , pp{end}) - dirname = [strcat(filesep(),{pp{1:end-1}}){:}]; + dirname = [pkg("prefix") filesep() pp{end-1}]; + pkg_folder = strsplit (pkg_folder,filesep (), true); + pkg_folder = [strcat(filesep(),{pkg_folder{1:end-1}}){:}]; end if (! exist (fullfile (dirname, "inst"), "dir")) +## Run this if the package is installed for ii=1:length (dirlist) - ## Run this if the package is installed - rmpath ( [ dirname filesep dirlist{ii}]) - end + rmpath ( [ pkg_folder filesep() dirlist{ii}]) + endfor else warning("geometry:Devel","Removing path for testing."); for ii=1:length(dirlist) diff --git a/devel/graphs/cellSprod.m b/devel/graphs/cellSprod.m new file mode 100644 index 0000000..281d41e --- /dev/null +++ b/devel/graphs/cellSprod.m @@ -0,0 +1,44 @@ +%% Copyright (C) 2012 Juan Pablo Carbajal
+%%
+%% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+function s=cellSprod(k,s2)
+ if ~ischar(k)
+ disp('First argument must be a string.')
+ s=[];
+ return
+ end
+ if strcmp(k,'')
+ s={''};
+ return
+ end
+ if strcmp(k,'u')
+ s=s2;
+ return;
+ end
+
+ n=numel(s2);
+ for i=1:n
+ if ~strcmp(s2{i},'')
+ if strcmp(s2{i},'u')
+ s{i}=k;
+ else
+ s{i}=[k s2{i}];
+ end
+ else
+ s{i}='';
+ end
+ end
+
+endfunction
diff --git a/devel/graphs/cellmatprod.m b/devel/graphs/cellmatprod.m new file mode 100644 index 0000000..a6a0487 --- /dev/null +++ b/devel/graphs/cellmatprod.m @@ -0,0 +1,33 @@ +%% Copyright (C) 2012 Juan Pablo Carbajal
+%%
+%% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+function C=cellmatprod(A,B)
+ [nA mA]=size(A);
+ [nB mB]=size(B);
+ if mA~=nB
+ disp('Internal Matrix dimension must agree')
+ else
+ C=cell(nA,mB);
+ for i=1:nA
+ for j=1:mB
+ C{i,j}=cellstr('');
+ for k=1:nB
+ X=cellprod(A{i,k},B{k,j});
+ C{i,j}=cellsum(C{i,j},X);
+ end
+ end
+ end
+ end
+endfunction
diff --git a/devel/graphs/cellprod.m b/devel/graphs/cellprod.m new file mode 100644 index 0000000..412eded --- /dev/null +++ b/devel/graphs/cellprod.m @@ -0,0 +1,29 @@ +%% Copyright (C) 2012 Juan Pablo Carbajal
+%%
+%% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+function s=cellprod(s1,s2)
+ % if ~iscellstr(s1) || ~iscellstr(s2)
+ % disp('Error. Arguments must be cell string');
+ % end
+
+ n=numel(s1);
+ if n==1
+ s=cellSprod(s1{1},s2);
+ else
+ X=cellSprod(s1{1},s2)
+ s=cellsum(X,cellprod({s1{2:end}},s2));
+ end
+
+endfunction
diff --git a/devel/graphs/cellsum.m b/devel/graphs/cellsum.m new file mode 100644 index 0000000..099e4ae --- /dev/null +++ b/devel/graphs/cellsum.m @@ -0,0 +1,42 @@ +%% Copyright (C) 2012 Juan Pablo Carbajal
+%%
+%% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+function s=cellsum(s1,s2)
+ % if ~iscellstr(s1)
+ % disp('Error. Argument 1 must be cell string.')
+ % return
+ % end
+ % if ~iscellstr(s2)
+ % disp('Error. Argument 2 must be cell string.')
+ % return
+ % end
+
+ ind1=~strcmp(s1,'');
+ ind2=~strcmp(s2,'');
+ if ~any(ind1)
+ if ~any(ind2)
+ s={''};
+ else
+ s=s2(ind2);
+ end
+ else
+ if ~any(ind2)
+ s=s1(ind1);
+ else
+ s=[s1(ind1) s2(ind2)];
+ end
+ end
+
+endfunction
diff --git a/devel/graphs/getAllPath.m b/devel/graphs/getAllPath.m new file mode 100644 index 0000000..1a047d9 --- /dev/null +++ b/devel/graphs/getAllPath.m @@ -0,0 +1,54 @@ +%% Copyright (C) 2012 Juan Pablo Carbajal +%% +%% 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 3 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, see <http://www.gnu.org/licenses/>. + +function [PathLength CyclesLength]=getAllPath(graph) +% +% graph is a Torsche Graph + +% Using DANIELSON, GORDON . On finding simple paths and circuits in a +% graph. IEEE Trans. Circuit Theor. 15 (1968), 294-295. + N=numel(graph.N); + A=graph.adj; + B=A; + [x y]=find(A==1); + i=sub2ind(size(A),x,y); + B(i)=y; + + Ac=graph2cell(A,'adj'); + Bc=graph2cell(B,'varadj'); + + P=cellmatprod(Bc,Ac); + [P cycles]=simplepath(P); + + i=1; + notemptyp=~iscellempty(P); + notemptyc=~iscellempty(cycles); + PathLength=[]; + CyclesLength=[]; + while any(notemptyp(:)) || any(notemptyc(:)) + if any(notemptyp(:)) + PathLength{i}=P; + end + if any(notemptyc(:)) + CyclesLength{i}=cycles; + end + P=cellmatprod(Bc,P); + [P cycles]=simplepath(P); + i=i+1; + notemptyp=~iscellempty(P); + notemptyc=~iscellempty(cycles); + end + +endfunction diff --git a/devel/graphs/graph2cell.m b/devel/graphs/graph2cell.m new file mode 100644 index 0000000..53435b3 --- /dev/null +++ b/devel/graphs/graph2cell.m @@ -0,0 +1,38 @@ +%% Copyright (C) 2012 Juan Pablo Carbajal
+%%
+%% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+function C=graph2cell(A,type)
+ C=cell(size(A));
+
+ x=find(A==0);
+ for i=1:numel(x);
+ C{x(i)}={''};
+ end
+ x=find(A~=0 & A~=1);
+ for i=1:numel(x);
+ C{x(i)}={[' ' num2str(A(x(i))) ' ']};
+ end
+ x=find(A==1);
+ if strcmp(type,'adj')
+ for i=1:numel(x);
+ C{x(i)}={'u'};
+ end
+ elseif strcmp(type,'varadj')
+ for i=1:numel(x);
+ C{x(i)}={[' ' num2str(A(x(i))) ' ']};
+ end
+ end
+
+endfunction
diff --git a/devel/graphs/iscellempty.m b/devel/graphs/iscellempty.m new file mode 100644 index 0000000..58e868c --- /dev/null +++ b/devel/graphs/iscellempty.m @@ -0,0 +1,44 @@ +%% Copyright (C) 2012 Juan Pablo Carbajal
+%%
+%% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+function out=iscellempty(P)
+ itiscellstr=0;
+ if iscell(P)
+ itiscell=1;
+ if iscellstr(P{1})
+ itiscellstr=1;
+ end
+ else
+ disp('Implemented only for cells.')
+ return
+ end
+
+ [n m]=size(P);
+ if itiscellstr==1
+ for i=1:n
+ for j=1:m
+ out(i,j)=all(strcmp({''},P{i,j}));
+ end
+ end
+ elseif itiscell==1
+ for i=1:n
+ for j=1:m
+ out(i,j)=isempty(P{i,j});
+ end
+ end
+ end
+
+endfunction
+
diff --git a/devel/graphs/simplepath.m b/devel/graphs/simplepath.m new file mode 100644 index 0000000..6e51a5e --- /dev/null +++ b/devel/graphs/simplepath.m @@ -0,0 +1,35 @@ +%% Copyright (C) 2012 Juan Pablo Carbajal
+%%
+%% 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 3 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, see <http://www.gnu.org/licenses/>.
+
+function [P cycle]=simplepath(P)
+ [n m]=size(P);
+ cycle=cell(n,1);
+ for i=1:n
+ for j=1:m
+ if i==j && (n~=1 && m~=1)
+ cycle{i}=P{i,j};
+ P{i,j}={''};
+ else
+ for k=1:numel(P{i,j});
+ path=cell2mat(P{i,j}(k));
+ ind=findstr(path,[' ' num2str(i) ' ']);
+ if ~isempty(ind)
+ P{i,j}(k)={''};
+ end
+ end
+ end
+ end
+ end
+endfunction
diff --git a/inst/geom2d/bisector.m b/inst/geom2d/bisector.m index a13a84c..cb32030 100644 --- a/inst/geom2d/bisector.m +++ b/inst/geom2d/bisector.m @@ -10,8 +10,8 @@ %%
%% 1. Redistributions of source code must retain the above copyright notice, this
%% list of conditions and the following disclaimer.
-%%
-%% 2. Redistributions in binary form must reproduce the above copyright notice,
+%%
+%% 2. Redistributions in binary form must reproduce the above copyright notice,
%% this list of conditions and the following disclaimer in the documentation
%% and/or other materials provided with the distribution.
%%
@@ -19,9 +19,9 @@ %% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
%% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
%% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
-%% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+%% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
%% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-%% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+%% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
%% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
%% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
%% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
@@ -43,7 +43,7 @@ %% The result has the form [x0 y0 dx dy], with [x0 y0] being the origin
%% point ans [dx dy] being the direction vector, normalized to have unit
%% norm.
-%%
+%%
%% @seealso{lines2d, rays2d}
%% @end deftypefn
@@ -53,9 +53,9 @@ function ray = bisector(varargin) % two lines
line1 = varargin{1};
line2 = varargin{2};
-
- point = intersectLines(line1, line2);
-
+
+ point = intersectLines(line1, line2);
+
elseif length(varargin)==3
% three points
p1 = varargin{1};
@@ -65,7 +65,7 @@ function ray = bisector(varargin) line1 = createLine(p2, p1);
line2 = createLine(p2, p3);
point = p2;
-
+
elseif length(varargin)==1
% three points, given in one array
var = varargin{1};
@@ -90,7 +90,11 @@ function ray = bisector(varargin) endfunction
+%!shared privpath
+%! privpath = [fileparts(which('geom2d_Contents')) filesep() 'private'];
+
%!test
+%! addpath (privpath,'-end')
%! p0 = [0 0];
%! p1 = [10 0];
%! p2 = [0 10];
@@ -99,19 +103,24 @@ endfunction %! ray = bisector(line1, line2);
%! assertElementsAlmostEqual([0 0], ray(1,1:2));
%! assertAlmostEqual(pi/4, lineAngle(ray));
+%! rmpath (privpath);
%!test
+%! addpath (privpath,'-end')
%! p0 = [0 0];
%! p1 = [10 0];
%! p2 = [0 10];
%! ray = bisector(p1, p0, p2);
%! assertElementsAlmostEqual([0 0], ray(1,1:2));
%! assertAlmostEqual(pi/4, lineAngle(ray));
+%! rmpath (privpath);
%!test
+%! addpath (privpath,'-end')
%! p0 = [0 0];
%! p1 = [10 0];
%! p2 = [0 10];
%! ray = bisector([p1; p0; p2]);
%! assertElementsAlmostEqual([0 0], ray(1,1:2));
%! assertAlmostEqual(pi/4, lineAngle(ray));
+%! rmpath (privpath);
diff --git a/inst/geom2d/cbezier2poly.m b/inst/geom2d/cbezier2poly.m index f191416..6169eac 100644 --- a/inst/geom2d/cbezier2poly.m +++ b/inst/geom2d/cbezier2poly.m @@ -10,8 +10,8 @@ %% %% 1. Redistributions of source code must retain the above copyright notice, this %% list of conditions and the following disclaimer. -%% -%% 2. Redistributions in binary form must reproduce the above copyright notice, +%% +%% 2. Redistributions in binary form must reproduce the above copyright notice, %% this list of conditions and the following disclaimer in the documentation %% and/or other materials provided with the distribution. %% @@ -19,9 +19,9 @@ %% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE %% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE %% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -%% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +%% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR %% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -%% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +%% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS %% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN %% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) %% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE @@ -37,7 +37,11 @@ %% Returns the polynomial representation of the cubic Bezier defined by the control points @var{points}. %% %% With only one input argument, calculates the polynomial @var{pp} of the cubic -%% Bezier curve defined by the 4 control points stored in @var{points}. +%% Bezier curve defined by the 4 control points stored in @var{points}. The first +%% point is the inital point of the curve. The segment joining the first point +%% with the second point (first center) defines the tangent of the curve at the initial point. +%% The segment that joints the third point (second center) with the fourth defines the tanget at +%% the end-point of the curve, which is defined in the fourth point. %% @var{points} is either a 4-by-2 array (vertical concatenation of point %% coordinates), or a 1-by-8 array (horizotnal concatenation of point %% coordinates). @var{pp} is a 2-by-3 array, 1st row is the polynomial for the @@ -73,7 +77,7 @@ function varargout = cbezier2poly (points, ti=[]) % compute coefficients of Bezier Polynomial pp = zeros(2,4); - + pp(:,4) = [p1(1); ... p1(2)]; pp(:,3) = [3 * c1(1) - 3 * p1(1); ... @@ -148,4 +152,3 @@ endfunction %! y2 = polyval(pp(2,:),t); %! assert(x,x2); %! assert(y,y2); - diff --git a/inst/geom2d/createCircle.m b/inst/geom2d/createCircle.m index 3f9eb40..069e8ba 100644 --- a/inst/geom2d/createCircle.m +++ b/inst/geom2d/createCircle.m @@ -10,8 +10,8 @@ %%
%% 1. Redistributions of source code must retain the above copyright notice, this
%% list of conditions and the following disclaimer.
-%%
-%% 2. Redistributions in binary form must reproduce the above copyright notice,
+%%
+%% 2. Redistributions in binary form must reproduce the above copyright notice,
%% this list of conditions and the following disclaimer in the documentation
%% and/or other materials provided with the distribution.
%%
@@ -19,9 +19,9 @@ %% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
%% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
%% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
-%% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+%% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
%% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-%% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+%% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
%% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
%% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
%% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
@@ -36,7 +36,7 @@ %% @deftypefnx {Function File} {@var{circle} = } createCircle (@var{p1}, @var{p2})
%% Create a circle from 2 or 3 points.
%%
-%% Creates the circle passing through the 3 given points.
+%% Creates the circle passing through the 3 given points.
%% C is a 1x3 array of the form: [XC YX R].
%%
%% When two points are given, creates the circle whith center @var{p1} and passing
@@ -46,7 +46,7 @@ %% result has as many lines as the point arrays.
%%
%% Example
-%%
+%%
%% @example
%% % Draw a circle passing through 3 points.
%% p1 = [10 15];
@@ -70,7 +70,7 @@ function circle = createCircle(varargin) x0 = p1(:,1);
y0 = p1(:,2);
r = hypot((p2(:,1)-x0), (p2(:,2)-y0));
-
+
elseif nargin == 3
% inputs are three points on the circle
p1 = varargin{1};
@@ -81,19 +81,23 @@ function circle = createCircle(varargin) line1 = medianLine(p1, p2);
line2 = medianLine(p1, p3);
point = intersectLines(line1, line2);
- x0 = point(:, 1);
+ x0 = point(:, 1);
y0 = point(:, 2);
-
+
% circle radius
r = hypot((p1(:,1)-x0), (p1(:,2)-y0));
end
-
- % create array for returning result
+
+ % create array for returning result
circle = [x0 y0 r];
endfunction
+%!shared privpath
+%! privpath = [fileparts(which('geom2d_Contents')) filesep() 'private'];
+
%!test
+%! addpath (privpath,'-end')
%! p1 = [10 15];
%! p2 = [15 20];
%! p3 = [10 25];
@@ -104,8 +108,10 @@ endfunction %! assertEqual(exp, circle);
%! circle = createCircle(p2, p3, p1);
%! assertEqual(exp, circle);
+%! rmpath (privpath);
%!test
+%! addpath (privpath,'-end')
%! p1 = [10 15];
%! p2 = [15 20];
%! p3 = [10 25];
@@ -120,4 +126,4 @@ endfunction %! assertEqual(exp, circle);
%! circle = createCircle(p2, p3, p1);
%! assertEqual(exp, circle);
-
+%! rmpath (privpath);
diff --git a/inst/geom2d/drawLine.m b/inst/geom2d/drawLine.m index c58eb89..489a0a2 100644 --- a/inst/geom2d/drawLine.m +++ b/inst/geom2d/drawLine.m @@ -10,8 +10,8 @@ %%
%% 1. Redistributions of source code must retain the above copyright notice, this
%% list of conditions and the following disclaimer.
-%%
-%% 2. Redistributions in binary form must reproduce the above copyright notice,
+%%
+%% 2. Redistributions in binary form must reproduce the above copyright notice,
%% this list of conditions and the following disclaimer in the documentation
%% and/or other materials provided with the distribution.
%%
@@ -19,9 +19,9 @@ %% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
%% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
%% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
-%% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+%% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
%% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-%% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+%% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
%% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
%% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
%% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
@@ -35,7 +35,7 @@ %% @deftypefn {Function File} {@var{h} =} drawLine (@var{line})
%% @deftypefnx {Function File} {@var{h} =} drawLine (@var{line}, @var{param},@var{value})
%% Draw the line on the current axis.
-%%
+%%
%% Draws the line LINE on the current axis, by using current axis to clip
%% the line. Extra @var{param},@var{value} pairs are passed to the @code{line} function.
%% Returns a handle to the created line object. If clipped line is not
@@ -85,110 +85,134 @@ endfunction %! drawLine([30 40 10 20]);
%! drawLine([30 40 20 -10], 'color', 'm', 'linewidth', 2);
-%%!test
-%%! box = [0 100 0 100];
-%%! hf = figure();
-%%! axis(box);
-%%! line = [30 40 10 0];
-%%! edge = [0 40 100 40];
-%%! hl = drawLine(line);
-%%! assertElementsAlmostEqual(edge([1 3]), get(hl, 'xdata'));
-%%! assertElementsAlmostEqual(edge([2 4]), get(hl, 'ydata'));
-
-%%!test
-%%! box = [0 100 0 100];
-%%! hf = figure();
-%%! axis(box);
-%%! line = [30 40 -10 0];
-%%! edge = [100 40 0 40];
-%%! hl = drawLine(line);
-%%! assertElementsAlmostEqual(edge([1 3]), get(hl, 'xdata'));
-%%! assertElementsAlmostEqual(edge([2 4]), get(hl, 'ydata'));
-
-%%!test
-%%! box = [0 100 0 100];
-%%! hf = figure();
-%%! axis(box);
-%%! line = [30 140 10 0];
-%%! hl = drawLine(line);
-%%! assertEqual(-1, hl);
-
-%%!test
-%%! box = [0 100 0 100];
-%%! hf = figure();
-%%! axis(box);
-%%! line = [30 40 0 10];
-%%! edge = [30 0 30 100];
-%%! hl = drawLine(line);
-%%! assertElementsAlmostEqual(edge([1 3]), get(hl, 'xdata'));
-%%! assertElementsAlmostEqual(edge([2 4]), get(hl, 'ydata'));
-
-%%!test
-%%! box = [0 100 0 100];
-%%! hf = figure();
-%%! axis(box);
-%%! line = [30 40 0 -10];
-%%! edge = [30 100 30 0];
-%%! hl = drawLine(line);
-%%! assertElementsAlmostEqual(edge([1 3]), get(hl, 'xdata'));
-%%! assertElementsAlmostEqual(edge([2 4]), get(hl, 'ydata'));
-
-%%!test
-%%! box = [0 100 0 100];
-%%! hf = figure();
-%%! axis(box);
-%%! line = [140 30 0 10];
-%%! hl = drawLine(line);
-%%! assertEqual(-1, hl);
-
-%%!test
-%%! box = [0 100 0 100];
-%%! hf = figure();
-%%! axis(box);
-%%! line = [80 30 10 10];
-%%! edge = [50 0 100 50];
-%%! hl = drawLine(line);
-%%! assertElementsAlmostEqual(edge([1 3]), get(hl, 'xdata'));
-%%! assertElementsAlmostEqual(edge([2 4]), get(hl, 'ydata'));
-
-%%!test
-%%! box = [0 100 0 100];
-%%! hf = figure();
-%%! axis(box);
-%%! line = [20 70 10 10];
-%%! edge = [0 50 50 100];
-%%! hl = drawLine(line);
-%%! assertElementsAlmostEqual(edge([1 3]), get(hl, 'xdata'));
-%%! assertElementsAlmostEqual(edge([2 4]), get(hl, 'ydata'));
-
-%%!test
-%%! box = [0 100 0 100];
-%%! hf = figure();
-%%! axis(box);
-%%! line = [140 -30 10 10];
-%%! hl = drawLine(line);
-%%! assertEqual(-1, hl);
-%%! line = [-40 130 10 10];
-%%! hl = drawLine(line);
-%%! assertEqual(-1, hl);
-
-%%!test
-%%! box = [0 100 0 100];
-%%! hf = figure();
-%%! axis(box);
-%%! line = [...
-%%! 80 30 10 10; ...
-%%! 20 70 10 10; ...
-%%! 140 -30 10 10; ...
-%%! -40 130 10 10];
-%%! edge = [...
-%%! 50 0 100 50; ...
-%%! 0 50 50 100];
-%%! hl = drawLine(line);
-%%! assertEqual(4, length(hl));
-%%! assertElementsAlmostEqual(edge(1, [1 3]), get(hl(1), 'xdata'));
-%%! assertElementsAlmostEqual(edge(1, [2 4]), get(hl(1), 'ydata'));
-%%! assertElementsAlmostEqual(edge(2, [1 3]), get(hl(2), 'xdata'));
-%%! assertElementsAlmostEqual(edge(2, [2 4]), get(hl(2), 'ydata'));
-%%! assertEqual(-1, hl(3));
-%%! assertEqual(-1, hl(4));
+%!shared privpath
+%! privpath = [fileparts(which('geom2d_Contents')) filesep() 'private'];
+
+%!test
+%! addpath (privpath,'-end')
+%! box = [0 100 0 100];
+%! hf = figure('visible','off');
+%! axis(box);
+%! line = [30 40 10 0];
+%! edge = [0 40 100 40];
+%! hl = drawLine(line);
+%! assertElementsAlmostEqual(edge([1 3]), get(hl, 'xdata'));
+%! assertElementsAlmostEqual(edge([2 4]), get(hl, 'ydata'));
+%! rmpath (privpath);
+
+%!test
+%! addpath (privpath,'-end')
+%! box = [0 100 0 100];
+%! hf = figure('visible','off');
+%! axis(box);
+%! line = [30 40 -10 0];
+%! edge = [100 40 0 40];
+%! hl = drawLine(line);
+%! assertElementsAlmostEqual(edge([1 3]), get(hl, 'xdata'));
+%! assertElementsAlmostEqual(edge([2 4]), get(hl, 'ydata'));
+%! rmpath (privpath);
+
+%!test
+%! addpath (privpath,'-end')
+%! box = [0 100 0 100];
+%! hf = figure('visible','off');
+%! axis(box);
+%! line = [30 140 10 0];
+%! hl = drawLine(line);
+%! assertEqual(-1, hl);
+%! rmpath (privpath);
+
+%!test
+%! addpath (privpath,'-end')
+%! box = [0 100 0 100];
+%! hf = figure('visible','off');
+%! axis(box);
+%! line = [30 40 0 10];
+%! edge = [30 0 30 100];
+%! hl = drawLine(line);
+%! assertElementsAlmostEqual(edge([1 3]), get(hl, 'xdata'));
+%! assertElementsAlmostEqual(edge([2 4]), get(hl, 'ydata'));
+%! rmpath (privpath);
+
+%!test
+%! addpath (privpath,'-end')
+%! box = [0 100 0 100];
+%! hf = figure('visible','off');
+%! axis(box);
+%! line = [30 40 0 -10];
+%! edge = [30 100 30 0];
+%! hl = drawLine(line);
+%! assertElementsAlmostEqual(edge([1 3]), get(hl, 'xdata'));
+%! assertElementsAlmostEqual(edge([2 4]), get(hl, 'ydata'));
+%! rmpath (privpath);
+
+%!test
+%! addpath (privpath,'-end')
+%! box = [0 100 0 100];
+%! hf = figure('visible','off');
+%! axis(box);
+%! line = [140 30 0 10];
+%! hl = drawLine(line);
+%! assertEqual(-1, hl);
+%! rmpath (privpath);
+
+%!test
+%! addpath (privpath,'-end')
+%! box = [0 100 0 100];
+%! hf = figure('visible','off');
+%! axis(box);
+%! line = [80 30 10 10];
+%! edge = [50 0 100 50];
+%! hl = drawLine(line);
+%! assertElementsAlmostEqual(edge([1 3]), get(hl, 'xdata'));
+%! assertElementsAlmostEqual(edge([2 4]), get(hl, 'ydata'));
+%! rmpath (privpath);
+
+%!test
+%! addpath (privpath,'-end')
+%! box = [0 100 0 100];
+%! hf = figure('visible','off');
+%! axis(box);
+%! line = [20 70 10 10];
+%! edge = [0 50 50 100];
+%! hl = drawLine(line);
+%! assertElementsAlmostEqual(edge([1 3]), get(hl, 'xdata'));
+%! assertElementsAlmostEqual(edge([2 4]), get(hl, 'ydata'));
+%! rmpath (privpath);
+
+%!test
+%! addpath (privpath,'-end')
+%! box = [0 100 0 100];
+%! hf = figure('visible','off');
+%! axis(box);
+%! line = [140 -30 10 10];
+%! hl = drawLine(line);
+%! assertEqual(-1, hl);
+%! line = [-40 130 10 10];
+%! hl = drawLine(line);
+%! assertEqual(-1, hl);
+%! rmpath (privpath);
+
+%!test
+%! addpath (privpath,'-end')
+%! box = [0 100 0 100];
+%! hf = figure('visible','off');
+%! axis(box);
+%! line = [...
+%! 80 30 10 10; ...
+%! 20 70 10 10; ...
+%! 140 -30 10 10; ...
+%! -40 130 10 10];
+%! edge = [...
+%! 50 0 100 50; ...
+%! 0 50 50 100];
+%! hl = drawLine(line);
+%! assertEqual(4, length(hl));
+%! assertElementsAlmostEqual(edge(1, [1 3]), get(hl(1), 'xdata'));
+%! assertElementsAlmostEqual(edge(1, [2 4]), get(hl(1), 'ydata'));
+%! assertElementsAlmostEqual(edge(2, [1 3]), get(hl(2), 'xdata'));
+%! assertElementsAlmostEqual(edge(2, [2 4]), get(hl(2), 'ydata'));
+%! assertEqual(-1, hl(3));
+%! assertEqual(-1, hl(4));
+%! rmpath (privpath);
+
diff --git a/inst/geom2d/geom2d_Contents.m b/inst/geom2d/geom2d_Contents.m new file mode 100644 index 0000000..d1056a1 --- /dev/null +++ b/inst/geom2d/geom2d_Contents.m @@ -0,0 +1,223 @@ +%% Copyright (c) 2011, INRA
+%% 2007-2011, David Legland <david.legland@grignon.inra.fr>
+%% 2011 Adapted to Octave by Juan Pablo Carbajal <carbajal@ifi.uzh.ch>
+%%
+%% All rights reserved.
+%% (simplified BSD License)
+%%
+%% Redistribution and use in source and binary forms, with or without
+%% modification, are permitted provided that the following conditions are met:
+%%
+%% 1. Redistributions of source code must retain the above copyright notice, this
+%% list of conditions and the following disclaimer.
+%%
+%% 2. Redistributions in binary form must reproduce the above copyright notice,
+%% this list of conditions and the following disclaimer in the documentation
+%% and/or other materials provided with the distribution.
+%%
+%% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+%% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+%% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+%% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+%% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+%% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+%% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+%% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+%% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+%% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+%% POSSIBILITY OF SUCH DAMAGE.
+%%
+%% The views and conclusions contained in the software and documentation are
+%% those of the authors and should not be interpreted as representing official
+%% policies, either expressed or implied, of copyright holder.
+
+%% -*- texinfo -*-
+%% @deftypefn {Function File} geom2d_Contents ()
+%% Geometry 2D Toolbox
+%% Version 1.2.0 21-Oct-2011 .
+%%
+%% Library to handle and visualize geometric primitives such as points,
+%% lines, circles and ellipses, polygons...
+%%
+%% The goal is to provide a low-level library for manipulating geometrical
+%% primitives, making easier the development of more complex geometric
+%% algorithms.
+%%
+%% Most functions works for planar shapes, but some ones have been
+%% extended to 3D or to any dimension.
+%%
+%% Points
+%% points2d - Description of functions operating on points
+%% clipPoints - Clip a set of points by a box
+%% centroid - Compute centroid (center of mass) of a set of points
+%% midPoint - Middle point of two points or of an edge
+%% isCounterClockwise - Compute relative orientation of 3 points
+%% polarPoint - Create a point from polar coordinates (rho + theta)
+%% angle2Points - Compute horizontal angle between 2 points
+%% angle3Points - Compute oriented angle made by 3 points
+%% angleSort - Sort points in the plane according to their angle to origin
+%% distancePoints - Compute distance between two points
+%% minDistancePoints - Minimal distance between several points
+%% transformPoint - Transform a point with an affine transform
+%% drawPoint - Draw the point on the axis.
+%%
+%% Vectors
+%% vectors2d - Description of functions operating on plane vectors
+%% createVector - Create a vector from two points
+%% vectorNorm - Compute norm of a vector, or of a set of vectors
+%% vectorAngle - Angle of a vector, or between 2 vectors
+%% normalizeVector - Normalize a vector to have norm equal to 1
+%% isPerpendicular - Check orthogonality of two vectors
+%% isParallel - Check parallelism of two vectors
+%% transformVector - Transform a vector with an affine transform
+%% rotateVector - Rotate a vector by a given angle
+%%
+%% Straight lines
+%% lines2d - Description of functions operating on planar lines
+%% createLine - Create a straight line from 2 points, or from other inputs
+%% medianLine - Create a median line between two points
+%% cartesianLine - Create a straight line from cartesian equation coefficients
+%% orthogonalLine - Create a line orthogonal to another one.
+%% parallelLine - Create a line parallel to another one.
+%% intersectLines - Return all intersection points of N lines in 2D
+%% lineAngle - Computes angle between two straight lines
+%% linePosition - Position of a point on a line
+%% lineFit - Fit a straight line to a set of points
+%% clipLine - Clip a line with a box
+%% reverseLine - Return same line but with opposite orientation
+%% transformLine - Transform a line with an affine transform
+%% drawLine - Draw the line on the current axis
+%%
+%% Edges (line segments between 2 points)
+%% edges2d - Description of functions operating on planar edges
+%% createEdge - Create an edge between two points, or from a line
+%% edgeToLine - Convert an edge to a straight line
+%% edgeAngle - Return angle of edge
+%% edgeLength - Return length of an edge
+%% midPoint - Middle point of two points or of an edge
+%% edgePosition - Return position of a point on an edge
+%% clipEdge - Clip an edge with a rectangular box
+%% reverseEdge - Intervert the source and target vertices of edge
+%% intersectEdges - Return all intersections between two set of edges
+%% intersectLineEdge - Return intersection between a line and an edge
+%% transformEdge - Transform an edge with an affine transform
+%% drawEdge - Draw an edge given by 2 points
+%% drawCenteredEdge - Draw an edge centered on a point
+%%
+%% Rays
+%% rays2d - Description of functions operating on planar rays
+%% createRay - Create a ray (half-line), from various inputs
+%% bisector - Return the bisector of two lines, or 3 points
+%% clipRay - Clip a ray with a box
+%% drawRay - Draw a ray on the current axis
+%%
+%% Relations between points and lines
+%% distancePointEdge - Minimum distance between a point and an edge
+%% distancePointLine - Minimum distance between a point and a line
+%% projPointOnLine - Project of a point orthogonally onto a line
+%% pointOnLine - Create a point on a line at a given position on the line
+%% isPointOnLine - Test if a point belongs to a line
+%% isPointOnEdge - Test if a point belongs to an edge
+%% isPointOnRay - Test if a point belongs to a ray
+%% isLeftOriented - Test if a point is on the left side of a line
+%%
+%% Circles
+%% circles2d - Description of functions operating on circles
+%% createCircle - Create a circle from 2 or 3 points
+%% createDirectedCircle - Create a directed circle
+%% intersectCircles - Intersection points of two circles
+%% intersectLineCircle - Intersection point(s) of a line and a circle
+%% circleAsPolygon - Convert a circle into a series of points
+%% circleArcAsCurve - Convert a circle arc into a series of points
+%% isPointInCircle - Test if a point is located inside a given circle
+%% isPointOnCircle - Test if a point is located on a given circle.
+%% enclosingCircle - Find the minimum circle enclosing a set of points.
+%% radicalAxis - Compute the radical axis (or radical line) of 2 circles
+%% drawCircle - Draw a circle on the current axis
+%% drawCircleArc - Draw a circle arc on the current axis
+%%
+%% Ellipses
+%% ellipses2d - Description of functions operating on ellipses
+%% inertiaEllipse - Inertia ellipse of a set of points
+%% isPointInEllipse - Check if a point is located inside a given ellipse
+%% ellipseAsPolygon - Convert an ellipse into a series of points
+%% drawEllipse - Draw an ellipse on the current axis
+%% drawEllipseArc - Draw an ellipse arc on the current axis
+%%
+%% Geometric transforms
+%% transforms2d - Description of functions operating on transforms
+%% createTranslation - Create the 3*3 matrix of a translation
+%% createRotation - Create the 3*3 matrix of a rotation
+%% createScaling - Create the 3*3 matrix of a scaling in 2 dimensions
+%% createHomothecy - Create the the 3x3 matrix of an homothetic transform
+%% createBasisTransform - Compute matrix for transforming a basis into another basis
+%% createLineReflection - Create the the 3x3 matrix of a line reflection
+%% fitAffineTransform2d - Fit an affine transform using two point sets
+%%
+%% Angles
+%% angles2d - Description of functions for manipulating angles
+%% normalizeAngle - Normalize an angle value within a 2*PI interval
+%% angleAbsDiff - Absolute difference between two angles
+%% angleDiff - Difference between two angles
+%% deg2rad - Convert angle from degrees to radians
+%% rad2deg - Convert angle from radians to degrees
+%%
+%% Boxes
+%% boxes2d - Description of functions operating on bounding boxes
+%% intersectBoxes - Intersection of two bounding boxes
+%% mergeBoxes - Merge two boxes, by computing their greatest extent
+%% randomPointInBox - Generate random point within a box
+%% drawBox - Draw a box defined by coordinate extents
+%%
+%% Various drawing functions
+%% drawBezierCurve - Draw a cubic bezier curve defined by 4 control points
+%% drawParabola - Draw a parabola on the current axis
+%% drawOrientedBox - Draw centered oriented rectangle
+%% drawRect - Draw rectangle on the current axis
+%% drawArrow - Draw an arrow on the current axis
+%% drawLabels - Draw labels at specified positions
+%% drawShape - Draw various types of shapes (circles, polygons...)
+%%
+%% Other shapes
+%% squareGrid - Generate equally spaces points in plane.
+%% hexagonalGrid - Generate hexagonal grid of points in the plane.
+%% triangleGrid - Generate triangular grid of points in the plane.
+%% crackPattern - Create a (bounded) crack pattern tessellation
+%% crackPattern2 - Create a (bounded) crack pattern tessellation
+%%
+%%
+%% Credits:
+%% * function 'enclosingCircle' rewritten from a file from Yazan Ahed
+%% , available on Matlab File Exchange
+%%
+%% @end deftypefn
+
+function geom2d_Contents ()
+
+ help('geom2d_Contents');
+
+ %% Deprecated functions
+
+ % createMedian - create a median line
+ % minDistance - compute minimum distance between a point and a set of points
+ % homothecy - create a homothecy as an affine transform
+ % rotation - return 3*3 matrix of a rotation
+ % translation - return 3*3 matrix of a translation
+ % scaling - return 3*3 matrix of a scaling in 2 dimensions
+ % lineSymmetry - create line symmetry as 2D affine transform
+ % vecnorm - compute norm of vector or of set of vectors
+ % normalize - normalize a vector
+ % onCircle - test if a point is located on a given circle.
+ % inCircle - test if a point is located inside a given circle.
+ % onEdge - test if a point belongs to an edge
+ % onLine - test if a point belongs to a line
+ % onRay - test if a point belongs to a ray
+ % invertLine - return same line but with opposite orientation
+ % clipLineRect - clip a line with a polygon
+ % formatAngle - Ensure an angle value is comprised between 0 and 2*PI
+
+
+ %% Others...
+ % drawRect2 - Draw centered rectangle on the current axis
+
+endfunction
diff --git a/inst/geom2d/Contents.m b/inst/geom2d/geometry_Contents.m index 28dc171..b87427f 100644 --- a/inst/geom2d/Contents.m +++ b/inst/geom2d/geometry_Contents.m @@ -32,7 +32,7 @@ %% policies, either expressed or implied, of copyright holder.
%% -*- texinfo -*-
-%% @deftypefn {Function File} Contents ()
+%% @deftypefn {Function File} geometry_Contents ()
%% Geometry 2D Toolbox
%% Version 1.2.0 21-Oct-2011 .
%%
@@ -192,7 +192,7 @@ %%
%% @end deftypefn
-function Contents ()
+function geometry_Contents ()
help('Contents');
diff --git a/inst/geom2d/medianLine.m b/inst/geom2d/medianLine.m index 3f99c73..4e1b9ea 100644 --- a/inst/geom2d/medianLine.m +++ b/inst/geom2d/medianLine.m @@ -10,8 +10,8 @@ %%
%% 1. Redistributions of source code must retain the above copyright notice, this
%% list of conditions and the following disclaimer.
-%%
-%% 2. Redistributions in binary form must reproduce the above copyright notice,
+%%
+%% 2. Redistributions in binary form must reproduce the above copyright notice,
%% this list of conditions and the following disclaimer in the documentation
%% and/or other materials provided with the distribution.
%%
@@ -19,9 +19,9 @@ %% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
%% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
%% ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
-%% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+%% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
%% CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-%% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+%% SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
%% INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
%% CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
%% ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
@@ -47,7 +47,7 @@ %% Creates the median of the @var{edge}. @var{edge} is a 1*4 array, containing [X1 Y1]
%% coordinates of first point, and [X2 Y2], the coordinates of the second
%% point.
-%%
+%%
%% Example
%%
%% @example
@@ -84,27 +84,27 @@ function lin = medianLine(varargin) tab = varargin{1};
if size(tab, 2)==2
% input is an array of two points
- x0 = tab(1,1);
+ x0 = tab(1,1);
y0 = tab(1,2);
- dx = tab(2,1)-x0;
+ dx = tab(2,1)-x0;
dy = tab(2,2)-y0;
else
% input is an edge
- x0 = tab(:, 1);
+ x0 = tab(:, 1);
y0 = tab(:, 2);
- dx = tab(:, 3) - tab(:, 1);
+ dx = tab(:, 3) - tab(:, 1);
dy = tab(:, 4) - tab(:, 2);
end
-
+
elseif nargs==2
% input is given as two points, or two point arrays
p1 = varargin{1};
p2 = varargin{2};
- x0 = p1(:, 1);
+ x0 = p1(:, 1);
y0 = p1(:, 2);
- dx = bsxfun(@minus, p2(:, 1), x0);
+ dx = bsxfun(@minus, p2(:, 1), x0);
dy = bsxfun(@minus, p2(:, 2), y0);
-
+
else
error('Too many input arguments');
end
@@ -115,23 +115,32 @@ function lin = medianLine(varargin) endfunction
+%!shared privpath
+%! privpath = [fileparts(which('geom2d_Contents')) filesep() 'private'];
+
%!test
+%! addpath (privpath,'-end')
%! p1 = [0 0];
%! p2 = [10 0];
%! exp = [5 0 0 10];
%! lin = medianLine(p1, p2);
%! assertElementsAlmostEqual(exp, lin);
-
+%! rmpath (privpath);
+
%!test
+%! addpath (privpath,'-end')
%! p1 = [0 0];
%! p2 = [10 0];
%! exp = [5 0 0 10];
%! lin = medianLine([p1 p2]);
%! assertElementsAlmostEqual(exp, lin);
+%! rmpath (privpath);
%!test
+%! addpath (privpath,'-end')
%! p1 = [0 0; 10 10];
%! p2 = [10 0;10 20];
%! exp = [5 0 0 10; 10 15 -10 0];
%! lin = medianLine(p1, p2);
%! assertElementsAlmostEqual(exp, lin);
+%! rmpath (privpath);
diff --git a/inst/io/@svg/parsePath.py b/inst/io/@svg/parsePath.py index a6738ae..ffa9f55 100644 --- a/inst/io/@svg/parsePath.py +++ b/inst/io/@svg/parsePath.py @@ -1,5 +1,20 @@ #!/usr/bin/env python +## Copyright (c) 2012 Juan Pablo Carbajal <carbajal@ifi.uzh.ch> +## +## 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 3 of the License, or +## 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, see <http://www.gnu.org/licenses/>. + import inkex, simplepath import sys #import getopt @@ -8,7 +23,7 @@ def parsePaths (filen=None): svg = inkex.Effect () svg.parse (filen) - + paths = svg.document.xpath ('//svg:path', namespaces=inkex.NSS) for path in paths: D = simplepath.parsePath (path.attrib['d']) @@ -17,14 +32,14 @@ def parsePaths (filen=None): for cmd,params in D: cmdlst.append(cmd) parlst.append(params) - + print 'svgpath = struct("cmd","{0}","data",{{{1}}});' \ .format(''.join(cmdlst),str(parlst).replace('[[','[').replace(']]',']')) print 'svgpathid = "{0}"; $'.format(path.attrib['id']) - - + + # ---------------------------- if __name__=="__main__": @@ -34,7 +49,7 @@ if __name__=="__main__": except getopt.GetoptError: usage() sys.exit(2) - + doHelp = 0 c = Context() c.doPrint = 1 diff --git a/inst/io/@svg/parseSVGData.py b/inst/io/@svg/parseSVGData.py index de96e30..5b23cb9 100644 --- a/inst/io/@svg/parseSVGData.py +++ b/inst/io/@svg/parseSVGData.py @@ -1,5 +1,19 @@ #!/usr/bin/env python +## Copyright (c) 2012 Juan Pablo Carbajal <carbajal@ifi.uzh.ch> +## +## 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 3 of the License, or +## 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, see <http://www.gnu.org/licenses/>. import inkex import sys #import getopt @@ -8,7 +22,7 @@ def parseSVGData (filen=None): svg = inkex.Effect () svg.parse (filen) - + root = svg.document.xpath ('//svg:svg', namespaces=inkex.NSS) print 'data = struct("height",{0},"width",{1},"id","{2}");' \ .format(root[0].attrib['height'],root[0].attrib['width'], diff --git a/inst/io/@svg/path2polygon.m b/inst/io/@svg/path2polygon.m index 64ce003..b823674 100644 --- a/inst/io/@svg/path2polygon.m +++ b/inst/io/@svg/path2polygon.m @@ -1,5 +1,5 @@ %% Copyright (c) 2011 Juan Pablo Carbajal <carbajal@ifi.uzh.ch> -%% +%% %% 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 3 of the License, or @@ -16,13 +16,13 @@ %% -*- texinfo -*- %% @deftypefn {Function File} @var{P} = path2polygon (@var{id}) %% Converts the SVG path to an array of polygons. -%% +%% %% @end deftypefn function P = path2polygon (obj,varargin) narg = numel(varargin); - + if narg == 1 id = varargin{1}; @@ -38,16 +38,21 @@ function P = path2polygon (obj,varargin) error("svg:path2polygon:InvalidArgument", "Wrong number of arguments."); end - + + P = shape2polygon(getpath(obj, id)); + +endfunction + +%{ pd = obj.Path.(id).data; P = cellfun(@(x)convertpath(x,n),pd,'UniformOutput',false); P = cell2mat(P); - + end function p = convertpath(x,np) n = size(x,2); - + switch n case 2 p = zeros(2,2); @@ -63,3 +68,4 @@ function p = convertpath(x,np) end end +%} diff --git a/inst/io/data2geo.m b/inst/io/data2geo.m index e587a32..94ff611 100644 --- a/inst/io/data2geo.m +++ b/inst/io/data2geo.m @@ -107,6 +107,6 @@ endfunction %! %! % -------------------------------------------------------------------------- %! % We load the drawing6.svg file into Octave and transform it into a polygon. -%! % Then we create a temporary fiel where the .geo mesh will be written. -%! % If the packages msh and fplare available, a mesh is created from the .geo +%! % Then we create a temporary file where the .geo mesh will be written. +%! % If the packages msh and fpl are available, a mesh is created from the .geo %! % file. diff --git a/inst/io/deprecated/private/SVGstrPath2SVGpath.m b/inst/io/deprecated/private/SVGstrPath2SVGpath.m new file mode 100644 index 0000000..71c0dea --- /dev/null +++ b/inst/io/deprecated/private/SVGstrPath2SVGpath.m @@ -0,0 +1,103 @@ +%% Copyright (c) 2011 Juan Pablo Carbajal <carbajal@ifi.uzh.ch> +%% +%% 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 3 of the License, or +%% 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, see <http://www.gnu.org/licenses/>. + +function SVGpath = SVGstrPath2SVGpath (SVGstrPath) + + nPaths = numel (SVGstrPath); + SVGpath = repmat (struct('coord', [], 'closed', [], 'id', []), 1, nPaths); + + for ip = 1:nPaths + path = SVGstrPath{ip}; + + % Match data + [s e te m] = regexpi (path, 'd="(?:(?!").)*'); + data=strtrim (m{1}); + % parse data + d = parsePathData (data); + SVGpath(ip).coord = d.coord; + SVGpath(ip).closed = d.closed; + + % Match id + [s e te m] = regexp (path, 'id="(?:(?!").)*'); + if ~isempty (m) + SVGpath(ip).id = strtrim (m{1}(5:end)); + end + end + +end + +function d = parsePathData (data) + + d = struct ('coord', [], 'closed', []); + + [s e te comm] = regexp (data, '[MmLlHhVvCcSsQqTtAaZz]{1}'); + % TODO + % This info could be used to preallocate d + [zcomm zpos] = ismember ({'Z','z'}, comm); + + if any (zcomm) + d.closed = true; + else + d.closed = false; + s(end+1) = length (data); + end + comm(zpos(zcomm)) = []; + ncomm = size (comm, 2); + for ic = 1:ncomm + + switch comm{ic} + case {'M','L'} + [x y] = strread (data(s(ic) + 1 : s(ic + 1) - 1), ... + '%f%f', 'delimiter', ', '); + coord = [x y]; + + case 'm' + [x y] = strread( data(s(ic) + 1 : s(ic + 1) - 1), ... + '%f%f', 'delimiter', ', '); + nc = size (x, 1); + coord = [x y]; + if ic == 1 + % relative moveto at begining of data. + % First coordinates are absolute, the rest are relative. + coord = cumsum (coord); + else + % Relative moveto. + % The coordinates are relative to the last one loaded + coord(1,:) =coord(1,:) + d.coord(end,:); + coord = cumsum(coord); + warning('svg2octWarning',['Relative moveto in path data.'... + ' May mean that the orginal path was not a simple polygon.' ... + ' If that is the case, the path will not display equally.']) + end + + case 'l' + % Relative lineto, coordinates are relative to last point loaded. + [x y] = strread( data(s(ic) + 1 : s(ic + 1) - 1), ... + '%f%f', 'delimiter', ', '); + nc = size (x, 1); + coord = [x y] + coord(1,:) =coord(1,:) + d.coord(end,:); + coord = cumsum(coord); + + otherwise + warning('svg2oct:Warning',... + 'Path data command "%s" not implemented yet.',comm{ic}); + end + + nc = size(coord,1); + d.coord(end+1:end+nc,:) = coord; + + end +end diff --git a/inst/io/deprecated/private/_parsePath.py b/inst/io/deprecated/private/_parsePath.py new file mode 100644 index 0000000..a6738ae --- /dev/null +++ b/inst/io/deprecated/private/_parsePath.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python + +import inkex, simplepath +import sys +#import getopt + +def parsePaths (filen=None): + + svg = inkex.Effect () + svg.parse (filen) + + paths = svg.document.xpath ('//svg:path', namespaces=inkex.NSS) + for path in paths: + D = simplepath.parsePath (path.attrib['d']) + cmdlst = []; + parlst = []; + for cmd,params in D: + cmdlst.append(cmd) + parlst.append(params) + + print 'svgpath = struct("cmd","{0}","data",{{{1}}});' \ + .format(''.join(cmdlst),str(parlst).replace('[[','[').replace(']]',']')) + + print 'svgpathid = "{0}"; $'.format(path.attrib['id']) + + + +# ---------------------------- + +if __name__=="__main__": + ''' + try: + optlist,args = getopt.getopt(sys.argv[1:],"thdp") + except getopt.GetoptError: + usage() + sys.exit(2) + + doHelp = 0 + c = Context() + c.doPrint = 1 + for opt in optlist: + if opt[0] == "-d": c.debug = 1 + if opt[0] == "-p": c.plot = 1 + if opt[0] == "-t": c.triangulate = 1 + if opt[0] == "-h": doHelp = 1 + + if not doHelp: + pts = [] + fp = sys.stdin + if len(args) > 0: + fp = open(args[0],'r') + for line in fp: + fld = line.split() + x = float(fld[0]) + y = float(fld[1]) + pts.append(Site(x,y)) + if len(args) > 0: fp.close() + + if doHelp or len(pts) == 0: + usage() + sys.exit(2) + ''' + svg = sys.argv[1] + parsePaths(svg) diff --git a/inst/io/deprecated/private/formatSVGstr.m b/inst/io/deprecated/private/formatSVGstr.m new file mode 100644 index 0000000..a1310e6 --- /dev/null +++ b/inst/io/deprecated/private/formatSVGstr.m @@ -0,0 +1,24 @@ +%% Copyright (c) 2011 Juan Pablo Carbajal <carbajal@ifi.uzh.ch> +%% +%% 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 3 of the License, or +%% 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, see <http://www.gnu.org/licenses/>. + +function svgF = formatSVGstr(svg) + + % Remove all newlines and tabs + svgF = strrep(svg,"\n",' '); + svgF = strrep(svgF,"\t",' '); + % Remove consecutive blanks + svgF = regexprep(svgF,' +',' '); + +end diff --git a/inst/io/deprecated/private/getSVGPaths_py.m b/inst/io/deprecated/private/getSVGPaths_py.m new file mode 100644 index 0000000..cca08ee --- /dev/null +++ b/inst/io/deprecated/private/getSVGPaths_py.m @@ -0,0 +1,113 @@ +%% Copyright (c) 2011 Juan Pablo Carbajal <carbajal@ifi.uzh.ch> +%% +%% 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 3 of the License, or +%% 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, see <http://www.gnu.org/licenses/>. + +function Paths = getSVGPaths_py (svg, varargin) + + %% Call python script + if exist (svg,'file') + % read from file + [st str]=system (sprintf ('python parsePath.py %s', svg)); + + else + % inline SVG + [st str]=system (sprintf ('python parsePath.py < %s', svg)); + end + + %% Parse ouput + strpath = strsplit (str(1:end-1), '$', true); + + npaths = numel (strpath); + + %% Convert path data to polygons + for ip = 1:npaths + + eval (strpath{ip}); + %% FIXME: intialize struct with cell field + svgpath2.cmd = svgpath(1).cmd; + svgpath2.data = {svgpath.data}; + + nD = length(svgpath2.cmd); + pathdata = cell (nD-1,1); + + point_end=[]; + %% If the path is closed, last command is Z and we set initial point == final + if svgpath2.cmd(end) == 'Z' + nD -= 1; + point_end = svgpath2.data{1}; + end + + %% Initial point + points(1,:) = svgpath2.data{1}; + + for jp = 2:nD + switch svgpath2.cmd(jp) + case 'L' + %% Straigth segment to polygon + points(2,:) = svgpath2.data{jp}; + pp = [(points(2,:)-points(1,:))' points(1,:)']; + clear points + points(1,:) = [polyval(pp(1,:),1) polyval(pp(2,:),1)]; + + case 'C' + %% Cubic bezier to polygon + points(2:4,:) = reshape (svgpath2.data{jp}, 2, 3).'; + pp = cbezier2poly (points); + clear points + points(1,:) = [polyval(pp(1,:),1) polyval(pp(2,:),1)]; + end + + pathdata{jp-1} = pp; + end + + if ~isempty(point_end) + %% Straight segmet to close the path + points(2,:) = point_end; + pp = [(points(2,:)-points(1,:))' points(1,:)']; + + pathdata{end} = pp; + end + + Paths.(svgpathid).data = pathdata; + end +endfunction + +%!test +%! figure(1) +%! hold on +%! paths = getSVGPaths_py ('../drawing.svg'); +%! +%! % Get path ids +%! ids = fieldnames(paths); +%! npath = numel(ids); +%! +%! t = linspace (0, 1, 64); +%! +%! for i = 1:npath +%! x = []; y = []; +%! data = paths.(ids(i)).data; +%! +%! for j = 1:numel(data) +%! x = cat (2, x, polyval (data{j}(1,:),t)); +%! y = cat (2, y, polyval (data{j}(2,:),t)); +%! end +%! +%! plot(x,y,'-'); +%! end +%! axis ij +%! if strcmpi(input('You should see drawing.svg [y/n] ','s'),'n') +%! error ("didn't get what was expected."); +%! end +%! close + diff --git a/inst/io/deprecated/private/getSVGdata.m b/inst/io/deprecated/private/getSVGdata.m new file mode 100644 index 0000000..21a1dd8 --- /dev/null +++ b/inst/io/deprecated/private/getSVGdata.m @@ -0,0 +1,33 @@ +%% Copyright (c) 2011 Juan Pablo Carbajal <carbajal@ifi.uzh.ch> +%% +%% 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 3 of the License, or +%% 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, see <http://www.gnu.org/licenses/>. + +function svgData = getSVGdata(svg) + + svgData = struct('height',[],'width',[]); + attr = fieldnames(svgData); + nattr = numel(attr); + + [s e te data] = regexpi(svg,'<[ ]*svg(?:(?!>).)*>'); + data=strtrim(data{1}); + + for a = 1:nattr + pattr =sprintf('%s="(?:(?!").)*',attr{a}); + [s e te m] = regexpi(data,pattr); + m=strtrim(m{1}); + [dummy value] = strread(m,'%s%f','delimiter','"'); + svgData.(attr{a}) = value; + end + +end diff --git a/inst/io/deprecated/private/getSVGstrPath.m b/inst/io/deprecated/private/getSVGstrPath.m new file mode 100644 index 0000000..ae58654 --- /dev/null +++ b/inst/io/deprecated/private/getSVGstrPath.m @@ -0,0 +1,20 @@ +%% Copyright (c) 2011 Juan Pablo Carbajal <carbajal@ifi.uzh.ch> +%% +%% 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 3 of the License, or +%% 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, see <http://www.gnu.org/licenses/>. + +function strPath = getSVGstrPath(svg) + + [s e te strPath] = regexpi(svg,'<[ ]*path(?:(?!/>).)*/>'); + +end diff --git a/inst/io/deprecated/svgload.m b/inst/io/deprecated/svgload.m new file mode 100644 index 0000000..a9e9963 --- /dev/null +++ b/inst/io/deprecated/svgload.m @@ -0,0 +1,62 @@ +%% Copyright (c) 2011 Juan Pablo Carbajal <carbajal@ifi.uzh.ch> +%% +%% 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 3 of the License, or +%% 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, see <http://www.gnu.org/licenses/>. + +%% -*- texinfo -*- +%% @deftypefn {Function File} @var{SVG} = loadSVG (@var{filename}) +%% Reads the plain SVG file @var{filename} and returns an SVG structure. +%% +%% In the current version only SVG path elements are parsed and stored in the field +%% path of the @var{SVG} structure. +%% The coordinates of the path are not modified in anyway. This produces the path +%% to be ploted vertically reflected. +%% +%% @seealso{svgnormalize, svgpath2polygon} +%% @end deftypefn + + +function SVG = svgload (filename) + + SVG = struct ('height', [], 'width', [], 'path', [], 'normalized', []); + + SVG.normalized = false; + + fid = fopen (filename); + svg = char (fread (fid, "uchar")'); + fclose (fid); + svgF = formatSVGstr (svg); + + % Get SVG Data + data = getSVGdata (svgF); + SVG.height = data.height; + SVG.width = data.width; + + % Get SVG Paths + SVGstrPath = getSVGstrPath (svgF); + SVGpath = SVGstrPath2SVGpath (SVGstrPath); + SVG.path = SVGpath; + +end + +%!demo +%! file = 'tmp__.svg'; +%! fid = fopen (file,'w'); +%! svgfile = '<html><body><svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="250" width="250"><path d="M150,0 75,200 225,200 Z" /></svg></body></html>'; +%! fprintf (fid,"%s\n",svgfile); +%! fclose (fid); +%! SVG = svgload (file); +%! SVG +%! plot([SVG.path.coord(:,1); SVG.path.coord(1,1)], ... +%! [SVG.path.coord(:,2); SVG.path.coord(1,2)]); +%! delete (file); diff --git a/inst/io/deprecated/svgnormalize.m b/inst/io/deprecated/svgnormalize.m new file mode 100644 index 0000000..381d29a --- /dev/null +++ b/inst/io/deprecated/svgnormalize.m @@ -0,0 +1,68 @@ +%% Copyright (c) 2011 Juan Pablo Carbajal <carbajal@ifi.uzh.ch> +%% +%% 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 3 of the License, or +%% 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, see <http://www.gnu.org/licenses/>. + +%% -*- texinfo -*- +%% @deftypefn {Function File} @var{SVGn} = loadSVG (@var{SVG}) +%% Scales and reflects the @var{SVG} structure and returns a modified @var{SVGn} +%% structure. +%% +%% The height and width of the SVG are scaled such that the diagonal of the +%% bounding box has length 1. Coordinates are trasnfomed such that a plot of the +%% paths coincides with the visualization of the original SVG. +%% +%% @seealso{svgload, svgpath2polygon} +%% @end deftypefn + +function SVGn = svgnormalize (SVG) + + SVGn = SVG; + if ~SVG.normalized + % Translate + TransV = [0, SVG.height/2]; + % Scale + Dnorm = sqrt (SVG.width ^ 2 + SVG.height ^ 2); + S = (1 / Dnorm) * eye (2); + for i = 1:numel (SVG.path) + nc = size (SVG.path(i).coord, 1); + % Translate to middle + T = repmat (TransV,nc, 1); + SVGn.path(i).coord = SVG.path(i).coord - T; + % Reflect + SVGn.path(i).coord(:, 2) = -SVGn.path(i).coord(:,2); + T(:,2) = -T(:,2); + % Translate to bottom + SVGn.path(i).coord = SVGn.path(i).coord - T; + %Scale + SVGn.path(i).coord = SVGn.path(i).coord * S; + end + SVGn.height = SVG.height / Dnorm; + SVGn.width = SVG.width / Dnorm; + SVGn.normalized = true; + end + +end + +%!demo +%! file = 'tmp__.svg'; +%! fid = fopen (file,'w'); +%! svgfile = '<html><body><svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="250" width="250"><path d="M150,0 75,200 225,200 Z" /></svg></body></html>'; +%! fprintf (fid,"%s\n",svgfile); +%! fclose (fid); +%! SVG = svgload (file); +%! SVGn = svgnormalize (SVG); +%! SVGn +%! plot([SVGn.path.coord(:,1); SVGn.path.coord(1,1)], ... +%! [SVGn.path.coord(:,2); SVGn.path.coord(1,2)]); +%! delete (file); diff --git a/inst/io/deprecated/svgpath2polygon.m b/inst/io/deprecated/svgpath2polygon.m new file mode 100644 index 0000000..e03a78f --- /dev/null +++ b/inst/io/deprecated/svgpath2polygon.m @@ -0,0 +1,60 @@ +%% Copyright (c) 2011 Juan Pablo Carbajal <carbajal@ifi.uzh.ch> +%% +%% 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 3 of the License, or +%% 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, see <http://www.gnu.org/licenses/>. + +%% -*- texinfo -*- +%% @deftypefn {Function File} @var{P} = svgpath2polygon (@var{SVGpath}) +%% Converts the SVG path structure @var{SVGpath} to an array of polygons +%% compatible with the geometry package and matGeom (@url{http://matgeom.sf.net}). +%% +%% @var{SVGpath} is a substructure of the SVG structure output by loadSVG. This +%% function extracts the field named "coord" if there is only one path. If there +%% are more than oe path it puts the "coord" field of each path in the same +%% array, separated by nans. +%% +%% @seealso{svgnormalize, svgload} +%% @end deftypefn + +function P = svgpath2polygon (SVGpath) + + P = SVGpath(1).coord; + for ip = 2:numel (SVGpath) + P = [P; nan(1,2); SVGpath(ip).coord]; + end + +end + +%!demo +%! file = 'tmp__.svg'; +%! fid = fopen (file,'w'); +%! svgfile = '<html><body><svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="250" width="250"><path d="M150,0 75,200 225,200 Z" /></svg></body></html>'; +%! fprintf (fid,"%s\n",svgfile); +%! fclose (fid); +%! SVG = svgload (file); +%! SVG = svgnormalize (SVG); +%! P = svgpath2polygon (SVG.path); +%! plot (P(:,1),P(:,2)); +%! delete (file); + +%!demo +%! file = 'tmp__.svg'; +%! fid = fopen (file,'w'); +%! svgfile = '<html><body><svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="250" width="250"><path d="M150,0 75,200 225,200 Z" /><path d="M0,0 100,0 100,100 0,100 Z" /></svg></body></html>'; +%! fprintf (fid,"%s\n",svgfile); +%! fclose (fid); +%! SVG = svgload (file); +%! SVG = svgnormalize (SVG); +%! P = svgpath2polygon (SVG.path); +%! plot (P(:,1),P(:,2)); +%! delete (file); diff --git a/inst/io/private/_parsePath.py b/inst/io/private/_parsePath.py new file mode 100644 index 0000000..a6738ae --- /dev/null +++ b/inst/io/private/_parsePath.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python + +import inkex, simplepath +import sys +#import getopt + +def parsePaths (filen=None): + + svg = inkex.Effect () + svg.parse (filen) + + paths = svg.document.xpath ('//svg:path', namespaces=inkex.NSS) + for path in paths: + D = simplepath.parsePath (path.attrib['d']) + cmdlst = []; + parlst = []; + for cmd,params in D: + cmdlst.append(cmd) + parlst.append(params) + + print 'svgpath = struct("cmd","{0}","data",{{{1}}});' \ + .format(''.join(cmdlst),str(parlst).replace('[[','[').replace(']]',']')) + + print 'svgpathid = "{0}"; $'.format(path.attrib['id']) + + + +# ---------------------------- + +if __name__=="__main__": + ''' + try: + optlist,args = getopt.getopt(sys.argv[1:],"thdp") + except getopt.GetoptError: + usage() + sys.exit(2) + + doHelp = 0 + c = Context() + c.doPrint = 1 + for opt in optlist: + if opt[0] == "-d": c.debug = 1 + if opt[0] == "-p": c.plot = 1 + if opt[0] == "-t": c.triangulate = 1 + if opt[0] == "-h": doHelp = 1 + + if not doHelp: + pts = [] + fp = sys.stdin + if len(args) > 0: + fp = open(args[0],'r') + for line in fp: + fld = line.split() + x = float(fld[0]) + y = float(fld[1]) + pts.append(Site(x,y)) + if len(args) > 0: fp.close() + + if doHelp or len(pts) == 0: + usage() + sys.exit(2) + ''' + svg = sys.argv[1] + parsePaths(svg) diff --git a/inst/io/private/pointGeo.m b/inst/io/private/pointGeo.m index 3366111..6c3d5e9 100644 --- a/inst/io/private/pointGeo.m +++ b/inst/io/private/pointGeo.m @@ -1,5 +1,5 @@ %% Copyright (c) 2010 Juan Pablo Carbajal <carbajal@ifi.uzh.ch> -%% +%% %% 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 3 of the License, or @@ -17,9 +17,9 @@ %% @deftypefn {Function File} @var{str} = poointGeo (@var{n}, @var{xyz}, @var{l}) %% Generates a string for Gmsh Point format. %% -%% Gmsh's simplest `elementary entity', a `Point'. A Point is defined by a list -%% of five numbers: @var{n} the identificator, @var{xyz} three coordinates (X, Y -%% and Z), and a characteristic length @var{l} that sets the target element size +%% Gmsh's simplest `elementary entity', a `Point'. A Point is defined by a list +%% of five numbers: @var{n} the identificator, @var{xyz} three coordinates (X, Y +%% and Z), and a characteristic length @var{l} that sets the target element size %% at the point: %% The distribution of the mesh element sizes is then obtained by %% interpolation of these characteristic lengths throughout the @@ -28,5 +28,5 @@ %% @end deftypefn function str = pointGeo(n,xyz,l) - str = sprintf('Point(%d) = {%f,%f,%f,%f};\n',n,xyz,l); + str = sprintf('Point(%d) = {%.16g,%.16g,%.16g,%.16g};\n',n,xyz,l); end diff --git a/inst/octclip/src/Makefile b/inst/octclip/src/Makefile index 44f8d58..cefa9c9 100644 --- a/inst/octclip/src/Makefile +++ b/inst/octclip/src/Makefile @@ -1,22 +1,19 @@ # -*- coding: utf-8 -*- -CC=mkoctfile +ifndef MKOCTFILE +MKOCTFILE := mkoctfile +endif -.PHONY: all -all: compile clean +CLIPOBJECT = compilador.o errores.o eucli.o fgeneral.o greiner.o polig.o \ + ptopol.o segmento.o ventorno.o +FLAGS = -Wall -Wextra -.PHONY: compile -compile: - $(CC) -c -Wall -Wextra -I. compilador.c -o compilador.o - $(CC) -c -Wall -Wextra -I. errores.c -o errores.o - $(CC) -c -Wall -Wextra -I. eucli.c -o eucli.o - $(CC) -c -Wall -Wextra -I. fgeneral.c -o fgeneral.o - $(CC) -c -Wall -Wextra -I. greiner.c -o greiner.o - $(CC) -c -Wall -Wextra -I. polig.c -o polig.o - $(CC) -c -Wall -Wextra -I. ptopol.c -o ptopol.o - $(CC) -c -Wall -Wextra -I. segmento.c -o segmento.o - $(CC) -c -Wall -Wextra -I. ventorno.c -o ventorno.o - $(CC) -s -Wall -Wextra -I. _oc_polybool.cc *.o +%.o: %.c + $(MKOCTFILE) $(FLAGS) -I. -c $< + +%.oct: %.cc $(CLIPOBJECT) + $(MKOCTFILE) $< $(CLIPOBJECT) $(FLAGS) -v -I. + +all: _oc_polybool.oct -.PHONY: clean clean: rm -rf *.o *~ diff --git a/inst/polygons2d/polygons2d.m b/inst/polygons2d/polygons2d.m index 4e7f5d0..80b7407 100644 --- a/inst/polygons2d/polygons2d.m +++ b/inst/polygons2d/polygons2d.m @@ -33,7 +33,7 @@ %% -*- texinfo -*-
%% @deftypefn {Function File} {} polygons2d ()
-%% MATGEOM-POLYGONS
+%% Description of functions operating on 2D polygons
%%
%% The 'polygons' module contains functions operating on shapes composed
%% of a vertex list, like polygons or polylines.
diff --git a/inst/polygons2d/simplifypolygon.m b/inst/polygons2d/simplifypolygon.m index 31db2d5..4a197a6 100644 --- a/inst/polygons2d/simplifypolygon.m +++ b/inst/polygons2d/simplifypolygon.m @@ -35,6 +35,11 @@ function polygonsimp = simplifypolygon (polygon) 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 diff --git a/inst/shape2d/shape2polygon.m b/inst/shape2d/shape2polygon.m index 5e131f8..1d7a987 100644 --- a/inst/shape2d/shape2polygon.m +++ b/inst/shape2d/shape2polygon.m @@ -29,21 +29,24 @@ function polygon = shape2polygon (shape, N=16) polygon = cell2mat ( ... - cellfun(@(x) func (x,N), shape,'UniformOutput',false) ); + cellfun (@(x) func (x,N), shape,'UniformOutput',false) ); - if size(polygon, 1) == 1 - polygon(2,1) = polyval(shape{1}(1,:),1); - polygon(2,2) = polyval(shape{1}(2,:),1); + %% TODO simply the polygon based on curvature +% polygon = unique (polygon, 'rows'); + + if size (polygon, 1) == 1 + polygon(2,1) = polyval (shape{1}(1,:), 1); + polygon(2,2) = polyval (shape{1}(2,:), 1); end endfunction -function y = func(x,N) +function y = func (x,N) - if size(x,2) > 2 - t = linspace(0,1-1/N,N).'; - y(:,1) = polyval(x(1,:),t); - y(:,2) = polyval(x(2,:),t); + if size (x,2) > 2 + t = linspace (0,1-1/N,N).'; + y(:,1) = polyval (x(1,:), t); + y(:,2) = polyval (x(2,:), t); else y = x(:,2).'; end diff --git a/inst/shape2d/shapearea.m b/inst/shape2d/shapearea.m index b6a0e18..e6b745d 100644 --- a/inst/shape2d/shapearea.m +++ b/inst/shape2d/shapearea.m @@ -26,10 +26,12 @@ %% @seealso{shapecentroid, shape2polygon, shapeplot} %% @end deftypefn -function A = shapearea (shape) +function [A ccw] = shapearea (shape) A = sum(cellfun (@Aint, shape)); if A < 0 + warning ('geom2d:shapearea:InvalidResult', ... + 'Shape has negative area. Assuming this is due to a clockwise parametrization of the boundary'); A = -A; end @@ -40,18 +42,22 @@ function dA = Aint (x) px = x(1,:); py = x(2,:); - P = polyint (conv (px, polyderiv(py))); + P = polyint (conv (px, polyder(py))); dA = diff(polyval(P,[0 1])); end -%!demo % non-convex bezier shape -%! weirdhearth ={[-17.6816 -34.3989 7.8580 3.7971; ... -%! 15.4585 -28.3820 -18.7645 9.8519]; ... -%! [-27.7359 18.1039 -34.5718 3.7878; ... -%! -40.7440 49.7999 -25.5011 2.2304]}; -%! A = shapearea (weirdhearth) +%!demo % non-convex piece-wise polynomial shape +%! boomerang = {[ 0 -2 1; ... +%! -4 4 0]; ... +%! [0.25 -1; ... +%! 0 0]; ... +%! [ 0 1.5 -0.75; ... +%! -3 3 0]; +%! [0.25 0.75; ... +%! 0 0]}; +%! A = shapearea (boomerang) %!test %! triangle = {[1 0; 0 0]; [-0.5 1; 1 0]; [-0.5 0.5; -1 1]}; diff --git a/inst/shape2d/shapecentroid.m b/inst/shape2d/shapecentroid.m index e04e763..a7ad8d5 100644 --- a/inst/shape2d/shapecentroid.m +++ b/inst/shape2d/shapecentroid.m @@ -15,30 +15,39 @@ %% -*- texinfo -*- %% @deftypefn {Function File} { @var{cm} =} shapecentroid (@var{pp}) -%% Centroid of a plane shape defined with piecewise smooth polynomials. +%% Centroid of a simple plane shape defined with piecewise smooth polynomials. %% %% The shape is defined with piecewise smooth polynomials. @var{pp} is a %% cell where each elements is a 2-by-(poly_degree+1) matrix containing a pair %% of polynomials. %% @code{px(i,:) = pp@{i@}(1,:)} and @code{py(i,:) = pp@{i@}(2,:)}. %% +%% The edges of the shape should not self-intersect. This function does not check for the +%% sanity of the shape. +%% %% @seealso{shapearea, shape2polygon} %% @end deftypefn function cm = shapecentroid (shape) - cm = sum( cell2mat ( cellfun (@CMint, shape, 'UniformOutput', false))); + cm = sum( cell2mat ( cellfun (@CMint, shape, 'UniformOutput', false)), 1); A = shapearea(shape); cm = cm / A; + [~,id] = lastwarn ('',''); + if strcmp (id ,'geom2d:shapearea:InvalidResult') + lastwarn('Inverting centroid','geom2d:shapecentroid:InvalidResult'); + cm = -cm; + end + endfunction function dcm = CMint (x) px = x(1,:); py = x(2,:); - Px = polyint (conv(conv (px , px)/2 , polyderiv (py))); - Py = polyint (conv(-conv (py , py)/2 , polyderiv (px))); + Px = polyint (conv(conv (-px , py) , polyder (px))); + Py = polyint (conv(conv (px , py) , polyder (py))); dcm = zeros (1,2); dcm(1) = diff(polyval(Px,[0 1])); @@ -47,11 +56,41 @@ function dcm = CMint (x) endfunction %!demo % non-convex bezier shape -%! weirdhearth ={[-17.6816 -34.3989 7.8580 3.7971; ... -%! 15.4585 -28.3820 -18.7645 9.8519]; ... -%! [-27.7359 18.1039 -34.5718 3.7878; ... -%! -40.7440 49.7999 -25.5011 2.2304]}; -%! CoM = shapecentroid (weirdhearth) +%! boomerang = {[ 0 -2 1; ... +%! -4 4 0]; ... +%! [0.25 -1; ... +%! 0 0]; ... +%! [ 0 1.5 -0.75; ... +%! -3 3 0]; +%! [0.25 0.75; ... +%! 0 0]}; +%! CoM = shapecentroid (boomerang) +%! Gcentroid = centroid(shape2polygon(boomerang)) +%! +%! figure(1); clf; +%! shapeplot(boomerang,10,'-o'); +%! hold on +%! drawPoint(CoM,'xk;shape centroid;'); +%! drawPoint(Gcentroid,'xr;point centroid;'); +%! hold off +%! axis equal + +%!demo +%! Lshape = {[0.00000 0.76635; -0.67579 -0.24067]; ... +%! [0.77976 0.76635; 0.00000 -0.91646]; ... +%! [0.00000 1.54611; 0.38614 -0.91646]; ... +%! [-0.43813 1.54611; 0.00000 -0.53032]; ... +%! [0.00000 1.10798; 0.28965 -0.53032]; ... +%! [-0.34163 1.10798; 0.00000 -0.24067]};... +%! CoM = shapecentroid (Lshape) +%! Gcentroid = centroid (shape2polygon (Lshape)) +%! +%! shapeplot(Lshape,10,'-o'); +%! hold on +%! drawPoint(CoM,'xk;shape centroid;'); +%! drawPoint(Gcentroid,'xr;point centroid;'); +%! hold off +%! axis equal %!test %! square = {[1 -0.5; 0 -0.5]; [0 0.5; 1 -0.5]; [-1 0.5; 0 0.5]; [0 -0.5; -1 0.5]}; @@ -59,6 +98,12 @@ endfunction %! assert (CoM, [0 0], sqrt(eps)); %!test +%! square = {[1 -0.5; 0 -0.5]; [0 0.5; 1 -0.5]; [-1 0.5; 0 0.5]; [0 -0.5; -1 0.5]}; +%! square_t = shapetransform (square,[1;1]); +%! CoM = shapecentroid (square_t); +%! assert (CoM, [1 1], sqrt(eps)); + +%!test %! circle = {[1.715729 -6.715729 0 5; ... %! -1.715729 -1.568542 8.284271 0]; ... %! [1.715729 1.568542 -8.284271 0; ... @@ -69,3 +114,37 @@ endfunction %! -1.715729 6.715729 0 -5]}; %! CoM = shapecentroid (circle); %! assert (CoM , [0 0], 5e-3); + +%!shared shape +%! shape = {[-93.172 606.368 -476.054 291.429; ... +%! -431.196 637.253 11.085 163.791]; ... +%! [-75.3626 -253.2337 457.1678 328.5714; ... +%! 438.7659 -653.6278 -7.9953 380.9336]; ... +%! [-89.5841 344.9716 -275.3876 457.1429; ... +%! -170.3613 237.8858 1.0469 158.0765];... +%! [32.900 -298.704 145.804 437.143; ... +%! -243.903 369.597 -34.265 226.648]; ... +%! [-99.081 409.127 -352.903 317.143; ... +%! 55.289 -114.223 -26.781 318.076]; ... +%! [-342.231 191.266 168.108 274.286; ... +%! 58.870 -38.083 -89.358 232.362]}; + +%!test % x-Reflection +%! v = shapecentroid (shape)(:); +%! T = createLineReflection([0 0 1 0]); +%! nshape = shapetransform (shape, T); +%! vn = shapecentroid (nshape)(:); +%! assert(vn,T(1:2,1:2)*v); + +%!test % Rotation +%! v = shapecentroid (shape)(:); +%! T = createRotation(v.',pi/2); +%! nshape = shapetransform (shape, T); +%! vn = shapecentroid (nshape)(:); +%! assert(vn,v,1e-2); + +%!test % Translation +%! v = shapecentroid (shape)(:); +%! nshape = shapetransform (shape, -v); +%! vn = shapecentroid (nshape)(:); +%! assert(vn,[0; 0],1e-2); diff --git a/inst/shape2d/shapeplot.m b/inst/shape2d/shapeplot.m index e2ad972..adeae7d 100644 --- a/inst/shape2d/shapeplot.m +++ b/inst/shape2d/shapeplot.m @@ -17,7 +17,7 @@ %% @deftypefn {Function File} {@var{h} = } shapeplot (@var{shape}) %% @deftypefnx {Function File} {@var{h} = } shapeplot (@var{shape}, @var{N}) %% @deftypefnx {Function File} {@var{h} = } shapeplot (@dots{}, @var{param}, @var{value}) -%% Pots a 2D shape defined by piecewise smooth polynomials. +%% Pots a 2D shape defined by piecewise smooth polynomials in the current axis. %% %% @var{pp} is a cell where each elements is a 2-by-(poly_degree+1) matrix %% containing a pair of polynomials. diff --git a/inst/shape2d/shapetransform.m b/inst/shape2d/shapetransform.m index 54e7201..6cf387e 100644 --- a/inst/shape2d/shapetransform.m +++ b/inst/shape2d/shapetransform.m @@ -109,36 +109,3 @@ endfunction %! axis square -%!shared shape -%! shape = {[-93.172 606.368 -476.054 291.429; ... -%! -431.196 637.253 11.085 163.791]; ... -%! [-75.3626 -253.2337 457.1678 328.5714; ... -%! 438.7659 -653.6278 -7.9953 380.9336]; ... -%! [-89.5841 344.9716 -275.3876 457.1429; ... -%! -170.3613 237.8858 1.0469 158.0765];... -%! [32.900 -298.704 145.804 437.143; ... -%! -243.903 369.597 -34.265 226.648]; ... -%! [-99.081 409.127 -352.903 317.143; ... -%! 55.289 -114.223 -26.781 318.076]; ... -%! [-342.231 191.266 168.108 274.286; ... -%! 58.870 -38.083 -89.358 232.362]}; - -%!test -%! v = shapecentroid (shape)(:); -%! nshape = shapetransform (shape, -v); -%! vn = shapecentroid (nshape)(:); -%! assert(vn,[0; 0],1e-2); - -%!test -%! v = shapecentroid (shape)(:); -%! T = createLineReflection([0 0 1 0]); -%! nshape = shapetransform (shape, T); -%! vn = shapecentroid (nshape)(:); -%! assert(vn,T(1:2,1:2)*v); - -%!test -%! v = shapecentroid (shape)(:); -%! T = createRotation(v.',pi/2); -%! nshape = shapetransform (shape, T); -%! vn = shapecentroid (nshape)(:); -%! assert(vn,v,1e-2); |