summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafael Laboissiere <rafael@laboissiere.net>2012-03-25 08:39:47 +0200
committerRafael Laboissiere <rafael@laboissiere.net>2012-03-25 08:39:47 +0200
commit12579fb532c3764c177809794131873bfa91b055 (patch)
tree0ff332ec85954417eeb7be3277d19e74b9550af1
parentb78bdf8180be1f4c86452ab46a7fc663e3472d0a (diff)
Imported Upstream version 1.4.1
-rw-r--r--DESCRIPTION6
-rw-r--r--INDEX5
-rw-r--r--NEWS21
-rw-r--r--PKG_ADD16
-rw-r--r--PKG_DEL16
-rw-r--r--devel/graphs/cellSprod.m44
-rw-r--r--devel/graphs/cellmatprod.m33
-rw-r--r--devel/graphs/cellprod.m29
-rw-r--r--devel/graphs/cellsum.m42
-rw-r--r--devel/graphs/getAllPath.m54
-rw-r--r--devel/graphs/graph2cell.m38
-rw-r--r--devel/graphs/iscellempty.m44
-rw-r--r--devel/graphs/simplepath.m35
-rw-r--r--inst/geom2d/bisector.m27
-rw-r--r--inst/geom2d/cbezier2poly.m17
-rw-r--r--inst/geom2d/createCircle.m30
-rw-r--r--inst/geom2d/drawLine.m248
-rw-r--r--inst/geom2d/geom2d_Contents.m223
-rw-r--r--inst/geom2d/geometry_Contents.m (renamed from inst/geom2d/Contents.m)4
-rw-r--r--inst/geom2d/medianLine.m37
-rw-r--r--inst/io/@svg/parsePath.py25
-rw-r--r--inst/io/@svg/parseSVGData.py16
-rw-r--r--inst/io/@svg/path2polygon.m18
-rw-r--r--inst/io/data2geo.m4
-rw-r--r--inst/io/deprecated/private/SVGstrPath2SVGpath.m103
-rw-r--r--inst/io/deprecated/private/_parsePath.py64
-rw-r--r--inst/io/deprecated/private/formatSVGstr.m24
-rw-r--r--inst/io/deprecated/private/getSVGPaths_py.m113
-rw-r--r--inst/io/deprecated/private/getSVGdata.m33
-rw-r--r--inst/io/deprecated/private/getSVGstrPath.m20
-rw-r--r--inst/io/deprecated/svgload.m62
-rw-r--r--inst/io/deprecated/svgnormalize.m68
-rw-r--r--inst/io/deprecated/svgpath2polygon.m60
-rw-r--r--inst/io/private/_parsePath.py64
-rw-r--r--inst/io/private/pointGeo.m10
-rw-r--r--inst/octclip/src/Makefile29
-rw-r--r--inst/polygons2d/polygons2d.m2
-rw-r--r--inst/polygons2d/simplifypolygon.m5
-rw-r--r--inst/shape2d/shape2polygon.m21
-rw-r--r--inst/shape2d/shapearea.m22
-rw-r--r--inst/shape2d/shapecentroid.m97
-rw-r--r--inst/shape2d/shapeplot.m2
-rw-r--r--inst/shape2d/shapetransform.m33
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
diff --git a/INDEX b/INDEX
index 03b10d1..05e723f 100644
--- a/INDEX
+++ b/INDEX
@@ -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
diff --git a/NEWS b/NEWS
index 1b981d9..c294711 100644
--- a/NEWS
+++ b/NEWS
@@ -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
===============================================================================
diff --git a/PKG_ADD b/PKG_ADD
index bb833c2..4be7588 100644
--- a/PKG_ADD
+++ b/PKG_ADD
@@ -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}])
diff --git a/PKG_DEL b/PKG_DEL
index b8f642d..2bdeb33 100644
--- a/PKG_DEL
+++ b/PKG_DEL
@@ -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);