summaryrefslogtreecommitdiff
path: root/inst/geom2d
diff options
context:
space:
mode:
Diffstat (limited to 'inst/geom2d')
-rw-r--r--inst/geom2d/Contents.m224
-rw-r--r--inst/geom2d/angle2Points.m109
-rw-r--r--inst/geom2d/angle3Points.m82
-rw-r--r--inst/geom2d/angleAbsDiff.m66
-rw-r--r--inst/geom2d/angleDiff.m76
-rw-r--r--inst/geom2d/angleSort.m106
-rw-r--r--inst/geom2d/angles2d.m54
-rw-r--r--inst/geom2d/bisector.m117
-rw-r--r--inst/geom2d/boxes2d.m53
-rw-r--r--inst/geom2d/cartesianLine.m69
-rw-r--r--inst/geom2d/cbezier2poly.m151
-rw-r--r--inst/geom2d/centroid.m129
-rw-r--r--inst/geom2d/changelog.txt192
-rw-r--r--inst/geom2d/circleArcAsCurve.m79
-rw-r--r--inst/geom2d/circleAsPolygon.m74
-rw-r--r--inst/geom2d/circles2d.m64
-rw-r--r--inst/geom2d/clipEdge.m203
-rw-r--r--inst/geom2d/clipLine.m210
-rw-r--r--inst/geom2d/clipPoints.m101
-rw-r--r--inst/geom2d/clipRay.m172
-rw-r--r--inst/geom2d/crackPattern.m189
-rw-r--r--inst/geom2d/crackPattern2.m148
-rw-r--r--inst/geom2d/createBasisTransform.m108
-rw-r--r--inst/geom2d/createCircle.m123
-rw-r--r--inst/geom2d/createDirectedCircle.m92
-rw-r--r--inst/geom2d/createEdge.m121
-rw-r--r--inst/geom2d/createHomothecy.m61
-rw-r--r--inst/geom2d/createLine.m163
-rw-r--r--inst/geom2d/createLineReflection.m68
-rw-r--r--inst/geom2d/createRay.m104
-rw-r--r--inst/geom2d/createRotation.m112
-rw-r--r--inst/geom2d/createScaling.m106
-rw-r--r--inst/geom2d/createTranslation.m71
-rw-r--r--inst/geom2d/createVector.m54
-rw-r--r--inst/geom2d/deg2rad.m58
-rw-r--r--inst/geom2d/distancePointEdge.m85
-rw-r--r--inst/geom2d/distancePointLine.m77
-rw-r--r--inst/geom2d/distancePoints.m204
-rw-r--r--inst/geom2d/drawArrow.m142
-rw-r--r--inst/geom2d/drawBezierCurve.m107
-rw-r--r--inst/geom2d/drawBox.m81
-rw-r--r--inst/geom2d/drawCenteredEdge.m152
-rw-r--r--inst/geom2d/drawCircle.m132
-rw-r--r--inst/geom2d/drawCircleArc.m123
-rw-r--r--inst/geom2d/drawEdge.m164
-rw-r--r--inst/geom2d/drawEllipse.m141
-rw-r--r--inst/geom2d/drawEllipseArc.m161
-rw-r--r--inst/geom2d/drawLabels.m108
-rw-r--r--inst/geom2d/drawLine.m194
-rw-r--r--inst/geom2d/drawOrientedBox.m113
-rw-r--r--inst/geom2d/drawParabola.m142
-rw-r--r--inst/geom2d/drawPoint.m91
-rw-r--r--inst/geom2d/drawRay.m66
-rw-r--r--inst/geom2d/drawRect.m104
-rw-r--r--inst/geom2d/drawShape.m110
-rw-r--r--inst/geom2d/edgeAngle.m61
-rw-r--r--inst/geom2d/edgeLength.m60
-rw-r--r--inst/geom2d/edgePosition.m91
-rw-r--r--inst/geom2d/edgeToLine.m56
-rw-r--r--inst/geom2d/edges2d.m56
-rw-r--r--inst/geom2d/ellipseAsPolygon.m93
-rw-r--r--inst/geom2d/ellipses2d.m50
-rw-r--r--inst/geom2d/enclosingCircle.m98
-rw-r--r--inst/geom2d/fitAffineTransform2d.m73
-rw-r--r--inst/geom2d/hexagonalGrid.m122
-rw-r--r--inst/geom2d/inertiaEllipse.m96
-rw-r--r--inst/geom2d/intersectBoxes.m76
-rw-r--r--inst/geom2d/intersectCircles.m129
-rw-r--r--inst/geom2d/intersectEdges.m175
-rw-r--r--inst/geom2d/intersectLineCircle.m106
-rw-r--r--inst/geom2d/intersectLineEdge.m106
-rw-r--r--inst/geom2d/intersectLines.m178
-rw-r--r--inst/geom2d/isCounterClockwise.m156
-rw-r--r--inst/geom2d/isLeftOriented.m59
-rw-r--r--inst/geom2d/isParallel.m97
-rw-r--r--inst/geom2d/isPerpendicular.m95
-rw-r--r--inst/geom2d/isPointInCircle.m67
-rw-r--r--inst/geom2d/isPointInEllipse.m81
-rw-r--r--inst/geom2d/isPointOnCircle.m65
-rw-r--r--inst/geom2d/isPointOnEdge.m294
-rw-r--r--inst/geom2d/isPointOnLine.m72
-rw-r--r--inst/geom2d/isPointOnRay.m94
-rw-r--r--inst/geom2d/lineAngle.m105
-rw-r--r--inst/geom2d/linePosition.m139
-rw-r--r--inst/geom2d/lines2d.m66
-rw-r--r--inst/geom2d/medianLine.m137
-rw-r--r--inst/geom2d/mergeBoxes.m77
-rw-r--r--inst/geom2d/midPoint.m170
-rw-r--r--inst/geom2d/minDistancePoints.m280
-rw-r--r--inst/geom2d/normalizeAngle.m96
-rw-r--r--inst/geom2d/normalizeVector.m72
-rw-r--r--inst/geom2d/orthogonalLine.m64
-rw-r--r--inst/geom2d/parallelLine.m63
-rw-r--r--inst/geom2d/pointOnLine.m53
-rw-r--r--inst/geom2d/points2d.m60
-rw-r--r--inst/geom2d/polarPoint.m83
-rw-r--r--inst/geom2d/private/assertAlmostEqual.m26
-rw-r--r--inst/geom2d/private/assertElementsAlmostEqual.m26
-rw-r--r--inst/geom2d/private/assertEqual.m26
-rw-r--r--inst/geom2d/private/assertFalse.m26
-rw-r--r--inst/geom2d/private/assertTrue.m26
-rw-r--r--inst/geom2d/projPointOnLine.m69
-rw-r--r--inst/geom2d/rad2deg.m58
-rw-r--r--inst/geom2d/radicalAxis.m88
-rw-r--r--inst/geom2d/randomPointInBox.m85
-rw-r--r--inst/geom2d/rays2d.m60
-rw-r--r--inst/geom2d/readme.txt68
-rw-r--r--inst/geom2d/reverseEdge.m50
-rw-r--r--inst/geom2d/reverseLine.m52
-rw-r--r--inst/geom2d/rotateVector.m64
-rw-r--r--inst/geom2d/squareGrid.m82
-rw-r--r--inst/geom2d/transformEdge.m71
-rw-r--r--inst/geom2d/transformLine.m66
-rw-r--r--inst/geom2d/transformPoint.m92
-rw-r--r--inst/geom2d/transformVector.m108
-rw-r--r--inst/geom2d/transforms2d.m63
-rw-r--r--inst/geom2d/triangleGrid.m69
-rw-r--r--inst/geom2d/vectorAngle.m221
-rw-r--r--inst/geom2d/vectorNorm.m114
-rw-r--r--inst/geom2d/vectors2d.m54
120 files changed, 12241 insertions, 0 deletions
diff --git a/inst/geom2d/Contents.m b/inst/geom2d/Contents.m
new file mode 100644
index 0000000..28dc171
--- /dev/null
+++ b/inst/geom2d/Contents.m
@@ -0,0 +1,224 @@
+%% 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} 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 Contents ()
+
+ help('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/angle2Points.m b/inst/geom2d/angle2Points.m
new file mode 100644
index 0000000..1e2c206
--- /dev/null
+++ b/inst/geom2d/angle2Points.m
@@ -0,0 +1,109 @@
+%% 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} {@var{alpha} =} angle2Points (@var{p1}, @var{p2})
+%% Compute horizontal angle between 2 points
+%%
+%% @var{p1} and @var{p2} are either [1x2] arrays, or [Nx2] arrays, in this case
+%% @var{alpha} is a [Nx1] array. The angle computed is the horizontal angle of
+%% the line (@var{p1},@var{p2}).
+%%
+%% Result is always given in radians, between 0 and 2*pi.
+%%
+%% @seealso{points2d, angles2d, angle3points, normalizeAngle, vectorAngle}
+%% @end deftypefn
+
+function theta = angle2Points(varargin)
+
+ % process input arguments
+ if length(varargin)==2
+ p1 = varargin{1};
+ p2 = varargin{2};
+ elseif length(varargin)==1
+ var = varargin{1};
+ p1 = var(1,:);
+ p2 = var(2,:);
+ end
+
+ % ensure data have correct size
+ n1 = size(p1, 1);
+ n2 = size(p2, 1);
+ if n1~=n2 && min(n1, n2)>1
+ error('angle2Points: wrong size for inputs');
+ end
+
+ % angle of line (P2 P1), between 0 and 2*pi.
+ dp = bsxfun(@minus, p2, p1);
+ theta = mod(atan2(dp(:,2), dp(:,1)) + 2*pi, 2*pi);
+
+endfunction
+
+%!test
+%! % all points inside window, possibly touching edges
+%! p1 = [0 0];
+%! p2 = [10 0];
+%! angle_ = angle2Points (p1, p2);
+%! assert (angle_,0,1e-6);
+%! angle_ = angle2Points (p2, p1);
+%! assert (angle_,pi,1e-6);
+
+
+%!test
+%! % all points inside window, possibly touching edges
+%! p1 = [0 0];
+%! p2 = [0 10];
+%! angle_ = angle2Points (p1, p2);
+%! assert (pi/2, angle_,1e-6);
+%! angle_ = angle2Points (p2, p1);
+%! assert (3*pi/2, angle_,1e-6);
+
+%!test
+%! % all points inside window, possibly touching edges
+%! p1 = [0 0;0 0;0 0;0 0];
+%! p2 = [10 0;10 10;0 10;-10 10];
+%! angle_ = angle2Points (p1, p2);
+%! assert (size (p1, 1), size (angle_, 1));
+%! res = [0;pi/4;pi/2;3*pi/4];
+%! assert (res, angle_, 1e-6);
+
+%!test
+%! % all points inside window, possibly touching edges
+%! p1 = [0 0];
+%! p2 = [10 0;10 10;0 10;-10 10];
+%! angle_ = angle2Points (p1, p2);
+%! assert(size (p2, 1), size (angle_, 1));
+%! res = [0;pi/4;pi/2;3*pi/4];
+%! assert(res, angle_,1e-6);
+
+
diff --git a/inst/geom2d/angle3Points.m b/inst/geom2d/angle3Points.m
new file mode 100644
index 0000000..fcd45d8
--- /dev/null
+++ b/inst/geom2d/angle3Points.m
@@ -0,0 +1,82 @@
+%% Copyright (c) 2011, INRA
+%% 2004-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} {@var{alpha} =} angle3Points (@var{p1}, @var{p2}, @var{p3})
+%% Computes the angle between the points @var{p1}, @var{p2} and @var{p3}.
+%%
+%% @var{p1}, @var{p2} and @var{p3} are either [1x2] arrays, or [Nx2] arrays, in this case
+%% @var{alpha} is a [Nx1] array. The angle computed is the directed angle between line
+%% (@var{p2}@var{p1}) and line (@var{p2}@var{p3}).
+%%
+%% Result is always given in radians, between 0 and 2*pi.
+%%
+%% @seealso{points2d, angles2d, angle2points}
+%% @end deftypefn
+
+function theta = angle3Points(varargin)
+
+ if length(varargin)==3
+ p1 = varargin{1};
+ p2 = varargin{2};
+ p3 = varargin{3};
+ elseif length(varargin)==1
+ var = varargin{1};
+ p1 = var(1,:);
+ p2 = var(2,:);
+ p3 = var(3,:);
+ end
+
+ % angle line (P2 P1)
+ theta = lineAngle(createLine(p2, p1), createLine(p2, p3));
+
+endfunction
+
+%!test
+%! % all points inside window, possibly touching edges
+%! p1 = [10 0];
+%! p2 = [0 0];
+%! p3 = [0 10];
+%! angle_ = angle3Points(p1, p2, p3);
+%! assert(pi/2, angle_,1e-6);
+%! angle_ = angle3Points([p1; p2; p3]);
+%! assert(pi/2, angle_, 1e-6);
+
+%!test
+%! p1 = [10 0; 20 0];
+%! p2 = [0 0;0 0];
+%! p3 = [0 10; 0 20];
+%! angle_ = angle3Points(p1, p2, p3);
+%! assert(2, size(angle_, 1));
+%! assert([pi/2;pi/2], angle_, 1e-6);
+
diff --git a/inst/geom2d/angleAbsDiff.m b/inst/geom2d/angleAbsDiff.m
new file mode 100644
index 0000000..2cf626f
--- /dev/null
+++ b/inst/geom2d/angleAbsDiff.m
@@ -0,0 +1,66 @@
+%% Copyright (c) 2011, INRA
+%% 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} {@var{dif} =} angleAbsDiff (@var{angle1}, @var{angle2})
+%% Computes the absolute angular difference between two angles in radians.
+%% The result is comprised between 0 and pi.
+%%
+%% @example
+%% A = angleAbsDiff(pi/2, pi/3)
+%% A =
+%% 0.5236 % equal to pi/6
+%% @end example
+%%
+%% @seealso{angles2d, angleDiff}
+%% @end deftypefn
+
+function dif = angleAbsDiff(angle1, angle2)
+
+ % first, normalization
+ angle1 = normalizeAngle(angle1);
+ angle2 = normalizeAngle(angle2);
+
+ % compute difference and normalize
+ dif = normalizeAngle(angle1 - angle2);
+ dif = min(dif, 2*pi - dif);
+
+endfunction
+
+%!shared xp
+%! xp = pi/2;
+%!assert (xp, angleAbsDiff (pi/2, 0), 1e-6);
+%!assert (xp, angleAbsDiff (0, pi/2), 1e-6);
+%!assert (xp, angleAbsDiff (0, 3*pi/2), 1e-6);
+%!assert (xp, angleAbsDiff (3*pi/2, 0), 1e-6);
+
diff --git a/inst/geom2d/angleDiff.m b/inst/geom2d/angleDiff.m
new file mode 100644
index 0000000..94ccc4d
--- /dev/null
+++ b/inst/geom2d/angleDiff.m
@@ -0,0 +1,76 @@
+%% Copyright (c) 2011, INRA
+%% 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} {@var{dif} =} angleDiff (@var{angle1}, @var{angle2})
+%% Difference between two angles
+%%
+%% Computes the signed angular difference between two angles in radians.
+%% The result is comprised between -PI and +PI.
+%%
+%% Example
+%% A = angleDiff(-pi/4, pi/4)
+%% A =
+%% 1.5708 % equal to pi/2
+%% A = angleDiff(pi/4, -pi/4)
+%% A =
+%% -1.5708 % equal to -pi/2
+%%
+%% @seealso{angles2d, angleAbsDiff}
+%% @end deftypefn
+
+function dif = angleDiff(angle1, angle2)
+
+ % first, normalization
+ angle1 = normalizeAngle(angle1);
+ angle2 = normalizeAngle(angle2);
+
+ % compute difference and normalize in [-pi pi]
+ dif = normalizeAngle(angle2 - angle1, 0);
+endfunction
+
+%!test
+%! dif = angleDiff(0, pi/2);
+%! assert (pi/2, dif, 1e-6);
+
+%!test
+%! dif = angleDiff(pi/2, 0);
+%! assert (-pi/2, dif, 1e-6);
+
+%!test
+%! dif = angleDiff(0, 3*pi/2);
+%! assert (-pi/2, dif, 1e-6);
+
+%!test
+%! dif = angleDiff(3*pi/2, 0);
+%! assert (pi/2, dif, 1e-6);
diff --git a/inst/geom2d/angleSort.m b/inst/geom2d/angleSort.m
new file mode 100644
index 0000000..bb77462
--- /dev/null
+++ b/inst/geom2d/angleSort.m
@@ -0,0 +1,106 @@
+%% Copyright (c) 2011, INRA
+%% 2005-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} {varargout =} angleSort (@var{pts}, varargin)
+%% Sort points in the plane according to their angle to origin
+%%
+%%
+%% PTS2 = angleSort(PTS);
+%% Computes angle of points with origin, and sort points with increasing
+%% angles in Counter-Clockwise direction.
+%%
+%% PTS2 = angleSort(PTS, PTS0);
+%% Computes angles between each point of PTS and PT0, which can be
+%% different from origin.
+%%
+%% PTS2 = angleSort(..., THETA0);
+%% Specifies the starting angle for sorting.
+%%
+%% [PTS2, I] = angleSort(...);
+%% Also returns in I the indices of PTS, such that PTS2 = PTS(I, :);
+%%
+%% @seealso{points2d, angles2d, angle2points, normalizeAngle}
+%% @end deftypefn
+
+function varargout = angleSort(pts, varargin)
+
+ % default values
+ pt0 = [0 0];
+ theta0 = 0;
+
+ if length(varargin)==1
+ var = varargin{1};
+ if size(var, 2)==1
+ % specify angle
+ theta0 = var;
+ else
+ pt0 = var;
+ end
+ elseif length(varargin)==2
+ pt0 = varargin{1};
+ theta0 = varargin{2};
+ end
+
+
+ n = size(pts, 1);
+ pts2 = pts - repmat(pt0, [n 1]);
+ angle = lineAngle([zeros(n, 2) pts2]);
+ angle = mod(angle - theta0 + 2*pi, 2*pi);
+
+ [dummy, I] = sort(angle);
+
+ % format output
+ if nargout<2
+ varargout{1} = pts(I, :);
+ elseif nargout==2
+ varargout{1} = pts(I, :);
+ varargout{2} = I;
+ end
+
+endfunction
+
+%!shared p1,p2,p3,p4,pts,center
+%! p1 = [0 0];
+%! p2 = [10 0];
+%! p3 = [10 10];
+%! p4 = [0 10];
+%! pts = [p1;p2;p3;p4];
+%! center = [5 5];
+
+%!test
+%! expected = pts([3 4 1 2], :);
+%! assert (expected, angleSort (pts, center), 1e-6);
+
+%!assert (pts, angleSort (pts, center, -pi), 1e-6);
+
diff --git a/inst/geom2d/angles2d.m b/inst/geom2d/angles2d.m
new file mode 100644
index 0000000..b7d6510
--- /dev/null
+++ b/inst/geom2d/angles2d.m
@@ -0,0 +1,54 @@
+%% Copyright (c) 2011, INRA
+%% 2010-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} angles2d ()
+%% Description of functions for manipulating angles
+%%
+%% Angles are normalized in an interval of width 2*PI. Most geom2d
+%% functions return results in the [0 2*pi] interval, but it can be
+%% convenient to consider the [-pi pi] interval as well. See the
+%% normalizeAngle function to switch between conventions.
+%%
+%% Angles are usually oriented. The default orientation is the CCW
+%% (Counter-Clockwise) orientation.
+%%
+%% @seealso{angle2Points, angle3Points, angleAbsDiff, normalizeAngle, vectorAngle,
+%% angleDiff, angleSort, lineAngle, edgeAngle, deg2rad, rad2deg}
+%% @end deftypefn
+
+function angles2d
+
+ help('angles2d');
+
+endfunction
diff --git a/inst/geom2d/bisector.m b/inst/geom2d/bisector.m
new file mode 100644
index 0000000..a13a84c
--- /dev/null
+++ b/inst/geom2d/bisector.m
@@ -0,0 +1,117 @@
+%% Copyright (c) 2011, INRA
+%% 2005-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} {@var{ray} = } bisector (@var{line1}, @var{line2})
+%% @deftypefnx {Function File} {@var{ray} = } bisector (@var{p1}, @var{p2}, @var{p3})
+%% Return the bisector of two lines, or 3 points.
+%%
+%% Creates the bisector of the two lines, given as [x0 y0 dx dy].
+%%
+%% create the bisector of lines (@var{p2} @var{p1}) and (@var{p2} @var{p3}).
+%%
+%% 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
+
+function ray = bisector(varargin)
+
+ if length(varargin)==2
+ % two lines
+ line1 = varargin{1};
+ line2 = varargin{2};
+
+ point = intersectLines(line1, line2);
+
+ elseif length(varargin)==3
+ % three points
+ p1 = varargin{1};
+ p2 = varargin{2};
+ p3 = varargin{3};
+
+ line1 = createLine(p2, p1);
+ line2 = createLine(p2, p3);
+ point = p2;
+
+ elseif length(varargin)==1
+ % three points, given in one array
+ var = varargin{1};
+ p1 = var(1, :);
+ p2 = var(2, :);
+ p3 = var(3, :);
+
+ line1 = createLine(p2, p1);
+ line2 = createLine(p2, p3);
+ point = p2;
+ end
+
+ % compute line angles
+ a1 = lineAngle(line1);
+ a2 = lineAngle(line2);
+
+ % compute bisector angle (angle of first line + half angle between lines)
+ angle = mod(a1 + mod(a2-a1+2*pi, 2*pi)/2, pi*2);
+
+ % create the resulting ray
+ ray = [point cos(angle) sin(angle)];
+
+endfunction
+
+%!test
+%! p0 = [0 0];
+%! p1 = [10 0];
+%! p2 = [0 10];
+%! line1 = createLine(p0, p1);
+%! line2 = createLine(p0, p2);
+%! ray = bisector(line1, line2);
+%! assertElementsAlmostEqual([0 0], ray(1,1:2));
+%! assertAlmostEqual(pi/4, lineAngle(ray));
+
+%!test
+%! 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));
+
+%!test
+%! 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));
diff --git a/inst/geom2d/boxes2d.m b/inst/geom2d/boxes2d.m
new file mode 100644
index 0000000..df25a15
--- /dev/null
+++ b/inst/geom2d/boxes2d.m
@@ -0,0 +1,53 @@
+%% Copyright (c) 2011, INRA
+%% 2008-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} boxes2d ()
+%% Description of functions operating on bounding boxes.
+%%
+%% A box is represented as a set of limits in each direction:
+%% @example
+%% BOX = [XMIN XMAX YMIN YMAX].
+%% @end example
+%% @noindent
+%% Boxes are used as result of computation for bounding boxes, and to clip
+%% shapes.
+%%
+%% @seealso{clipPoints, clipLine, clipEdge, clipRay, mergeBoxes,
+%% intersectBoxes, randomPointInBox, drawBox}
+%% @end deftypefn
+
+function boxes2d(varargin)
+ help('boxes2d');
+endfunction
+
diff --git a/inst/geom2d/cartesianLine.m b/inst/geom2d/cartesianLine.m
new file mode 100644
index 0000000..d729f6f
--- /dev/null
+++ b/inst/geom2d/cartesianLine.m
@@ -0,0 +1,69 @@
+%% Copyright (c) 2011, INRA
+%% 2004-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} {@var{line} = } cartesianLine (@var{A}, @var{B},@var{C})
+%% Create a straight line from cartesian equation coefficients.
+%%
+%% Create a line verifying the Cartesian equation:
+%% @var{A}*x + @var{B}*x + @var{C} = 0;
+%%
+%% @seealso{lines2d, createLine}
+%% @end deftypefn
+
+function line = cartesianLine(varargin)
+
+ if length(varargin)==1
+ var = varargin{1};
+ a = var(:,1);
+ b = var(:,2);
+ c = var(:,3);
+ elseif length(varargin)==3
+ a = varargin{1};
+ b = varargin{2};
+ c = varargin{3};
+ end
+
+ % normalisation factor
+ d = a.*a + b.*b;
+
+ x0 = -a.*c./d;
+ y0 = -b.*c./d;
+ theta = atan2(-a, b);
+ dx = cos(theta);
+ dy = sin(theta);
+
+ line = [x0 y0 dx dy];
+
+endfunction
+
diff --git a/inst/geom2d/cbezier2poly.m b/inst/geom2d/cbezier2poly.m
new file mode 100644
index 0000000..f191416
--- /dev/null
+++ b/inst/geom2d/cbezier2poly.m
@@ -0,0 +1,151 @@
+%% 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} {@var{pp} =} cbezier2poly (@var{points})
+%% @deftypefnx {Command} {Function File} {[@var{x} @var{y}] =} cbezier2poly (@var{points},@var{t})
+%% 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}.
+%% @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
+%% x-coordinate and the 2nd row for the y-coordinate. Each row can be evaluated
+%% with @code{polyval}. The polynomial @var{pp}(t) is defined for t in [0,1].
+%%
+%% When called with a second input argument @var{t}, it returns the coordinates
+%% @var{x} and @var{y} corresponding to the polynomial evaluated at @var{t} in
+%% [0,1].
+%%
+%% @seealso{drawBezierCurve, polyval}
+%% @end deftypefn
+
+function varargout = cbezier2poly (points, ti=[])
+
+
+ % rename points
+ if size(points, 2)==2
+ % case of points given as a 4-by-2 array
+ p1 = points(1,:);
+ c1 = points(2,:);
+ c2 = points(3,:);
+ p2 = points(4,:);
+ elseif size(points,2) == 8
+ % case of points given as a 1-by-8 array, [X1 Y1 CX1 CX2..]
+ p1 = points(1:2);
+ c1 = points(3:4);
+ c2 = points(5:6);
+ p2 = points(7:8);
+ else
+ print_usage ;
+ end
+
+ % compute coefficients of Bezier Polynomial
+ pp = zeros(2,4);
+
+ pp(:,4) = [p1(1); ...
+ p1(2)];
+ pp(:,3) = [3 * c1(1) - 3 * p1(1); ...
+ 3 * c1(2) - 3 * p1(2)];
+ pp(:,2) = [3 * p1(1) - 6 * c1(1) + 3 * c2(1); ...
+ 3 * p1(2) - 6 * c1(2) + 3 * c2(2)];
+ pp(:,1) = [p2(1) - 3 * c2(1) + 3 * c1(1) - p1(1); ...
+ p2(2) - 3 * c2(2) + 3 * c1(2) - p1(2)];
+
+ if isempty (ti)
+ varargout{1} = pp;
+ else
+ varargout{1} = polyval (pp(1,:), ti);
+ varargout{2} = polyval (pp(2,:), ti);
+ end
+
+endfunction
+
+%!demo
+%! points = [45.714286 483.79075; ...
+%! 241.65656 110.40445; ...
+%! 80.185847 741.77381; ...
+%! 537.14286 480.93361];
+%!
+%! pp = cbezier2poly(points);
+%! t = linspace(0,1,64);
+%! x = polyval(pp(1,:),t);
+%! y = polyval(pp(2,:),t);
+%! plot (x,y,'b-',points([1 4],1),points([1 4],2),'s',...
+%! points([2 3],1),points([2 3],2),'o');
+%! line(points([2 1],1),points([2 1],2),'color','r');
+%! line(points([3 4],1),points([3 4],2),'color','r');
+
+%!demo
+%! points = [0 0; ...
+%! 1 1; ...
+%! 1 1; ...
+%! 2 0];
+%!
+%! t = linspace(0,1,64);
+%! [x y] = cbezier2poly(points,t);
+%! plot (x,y,'b-',points([1 4],1),points([1 4],2),'s',...
+%! points([2 3],1),points([2 3],2),'o');
+%! line(points([2 1],1),points([2 1],2),'color','r');
+%! line(points([3 4],1),points([3 4],2),'color','r');
+
+%!test
+%! points = [0 0; ...
+%! 1 1; ...
+%! 1 1; ...
+%! 2 0];
+%! t = linspace(0,1,64);
+%!
+%! [x y] = cbezier2poly(points,t);
+%! pp = cbezier2poly(points);
+%! x2 = polyval(pp(1,:),t);
+%! y2 = polyval(pp(2,:),t);
+%! assert(x,x2);
+%! assert(y,y2);
+
+%!test
+%! points = [0 0; ...
+%! 1 1; ...
+%! 1 1; ...
+%! 2 0];
+%! t = linspace(0,1,64);
+%!
+%! p = reshape(points,1,8);
+%! [x y] = cbezier2poly(p,t);
+%! pp = cbezier2poly(p);
+%! x2 = polyval(pp(1,:),t);
+%! y2 = polyval(pp(2,:),t);
+%! assert(x,x2);
+%! assert(y,y2);
+
diff --git a/inst/geom2d/centroid.m b/inst/geom2d/centroid.m
new file mode 100644
index 0000000..26e5291
--- /dev/null
+++ b/inst/geom2d/centroid.m
@@ -0,0 +1,129 @@
+%% Copyright (c) 2011, INRA
+%% 2003-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} {@var{c} = } centroid (@var{points})
+%% @deftypefnx {Function File} {@var{c} = } centroid (@var{px}, @var{py})
+%% @deftypefnx {Function File} {@var{c} = } centroid (@dots{}, @var{mass})
+%% Compute centroid (center of mass) of a set of points.
+%%
+%% Computes the ND-dimensional centroid of a set of points.
+%% @var{points} is an array with as many rows as the number of points, and as
+%% many columns as the number of dimensions.
+%% @var{px} and @var{py} are two column vectors containing coordinates of the
+%% 2-dimensional points.
+%% The result @var{c} is a row vector with ND columns.
+%%
+%% If @var{mass} is given, computes center of mass of @var{points}, weighted by coefficient @var{mass}.
+%% @var{points} is a Np-by-Nd array, @var{mass} is Np-by-1 array, and @var{px} and @var{py} are
+%% also both Np-by-1 arrays.
+%%
+%% Example:
+%%
+%% @example
+%% pts = [2 2;6 1;6 5;2 4];
+%% centroid(pts)
+%% ans =
+%% 4 3
+%%@end example
+%%
+%% @seealso{points2d, polygonCentroid}
+%% @end deftypefn
+
+function center = centroid(varargin)
+
+ %% extract input arguments
+
+ % use empty mass by default
+ mass = [];
+
+ if nargin==1
+ % give only array of points
+ pts = varargin{1};
+
+ elseif nargin==2
+ % either POINTS+MASS or PX+PY
+ var = varargin{1};
+ if size(var, 2)>1
+ % arguments are POINTS, and MASS
+ pts = var;
+ mass = varargin{2};
+ else
+ % arguments are PX and PY
+ pts = [var varargin{2}];
+ end
+
+ elseif nargin==3
+ % arguments are PX, PY, and MASS
+ pts = [varargin{1} varargin{2}];
+ mass = varargin{3};
+ end
+
+ %% compute centroid
+
+ if isempty(mass)
+ % no weight
+ center = mean(pts);
+
+ else
+ % format mass to have sum equal to 1, and column format
+ mass = mass(:)/sum(mass(:));
+
+ % compute weighted centroid
+ center = sum(bsxfun(@times, pts, mass), 1);
+ % equivalent to:
+ % center = sum(pts .* mass(:, ones(1, size(pts, 2))));
+ end
+
+endfunction
+
+%!test
+%! points = [0 0;10 0;10 10;0 10];
+%! centro = centroid(points);
+%! assert ([5 5], centro, 1e-6);
+
+%!test
+%! points = [0 0;10 0;10 10;0 10];
+%! centro = centroid(points(:,1), points(:,2));
+%! assert ([5 5], centro, 1e-6);
+
+%!test
+%! points = [0 0;30 0;30 30;0 30];
+%! centro = centroid(points, [1;1;1;3]);
+%! assert ([10 20], centro, 1e-6);
+
+%!test
+%! points = [0 0;30 0;30 30;0 30];
+%! centro = centroid(points(:,1), points(:,2), [1;1;1;3]);
+%! assert ([10 20], centro, 1e-6);
+
diff --git a/inst/geom2d/changelog.txt b/inst/geom2d/changelog.txt
new file mode 100644
index 0000000..e58b56f
--- /dev/null
+++ b/inst/geom2d/changelog.txt
@@ -0,0 +1,192 @@
+%% 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.
+
+
+change log for geom2d
+
+geom2d, release 2011.??.??
+==========================
+
+New functions
+- added angleDiff and angleAbsDiff
+
+various doc updates
+
+
+geom2d, release 2011.06.30
+==========================
+
+New functions
+- added function rotateVector
+- added function randomPointInBox
+
+Changes
+- Shape orientation is now represented using degrees
+- function vectorAngle can now compute the angle between two vectors
+
+Bug fixes
+- enhanced function distancePointEdge
+- enhanced function isPointOnEdge
+- enhanced function isParallel
+- fixed bugs intersectLineCircle
+
+
+geom2d, release 2011.03.21
+==========================
+
+New functions
+- added functions intersectLineCircle and intersectCircles
+- added functions inertiaEllipse, isPointInEllipse
+- added function drawBezierCurve
+- added functions intersectBoxes and mergeBoxes
+
+Changes
+- re-organized the library in three sub-directories: geom2d, polygons2d, and
+ polynomialCurves2d
+- cleanup of code and doc
+
+Bug fixes
+- several bugs fixed in clipEdge, isPointOnEdge
+
+
+geom2d, release 2010.08.06
+==========================
+
+New functions
+- polygonToRow and rowToPolygon, to convert polygon to a row vector
+- midPoint, to compute middle points of either 2 points or an edge
+- added rad2deg and deg2rad, for angle conversions
+
+Changes
+- createCircle and createdirectedCircle are now vectorized, and use different
+ convention for 2 input variables (center + point and circle)
+- median line has been vectorized
+
+Bug fixes
+- fix bugs in intersectEdges
+- fix bugs in clipLine
+- rewrite drawLine using clipLine
+
+
+geom2d, release 2010.07.19
+==========================
+
+new functions
+
+- isCounterClockwise
+- intersectRayPolygon
+- clipRay
+- reverseEdge
+- drawBox
+- fitAffineTransform2d
+
+Changes
+
+- updated inertiaEllipse
+- fixed bugs in intersectEdges.m, isParallel.m and isPerpendicular.m
+- vectorized intersectLinePolygon
+- fixed precision bug in isPointOnEdge
+- renamed formatAngle to normalizeAngle
+- created help file 'angles2d'
+- fixed bug in weighted centroid computation
+
+various bug fixes, and doc updates.
+
+
+
+geom2d, release 2009.07.22
+==========================
+
+new features
+
+- new functions for polygons:
+ polygonPoint, polygonSubcurve, polygonLoops, distancePointPolygon,
+ distancePolygons, expandPolygon, polygonSelfIntersections,
+ projPointOnPolygon, isPointInPolygon, reveresPolygon
+
+- new functions for polylines:
+ intersectPolylines, polylineSelfIntersections, distancePolylines,
+ isPointOnPolyline, reveresPolyline
+
+- projPointOnPolyline can also return the distance of the point to the polyline
+
+- function 'edgeToLine' converts an edge to its supporting line
+
+
+Changes
+
+- Renamed functions
+ + subcurve -> polylineSubCurve
+ + curveCentroid -> polylineCentroid
+ + invertLine -> reverseLine
+
+- Compatibility considerations
+ + parallelLine: changed convention for signed distance
+
+various bug fixes, and doc updates.
+
+
+geom2d, release 2009.06.15
+==========================
+
+* new features
+
+- radicalAxis from 2 circles:
+- moment of a curve (polyline): curveMoment, curveCMoment, curveCSMoment
+- new functions for polylines
+ distancePointPolyline, drawPolyline, polylineLength, polylinePoint,
+ polylineSubcurve, projPointOnPolyline
+
+* changes
+
+- changed some function names to avoid potential name conflicts, and to make
+ function names more explicit:
+ + rotation -> createRotation
+ + scaling -> createScaling
+ + translation -> createRotation
+ + homothecy -> createHomothecy
+ + lineSymmetry -> createLineReflection
+ + inCircle -> isPointInCircle
+ + onCircle -> isPointOnCircle
+ + onEdge -> isPointOnEdge
+ + onLine -> isPointOnLine
+ + onRay -> isPointOnRay
+ + normalize -> normalizeVector
+
+
+* bug fixes
+
+- fixed bug in intersectEdges
+
+many updates in doc.
+
diff --git a/inst/geom2d/circleArcAsCurve.m b/inst/geom2d/circleArcAsCurve.m
new file mode 100644
index 0000000..3612494
--- /dev/null
+++ b/inst/geom2d/circleArcAsCurve.m
@@ -0,0 +1,79 @@
+%% Copyright (c) 2011, INRA
+%% 2006-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} {@var{p} = } circleArcAsCurve (@var{arc}, @var{N})
+%% Convert a circle arc into a series of points
+%%
+%% P = circleArcAsCurve(ARC, N);
+%% convert the circle ARC into a series of N points.
+%% ARC is given in the format: [XC YC R THETA1 DTHETA]
+%% where XC and YC define the center of the circle, R its radius, THETA1
+%% is the start of the arc and DTHETA is the angle extent of the arc. Both
+%% angles are given in degrees.
+%% N is the number of vertices of the resulting polyline, default is 65.
+%%
+%% The result is a N-by-2 array containing coordinates of the N points.
+%%
+%% [X Y] = circleArcAsCurve(ARC, N);
+%% Return the result in two separate arrays with N lines and 1 column.
+%%
+%%
+%% @seealso{circles2d, circleAsPolygon, drawCircle, drawPolygon}
+%% @end deftypefn
+
+function varargout = circleArcAsCurve(arc, N)
+
+ % default value for N
+ if nargin < 2
+ N = 65;
+ end
+
+ % vector of positions
+ t0 = deg2rad(arc(4));
+ t1 = t0 + deg2rad(arc(5));
+ t = linspace(t0, t1, N)';
+
+ % compute coordinates of vertices
+ x = arc(1) + arc(3) * cos(t);
+ y = arc(2) + arc(3) * sin(t);
+
+ % format output
+ if nargout <= 1
+ varargout = {[x y]};
+ else
+ varargout = {x, y};
+ end
+
+endfunction
+
diff --git a/inst/geom2d/circleAsPolygon.m b/inst/geom2d/circleAsPolygon.m
new file mode 100644
index 0000000..068f8ff
--- /dev/null
+++ b/inst/geom2d/circleAsPolygon.m
@@ -0,0 +1,74 @@
+%% Copyright (c) 2011, INRA
+%% 2005-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} {@var{P} = } circleAsPolygon (@var{circle}, @var{N})
+%% Convert a circle into a series of points
+%%
+%% P = circleAsPolygon(CIRCLE, N);
+%% convert circle given as [x0 y0 r], where x0 and y0 are coordinate of
+%% center, and r is the radius, into an array of [(N+1)x2] double,
+%% containing x and y values of points.
+%% The polygon is closed
+%%
+%% P = circleAsPolygon(CIRCLE);
+%% uses a default value of N=64 points
+%%
+%% Example
+%% circle = circleAsPolygon([10 0 5], 16);
+%% figure;
+%% drawPolygon(circle);
+%%
+%% @seealso{circles2d, polygons2d, createCircle}
+%% @end deftypefn
+
+function varargout = circleAsPolygon(circle, varargin)
+ % determines number of points
+ N = 64;
+ if ~isempty(varargin)
+ N = varargin{1};
+ end
+
+ % create circle
+ t = linspace(0, 2*pi, N+1)';
+ x = circle(1) + circle(3)*cos(t);
+ y = circle(2) + circle(3)*sin(t);
+
+ if nargout==1
+ varargout{1}=[x y];
+ elseif nargout==2
+ varargout{1}=x;
+ varargout{2}=y;
+ end
+
+endfunction
diff --git a/inst/geom2d/circles2d.m b/inst/geom2d/circles2d.m
new file mode 100644
index 0000000..1bef4cd
--- /dev/null
+++ b/inst/geom2d/circles2d.m
@@ -0,0 +1,64 @@
+%% Copyright (c) 2011, INRA
+%% 2008-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} circles2d ()
+%% Description of functions operating on circles
+%%
+%% Circles are represented by their center and their radius:
+%% C = [xc yc r];
+%% One sometimes considers orientation of circle, by adding an extra
+%% boolean value in 4-th position, with value TRUE for direct (i.e.
+%% turning Counter-clockwise) circles.
+%%
+%% Circle arcs are represented by their center, their radius, the starting
+%% angle and the angle extent, both in degrees:
+%% CA = [xc yc r theta0 dtheta];
+%%
+%% Ellipses are represented by their center, their 2 semi-axis length, and
+%% their angle (in degrees) with Ox direction.
+%% E = [xc yc A B theta];
+%%
+%% @seealso{ellipses2d, createCircle, createDirectedCircle, enclosingCircle
+%% isPointInCircle, isPointOnCircle
+%% intersectLineCircle, intersectCircles, radicalAxis
+%% circleAsPolygon, circleArcAsCurve
+%% drawCircle, drawCircleArc}
+%% @end deftypefn
+
+function circles2d(varargin)
+
+ help('circles2d');
+
+endfunction
+
diff --git a/inst/geom2d/clipEdge.m b/inst/geom2d/clipEdge.m
new file mode 100644
index 0000000..59d756a
--- /dev/null
+++ b/inst/geom2d/clipEdge.m
@@ -0,0 +1,203 @@
+%% Copyright (c) 2011, INRA
+%% 2010-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} {@var{edge2} =} clipEdge (@var{edge}, @var{box})
+%% Clip an edge with a rectangular box.
+%%
+%% @var{edge}: [x1 y1 x2 y2],
+%% @var{box} : [xmin xmax ; ymin ymax] or [xmin xmax ymin ymax];
+%% return :
+%% @var{edge2} = [xc1 yc1 xc2 yc2];
+%%
+%% If clipping is null, return [0 0 0 0];
+%%
+%% if @var{edge} is a [nx4] array, return an [nx4] array, corresponding to each
+%% clipped edge.
+%%
+%% @seealso{edges2d, boxes2d, clipLine}
+%% @end deftypefn
+
+function edge2 = clipEdge(edge, bb)
+
+ % process data input
+ if size(bb, 1)==2
+ bb = bb';
+ end
+
+ % get limits of window
+ xmin = bb(1);
+ xmax = bb(2);
+ ymin = bb(3);
+ ymax = bb(4);
+
+
+ % convert window limits into lines
+ lineX0 = [xmin ymin xmax-xmin 0];
+ lineX1 = [xmin ymax xmax-xmin 0];
+ lineY0 = [xmin ymin 0 ymax-ymin];
+ lineY1 = [xmax ymin 0 ymax-ymin];
+
+
+ % compute outcodes of each vertex
+ p11 = edge(:,1)<xmin; p21 = edge(:,3)<xmin;
+ p12 = edge(:,1)>xmax; p22 = edge(:,3)>xmax;
+ p13 = edge(:,2)<ymin; p23 = edge(:,4)<ymin;
+ p14 = edge(:,2)>ymax; p24 = edge(:,4)>ymax;
+ out1 = [p11 p12 p13 p14];
+ out2 = [p21 p22 p23 p24];
+
+ % detect edges totally inside window -> no clip.
+ inside = sum(out1 | out2, 2)==0;
+
+ % detect edges totally outside window
+ outside = sum(out1 & out2, 2)>0;
+
+ % select edges not totally outside, and process separately edges totally
+ % inside window
+ ind = find(~(inside | outside));
+
+
+ edge2 = zeros(size(edge));
+ edge2(inside, :) = edge(inside, :);
+
+
+ for i=1:length(ind)
+ % current edge
+ iedge = edge(ind(i), :);
+
+ % compute intersection points with each line of bounding window
+ px0 = intersectLineEdge(lineX0, iedge);
+ px1 = intersectLineEdge(lineX1, iedge);
+ py0 = intersectLineEdge(lineY0, iedge);
+ py1 = intersectLineEdge(lineY1, iedge);
+
+ % create array of points
+ points = [px0; px1; py0; py1; iedge(1:2); iedge(3:4)];
+
+ % remove infinite points (edges parallel to box edges)
+ points = points(all(isfinite(points), 2), :);
+
+ % sort points by x then y
+ points = sortrows(points);
+
+ % get center positions between consecutive points
+ centers = (points(2:end,:) + points(1:end-1,:))/2;
+
+ % find the centers (if any) inside window
+ inside = find( centers(:,1)>=xmin & centers(:,2)>=ymin & ...
+ centers(:,1)<=xmax & centers(:,2)<=ymax);
+
+ % if multiple segments are inside box, which can happen due to finite
+ % resolution, only take the longest segment
+ if length(inside)>1
+ % compute delta vectors of the segments
+ dv = points(inside+1,:) - points(inside,:);
+ % compute lengths of segments
+ len = hypot(dv(:,1), dv(:,2));
+ % find index of longest segment
+ [a, I] = max(len); %#ok<ASGLU>
+ inside = inside(I);
+ end
+
+ % if one of the center points is inside box, then the according edge
+ % segment is indide box
+ if length(inside)==1
+ % restore same direction of edge
+ if iedge(1)>iedge(3) || (iedge(1)==iedge(3) && iedge(2)>iedge(4))
+ edge2(i, :) = [points(inside+1,:) points(inside,:)];
+ else
+ edge2(i, :) = [points(inside,:) points(inside+1,:)];
+ end
+ end
+
+ end % end of loop of edges
+endfunction
+
+%!demo
+%! bb = [0 100 0 100];
+%! edge = [-10 10 90 110];
+%! ec = clipEdge (edge, bb);
+%!
+%! drawBox(bb,'color','k');
+%! line(edge([1 3]),edge([2 4]),'color','b');
+%! line(ec([1 3]),ec([2 4]),'color','r','linewidth',2);
+%! axis tight
+%! v = axis ();
+%! axis(v+[0 10 -10 0])
+
+%!shared bb
+%! bb = [0 100 0 100];
+%!assert (clipEdge([20 30 80 60], bb), [20 30 80 60],1e-6);
+%!assert (clipEdge([0 30 80 60], bb), [0 30 80 60],1e-6);
+%!assert (clipEdge([0 30 100 60], bb), [0 30 100 60],1e-6);
+%!assert (clipEdge([30 0 80 100], bb), [30 0 80 100],1e-6);
+%!assert (clipEdge([0 0 100 100], bb), [0 0 100 100],1e-6);
+%!assert (clipEdge([0 100 100 0], bb), [0 100 100 0],1e-6);
+%!assert (clipEdge([20 60 120 60], bb), [20 60 100 60],1e-6);
+%!assert (clipEdge([-20 60 80 60], bb), [0 60 80 60],1e-6);
+%!assert (clipEdge([20 60 20 160], bb), [20 60 20 100],1e-6);
+%!assert (clipEdge([20 -30 20 60], bb), [20 0 20 60],1e-6);
+%!assert (clipEdge([120 30 180 60], bb), [0 0 0 0],1e-6);
+%!assert (clipEdge([-20 30 -80 60], bb), [0 0 0 0],1e-6);
+%!assert (clipEdge([30 120 60 180], bb), [0 0 0 0],1e-6);
+%!assert (clipEdge([30 -20 60 -80], bb), [0 0 0 0],1e-6);
+%!assert (clipEdge([-120 110 190 150], bb), [0 0 0 0],1e-6);
+%!assert ([50 50 100 50], clipEdge([50 50 150 50], bb),1e-6);
+%!assert ([50 50 0 50], clipEdge([50 50 -50 50], bb),1e-6);
+%!assert ([50 50 50 100], clipEdge([50 50 50 150], bb),1e-6);
+%!assert ([50 50 50 0], clipEdge([50 50 50 -50], bb),1e-6);
+%!assert ([80 50 100 70], clipEdge([80 50 130 100], bb),1e-6);
+%!assert ([80 50 100 30], clipEdge([80 50 130 0], bb),1e-6);
+%!assert ([20 50 0 70], clipEdge([20 50 -30 100], bb),1e-6);
+%!assert ([20 50 0 30], clipEdge([20 50 -30 0], bb),1e-6);
+%!assert ([50 80 70 100], clipEdge([50 80 100 130], bb),1e-6);
+%!assert ([50 80 30 100], clipEdge([50 80 0 130], bb),1e-6);
+%!assert ([50 20 70 0], clipEdge([50 20 100 -30], bb),1e-6);
+%!assert ([50 20 30 0], clipEdge([50 20 0 -30], bb),1e-6);
+%!assert ([100 50 50 50], clipEdge([150 50 50 50], bb),1e-6);
+%!assert ([0 50 50 50], clipEdge([-50 50 50 50], bb),1e-6);
+%!assert ([50 100 50 50], clipEdge([50 150 50 50], bb),1e-6);
+%!assert ([50 0 50 50], clipEdge([50 -50 50 50], bb),1e-6);
+%!assert ([100 70 80 50], clipEdge([130 100 80 50], bb),1e-6);
+%!assert ([100 30 80 50], clipEdge([130 0 80 50], bb),1e-6);
+%!assert ([0 70 20 50], clipEdge([-30 100 20 50], bb),1e-6);
+%!assert ([0 30 20 50], clipEdge([-30 0 20 50], bb),1e-6);
+%!assert ([70 100 50 80], clipEdge([100 130 50 80], bb),1e-6);
+%!assert ([30 100 50 80], clipEdge([0 130 50 80], bb),1e-6);
+%!assert ([70 0 50 20], clipEdge([100 -30 50 20], bb),1e-6);
+%!assert ([30 0 50 20], clipEdge([0 -30 50 20], bb),1e-6);
+%!assert ([0 20 80 100], clipEdge([-10 10 90 110], bb),1e-6);
+
+
+
diff --git a/inst/geom2d/clipLine.m b/inst/geom2d/clipLine.m
new file mode 100644
index 0000000..0dbaf6c
--- /dev/null
+++ b/inst/geom2d/clipLine.m
@@ -0,0 +1,210 @@
+%% 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} {@var{edge} =} clipLine (@var{line}, @var{box})
+%% Clip a line with a box.
+%%
+%% @var{line} is a straight line given as a 4 element row vector: [x0 y0 dx dy],
+%% with (x0 y0) being a point of the line and (dx dy) a direction vector,
+%% @var{box} is the clipping box, given by its extreme coordinates:
+%% [xmin xmax ymin ymax].
+%% The result is given as an edge, defined by the coordinates of its 2
+%% extreme points: [x1 y1 x2 y2].
+%% If line does not intersect the box, [NaN NaN NaN NaN] is returned.
+%%
+%% Function works also if @var{line} is a Nx4 array, if @var{box} is a Nx4 array, or
+%% if both @var{line} and @var{box} are Nx4 arrays. In these cases, @var{edge} is a Nx4
+%% array.
+%%
+%% Example:
+%%
+%% @example
+%% line = [30 40 10 0];
+%% box = [0 100 0 100];
+%% res = clipLine(line, box)
+%% res =
+%% 0 40 100 40
+%% @end example
+%%
+%% @seealso{lines2d, boxes2d, edges2d, clipEdge, clipRay}
+%% @end deftypefn
+
+function edge = clipLine(lin, bb, varargin)
+
+ % adjust size of two input arguments
+ if size(lin, 1)==1
+ lin = repmat(lin, size(bb, 1), 1);
+ elseif size(bb, 1)==1
+ bb = repmat(bb, size(lin, 1), 1);
+ elseif size(lin, 1) ~= size(bb, 1)
+ error('bad sizes for input');
+ end
+
+ % allocate memory
+ nbLines = size(lin, 1);
+ edge = zeros(nbLines, 4);
+
+ % main loop on lines
+ for i=1:nbLines
+ % extract limits of the box
+ xmin = bb(i, 1);
+ xmax = bb(i, 2);
+ ymin = bb(i, 3);
+ ymax = bb(i, 4);
+
+ % use direction vector for box edges similar to direction vector of the
+ % line in order to reduce computation errors
+ delta = hypot(lin(i,3), lin(i,4));
+
+
+ % compute intersection with each edge of the box
+
+ % lower edge
+ px1 = intersectLines(lin(i,:), [xmin ymin delta 0]);
+ % right edge
+ px2 = intersectLines(lin(i,:), [xmax ymin 0 delta]);
+ % upper edge
+ py1 = intersectLines(lin(i,:), [xmax ymax -delta 0]);
+ % left edge
+ py2 = intersectLines(lin(i,:), [xmin ymax 0 -delta]);
+
+ % remove undefined intersections (case of lines parallel to box edges)
+ points = [px1 ; px2 ; py1 ; py2];
+ points = points(isfinite(points(:,1)), :);
+
+ % sort points according to their position on the line
+ pos = linePosition(points, lin(i,:));
+ [pos inds] = sort(pos); %#ok<ASGLU>
+ points = points(inds, :);
+
+ % create clipped edge by using the two points in the middle
+ ind = size(points, 1)/2;
+ inter1 = points(ind,:);
+ inter2 = points(ind+1,:);
+ edge(i, 1:4) = [inter1 inter2];
+
+ % check that middle point of the edge is contained in the box
+ midX = mean(edge(i, [1 3]));
+ xOk = xmin <= midX && midX <= xmax;
+ midY = mean(edge(i, [2 4]));
+ yOk = ymin <= midY && midY <= ymax;
+
+ % if one of the bounding condition is not met, set edge to NaN
+ if ~(xOk && yOk)
+ edge (i,:) = NaN;
+ end
+ end
+endfunction
+
+%!demo
+%! lin = [30 40 10 0];
+%! bb = [0 100 0 100];
+%! res = clipLine(lin, bb)
+%!
+%! drawBox(bb,'color','k');
+%! line(lin([1 3]),lin([2 4]),'color','b');
+%! line(res([1 3]),res([2 4]),'color','r','linewidth',2);
+%! axis tight
+%! v = axis ();
+%! axis(v+[0 10 -10 0])
+
+%!test % inside, to the right % inside, to the left% outside
+%! bb = [0 100 0 100];
+%! lin = [30 40 10 0];
+%! edge = [0 40 100 40];
+%! assert (edge, clipLine(lin, bb), 1e-6);
+%! lin = [30 40 -10 0];
+%! edge = [100 40 0 40];
+%! assert (edge, clipLine(lin, bb), 1e-6);
+%! lin = [30 140 10 0];
+%! assert (sum(isnan(clipLine(lin, bb)))==4);
+
+%!test % inside, upward % inside, downward % outside
+%! bb = [0 100 0 100];
+%! lin = [30 40 0 10];
+%! edge = [30 0 30 100];
+%! assert (edge, clipLine(lin, bb), 1e-6);
+%! lin = [30 40 0 -10];
+%! edge = [30 100 30 0];
+%! assert (edge, clipLine(lin, bb), 1e-6);
+%! lin = [140 30 0 10];
+%! assert (sum(isnan(clipLine(lin, bb)))==4);
+
+%!test % inside, top right corner% inside, down right corner % outside
+%! bb = [0 100 0 100];
+%! lin = [80 30 10 10];
+%! edge = [50 0 100 50];
+%! assert (edge, clipLine(lin, bb), 1e-6);
+%! lin = [20 70 10 10];
+%! edge = [0 50 50 100];
+%! assert (edge, clipLine(lin, bb), 1e-6);
+%! lin = [140 -30 10 10];
+%! assert (sum(isnan(clipLine(lin, bb)))==4);
+%! lin = [-40 130 10 10];
+%! assert (sum(isnan(clipLine(lin, bb)))==4);
+
+%!test %multilines % inside, top right corner
+%! bb = [0 100 0 100];
+%! lin = [...
+%! 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; ...
+%! NaN NaN NaN NaN; ...
+%! NaN NaN NaN NaN; ...
+%! ];
+%! clipped = clipLine(lin, bb);
+%! assert (4, size(clipped, 1));
+%! assert (edge(1:2, :), clipped(1:2, :), 1e-6);
+%! assert (sum(isnan(clipped(3,:)))==4);
+%! assert (sum(isnan(clipped(4,:)))==4);
+
+%!test % test clipping of horizontal lines % inside, to the right
+%! bb = [-1 1 -1 1]*1e10;
+%! lin = [3 0 1 2];
+%! D = 1e10;
+%! edge = [3-D/2 -D 3+D/2 D];
+%! clipped = clipLine(lin, bb);
+%! assert (edge, clipped);
+
+%!test % inside, to the right
+%! bb = [-1 1 -1 1]*100;
+%! lin = [3 0 1*1e10 2*1e10];
+%! D = 100;
+%! edge = [3-D/2 -D 3+D/2 D];
+%! clipped = clipLine(lin, bb);
+%! assert (edge, clipped, 1e-6);
diff --git a/inst/geom2d/clipPoints.m b/inst/geom2d/clipPoints.m
new file mode 100644
index 0000000..636f6b8
--- /dev/null
+++ b/inst/geom2d/clipPoints.m
@@ -0,0 +1,101 @@
+%% Copyright (c) 2011, INRA
+%% 2008-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} {@var{points2} =} clipPoints (@var{points}, @var{box})
+%% Clip a set of points by a box.
+%%
+%% Returns the set @var{points2} which are located inside of the box @var{box}.
+%%
+%% @seealso{points2d, boxes2d, clipLine, drawPoint}
+%% @end deftypefn
+
+function points = clipPoints(points, bb)
+
+ % get bounding box limits
+ xmin = bb(1);
+ xmax = bb(2);
+ ymin = bb(3);
+ ymax = bb(4);
+
+ % compute indices of points inside visible area
+ xOk = points(:,1)>=xmin & points(:,1)<=xmax;
+ yOk = points(:,2)>=ymin & points(:,2)<=ymax;
+
+ % keep only points inside box
+ points = points(xOk & yOk, :);
+
+endfunction
+
+%!demo
+%! points = 2*rand(100,2)-1;
+%! bb = [-0.5 0.5 -0.25 0.25];
+%! cpo = clipPoints (points, bb);
+%!
+%! plot(points(:,1),points(:,2),'xr')
+%! hold on
+%! drawBox(bb,'color','k')
+%! plot(cpo(:,1),cpo(:,2),'*g')
+%! hold off
+
+%!shared bb
+%! bb = [0 10 0 20];
+
+%!test
+%! corners = [0 0;10 0;0 20;10 20];
+%! cornersClipped = clipPoints(corners, bb);
+%! assert (4, size(cornersClipped, 1));
+%! assert (corners, cornersClipped, 1e-6);
+
+%!test
+%! borders = [0 5;10 5;5 0;5 20];
+%! bordersClipped = clipPoints(borders, bb);
+%! assert (4, size(bordersClipped, 1));
+%! assert (borders, bordersClipped, 1e-6);
+
+%!test
+%! inside = [5 5;5 10;5 15];
+%! insideClipped = clipPoints(inside, bb);
+%! assert (size(inside, 1), size(insideClipped, 1));
+%! assert (inside, insideClipped);
+
+%!test
+%! points = [-1 0;11 0;-1 20;11 20;0 -1;0 21;10 -1;10 21];
+%! pointsClipped = clipPoints(points, bb);
+%! assert (0, size(pointsClipped, 1));
+
+%!test
+%! points = [-5 10;0 10;5 10;10 10; 15 10];
+%! pointsClipped = clipPoints(points, bb);
+%! assert (3, size(pointsClipped, 1));
+%! assert (points(2:4,:), pointsClipped, 1e-6);
diff --git a/inst/geom2d/clipRay.m b/inst/geom2d/clipRay.m
new file mode 100644
index 0000000..64d0507
--- /dev/null
+++ b/inst/geom2d/clipRay.m
@@ -0,0 +1,172 @@
+%% Copyright (c) 2011, INRA
+%% 2010-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} {[@var{edge} @var{inside}] =} clipRay (@var{ray}, @var{box})
+%% Clip a ray with a box.
+%%
+%% @var{ray} is a straight ray given as a 4 element row vector: [x0 y0 dx dy],
+%% with (x0 y0) being the origin of the ray and (dx dy) its direction
+%% vector, @var{box} is the clipping box, given by its extreme coordinates:
+%% [xmin xmax ymin ymax].
+%% The result is given as an edge, defined by the coordinates of its 2
+%% extreme points: [x1 y1 x2 y2].
+%% If the ray does not intersect the box, [NaN NaN NaN NaN] is returned.
+%%
+%% Function works also if @var{ray} is a Nx4 array, if @var{box} is a Nx4 array, or
+%% if both @var{ray} and @var{box} are Nx4 arrays. In these cases, @var{edge} is a Nx4
+%% array.
+%%
+%% @seealso{rays2d, boxes2d, edges2d, clipLine, drawRay}
+%% @end deftypefn
+
+function [edge isInside] = clipRay(ray, bb)
+
+ % adjust size of two input arguments
+ if size(ray, 1)==1
+ ray = repmat(ray, size(bb, 1), 1);
+ elseif size(bb, 1)==1
+ bb = repmat(bb, size(ray, 1), 1);
+ elseif size(ray, 1) != size(bb, 1)
+ error('bad sizes for input');
+ end
+
+ % first compute clipping of supporting line
+ edge = clipLine(ray, bb);
+
+ % detectes valid edges (edges outside box are all NaN)
+ inds = find(isfinite(edge(:, 1)));
+
+ % compute position of edge extremities relative to the ray
+ pos1 = linePosition(edge(inds,1:2), ray(inds,:));
+ pos2 = linePosition(edge(inds,3:4), ray(inds,:));
+
+ % if first point is before ray origin, replace by origin
+ edge(inds(pos1<0), 1:2) = ray(inds(pos1<0), 1:2);
+
+ % if last point of edge is before origin, set all edge to NaN
+ edge(inds(pos2<0), :) = NaN;
+
+ % eventually returns result about inside or outside
+ if nargout>1
+ isInside = isfinite(edge(:,1));
+ end
+
+endfunction
+
+%!shared bb
+%! bb = [0 100 0 100];
+
+%!test % inside
+%! origin = [30 40];
+%! direction = [10 0];
+%! ray = [origin direction];
+%! expected = [30 40 100 40];
+%! assert (expected, clipRay(ray, bb), 1e-6);
+
+%!test % outside
+%! origin = [30 140];
+%! direction = [10 0];
+%! ray = [origin direction];
+%! assert (sum(isnan(clipRay(ray, bb)))==4);
+
+%!test % line inside, but ray outside
+%! origin = [130 40];
+%! direction = [10 0];
+%! ray = [origin direction];
+%! assert (sum(isnan(clipRay(ray, bb)))==4);
+
+%!test % inside
+%! origin = [30 40];
+%! direction = [-10 0];
+%! ray = [origin direction];
+%! expected = [30 40 0 40];
+%! assert (expected, clipRay(ray, bb), 1e-6);
+
+%!test % outside
+%! origin = [30 140];
+%! direction = [-10 0];
+%! ray = [origin direction];
+%! assert (sum(isnan(clipRay(ray, bb)))==4);
+
+%!test % line inside, but ray outside
+%! origin = [-30 40];
+%! direction = [-10 0];
+%! ray = [origin direction];
+%! assert (sum(isnan(clipRay(ray, bb)))==4);
+
+%!test % inside
+%! origin = [30 40];
+%! direction = [0 10];
+%! ray = [origin direction];
+%! expected = [30 40 30 100];
+%! assert (expected, clipRay(ray, bb), 1e-6);
+
+%!test % outside
+%! origin = [130 40];
+%! direction = [0 10];
+%! ray = [origin direction];
+%! assert (sum(isnan(clipRay(ray, bb)))==4);
+
+%!test % line inside, but ray outside
+%! origin = [30 140];
+%! direction = [0 10];
+%! ray = [origin direction];
+%! assert (sum(isnan(clipRay(ray, bb)))==4);
+
+%!test % inside
+%! origin = [30 40];
+%! direction = [0 -10];
+%! ray = [origin direction];
+%! expected = [30 40 30 0];
+%! assert (expected, clipRay(ray, bb), 1e-6);
+
+%!test % outside
+%! origin = [130 40];
+%! direction = [0 -10];
+%! ray = [origin direction];
+%! assert (sum(isnan(clipRay(ray, bb)))==4);
+
+%!test % line inside, but ray outside
+%! origin = [30 -40];
+%! direction = [0 -10];
+%! ray = [origin direction];
+%! assert (sum(isnan(clipRay(ray, bb)))==4);
+
+%!test
+%! origins = [30 40;30 40;30 140;130 40];
+%! directions = [10 0;0 10;10 0;0 10];
+%! rays = [origins directions];
+%! expected = [30 40 100 40;30 40 30 100;NaN NaN NaN NaN;NaN NaN NaN NaN];
+%! clipped = clipRay(rays, bb);
+%! assert (expected, clipped, 1e-6);
diff --git a/inst/geom2d/crackPattern.m b/inst/geom2d/crackPattern.m
new file mode 100644
index 0000000..1daca7e
--- /dev/null
+++ b/inst/geom2d/crackPattern.m
@@ -0,0 +1,189 @@
+%% 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} {@var{e} = } crackPattern (@var{box}, @var{points}, @var{alpha})
+%% Create a (bounded) crack pattern tessellation
+%%
+%% E = crackPattern2(BOX, POINTS, ALPHA)
+%% create a crack propagation pattern wit following parameters :
+%% - pattern is bounded by area BOX which is a polygon.
+%% - each crack originates from points given in POINTS
+%% - directions of each crack is given by a [NxM] array ALPHA, where M is
+%% the number of rays emanating from each seed/
+%% - a crack stop when it reaches another already created crack.
+%% - all cracks stop when they reach the border of the frame, given by box
+%% (a serie of 4 points).
+%% The result is a collection of edges, in the form [x1 y1 x2 y2].
+%%
+%% E = crackPattern2(BOX, POINTS, ALPHA, SPEED)
+%% Also specify speed of propagation of each crack.
+%%
+%%
+%% See the result with :
+%% figure;
+%% drawEdge(E);
+%%
+%% @seealso{drawEdge}
+%% @end deftypefn
+
+function edges = crackPattern(box, points, alpha, varargin)
+
+ if ~isempty(varargin)
+ speed = varargin{1};
+ else
+ speed = ones(size(points, 1), 1);
+ end
+
+ % Compute line equations for each initial crack.
+ % The two 'Inf' at the end correspond to the position of the limit.
+ % If an intersection point is found with another line, but whose position
+ % is after this value, this means that another crack stopped it before it
+ % reach the intersection point.
+ % There is one 'end position' for each side of the crack.
+ lines = [points speed.*cos(alpha) speed.*sin(alpha) Inf*ones(size(points, 1), 2)];
+
+ % initialize lines for borders, but assign a very high speed, to be sure
+ % borders will stop all cracks.
+ dx = (box([2 3 4 1],1)-box([1 2 3 4],1))*max(speed)*5;
+ dy = (box([2 3 4 1],2)-box([1 2 3 4],2))*max(speed)*5;
+
+ % add borders to the lines set
+ lines = [lines ; createLine(box, dx, dy) Inf*ones(4,2)];
+
+ edges = zeros(0, 4);
+
+
+ while true
+ modif = 0;
+
+ % try to update each line
+ for i=1:size(points, 1)
+
+ % compute intersections with all other lines
+ pi = intersectLines(lines(i,:), lines);
+
+ % compute position of all intersection points on the current line
+ pos = linePosition(pi, lines(i,:));
+
+ % consider points to the right (positive position), and sort them
+ indr = find(pos>=0 & pos~=Inf);
+ [posr, indr2] = sort(pos(indr));
+
+
+ % look for the closest intersection to the right
+ for i2=1:length(indr2)
+
+ % index of intersected line
+ il = indr(indr2(i2));
+
+ % position of point relative to intersected line
+ pos2 = linePosition(pi(il, :), lines(il, :));
+
+ % depending on the sign of position, tests if the line2 can
+ % stop the current line, or if it was stopped before
+ if pos2>0
+ if pos2<abs(posr(i2)) && pos2<lines(il, 5)
+ if lines(i, 5) ~= posr(i2)
+ edges(i, 3:4) = pi(il,:);
+ lines(i, 5) = posr(i2);
+ modif = 1;
+ end
+ break;
+ end
+ else
+ if abs(pos2)<abs(posr(i2)) && abs(pos2)<lines(il, 6)
+ if lines(i, 5) ~= posr(i2);
+ edges(i, 3:4) = pi(il,:);
+ lines(i, 5) = posr(i2);
+ modif = 1;
+ end
+ break;
+ end
+ end
+
+ end % end processing of right points of the line
+
+
+
+ % consider points to the left (negative position), and sort them
+ indl = find(pos<=0 && pos~=Inf);
+ [posl, indl2] = sort(abs(pos(indl)));
+
+ % look for the closest intersection to the right
+ for i2=1:length(indl2)
+ % index of intersected line
+ il = indl(indl2(i2));
+
+ % position of point relative to intersected line
+ pos2 = linePosition(pi(il, :), lines(il, :));
+
+ % depending on the sign of position, tests if the line2 can
+ % stop the current line, or if it was stopped before
+ if pos2>0
+ if pos2<abs(posl(i2)) && pos2<lines(il, 5)
+ if lines(i, 6) ~= abs(posl(i2));
+ edges(i, 1:2) = pi(il, :);
+ lines(i, 6) = abs(posl(i2));
+ modif = 1;
+ end
+ break;
+ end
+ else
+ if abs(pos2)<abs(posl(i2)) && abs(pos2)<lines(il, 6)
+ if lines(i, 6) ~= abs(posl(i2));
+ edges(i, 1:2) = pi(il, :);
+ lines(i, 6) = abs(posl(i2));
+ modif = 1;
+ end
+ break;
+ end
+ end
+
+ end % end processing of left points of the line
+
+
+ end % end processing of all lines
+
+ % break the infinite loop if no more modification was made
+ if ~modif
+ break;
+ end
+ end
+
+ % add edges of the surronding box.
+ edges = [edges ; box(1,:) box(2,:) ; box(2,:) box(3,:); ...
+ box(3,:) box(4,:) ; box(4,:) box(1,:) ];
+
+endfunction
+
diff --git a/inst/geom2d/crackPattern2.m b/inst/geom2d/crackPattern2.m
new file mode 100644
index 0000000..0f61565
--- /dev/null
+++ b/inst/geom2d/crackPattern2.m
@@ -0,0 +1,148 @@
+%% Copyright (c) 2011, INRA
+%% 2004-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} {@var{e} = } crackPattern2 (@var{box}, @var{points}, @var{alpha})
+%% Create a (bounded) crack pattern tessellation
+%%
+%% E = crackPattern2(BOX, POINTS, ALPHA)
+%% create a crack propagation pattern wit following parameters :
+%% - pattern is bounded by area BOX which is a polygon.
+%% - each crack originates from points given in POINTS
+%% - directions of each crack is given by a [NxM] array ALPHA, where M is
+%% the number of rays emanating from each seed/
+%% - a crack stop when it reaches another already created crack.
+%% - all cracks stop when they reach the border of the frame, given by box
+%% (a serie of 4 points).
+%% The result is a collection of edges, in the form [x1 y1 x2 y2].
+%%
+%% E = crackPattern2(BOX, POINTS, ALPHA, SPEED)
+%% Also specify speed of propagation of each crack.
+%%
+%%
+%% See the result with :
+%% figure;
+%% drawEdge(E);
+%%
+%% @seealso{drawEdge}
+%% @end deftypefn
+
+function edges = crackPattern2(box, points, alpha, varargin)
+
+ if ~isempty(varargin)
+ speed = varargin{1};
+ else
+ speed = ones(size(points, 1), 1);
+ end
+
+ % Compute line equations for each initial crack.
+ % The 'Inf' at the end correspond to the position of the limit.
+ % If an intersection point is found with another line, but whose position
+ % is after this value, this means that another crack stopped it before it
+ % reach the intersection point.
+ NP = size(points, 1);
+ lines = zeros(0, 5);
+ for i=1:size(alpha, 2)
+ lines = [lines; points speed.*cos(alpha(:,i)) speed.*sin(alpha(:,i)) Inf*ones(NP, 1)];
+ end
+ NL = size(lines, 1);
+
+ % initialize lines for borders, but assign a very high speed, to be sure
+ % borders will stop all cracks.
+ dx = (box([2 3 4 1],1)-box([1 2 3 4],1))*max(speed)*5;
+ dy = (box([2 3 4 1],2)-box([1 2 3 4],2))*max(speed)*5;
+
+ % add borders to the lines set
+ lines = [lines ; createLine(box, dx, dy) Inf*ones(4,1)];
+
+ edges = zeros(0, 4);
+
+
+ while true
+ modif = 0;
+
+ % try to update each line
+ for i=1:NL
+
+ % initialize first point of edge
+ edges(i, 1:2) = lines(i, 1:2);
+
+ % compute intersections with all other lines
+ pi = intersectLines(lines(i,:), lines);
+
+ % compute position of all intersection points on the current line
+ pos = linePosition(pi, lines(i,:));
+
+
+ % consider points to the right (positive position), and sort them
+ indr = find(pos>1e-12 & pos~=Inf);
+ [posr, indr2] = sort(pos(indr));
+
+
+ % look for the closest intersection to the right
+ for i2=1:length(indr2)
+
+ % index of intersected line
+ il = indr(indr2(i2));
+
+ % position of point relative to intersected line
+ pos2 = linePosition(pi(il, :), lines(il, :));
+
+ % depending on the sign of position, tests if the line2 can
+ % stop the current line, or if it was stopped before
+ if pos2>0
+ if pos2<abs(posr(i2)) && pos2<lines(il, 5)
+ if lines(i, 5) ~= posr(i2)
+ edges(i, 3:4) = pi(il,:);
+ lines(i, 5) = posr(i2);
+ modif = 1;
+ end
+ break;
+ end
+ end
+ end % end processing of right points of the line
+
+
+ end % end processing of all lines
+
+ % break the infinite loop if no more modification was made
+ if ~modif
+ break;
+ end
+ end
+
+ % add edges of the surronding box.
+ edges = [edges ; box(1,:) box(2,:) ; box(2,:) box(3,:); ...
+ box(3,:) box(4,:) ; box(4,:) box(1,:) ];
+
+endfunction
diff --git a/inst/geom2d/createBasisTransform.m b/inst/geom2d/createBasisTransform.m
new file mode 100644
index 0000000..b9a8f83
--- /dev/null
+++ b/inst/geom2d/createBasisTransform.m
@@ -0,0 +1,108 @@
+%% Copyright (c) 2011, INRA
+%% 2010-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 @var{source} and binary forms, with or without
+%% modification, are permitted provided that the following conditions are met:
+%%
+%% 1. Redistributions of @var{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} {@var{T} = } createBasisTransfrom (@var{@var{target}})
+%% @deftypefnx {Function File} {@var{T} = } createBasisTransfrom (@var{@var{source}}, @var{@var{target}})
+%% Compute matrix for transforming a basis into another basis
+%%
+%% With only one input arguemnt, assumes the @var{source} is the standard (Oij) basis, with origin at (0,0),
+%% first direction vector equal to (1,0) and second direction vector
+%% equal to (0,1). Otherwise @var{@var{source}} specifies the @var{source} basis.
+%%
+%% Both @var{source} and @var{target} represent basis, in the following form:
+%% [x0 y0 ex1 ey1 ex2 ey2]
+%% [y0 y0] is the origin of the basis, [ex1 ey1] is the first direction
+%% vector, and [ex2 ey2] is the second direction vector.
+%%
+%% The result @var{T} is a 3-by-3 matrix such that a point expressed with
+%% coordinates of the first basis will be represented by new coordinates
+%% @code{P2 = transformPoint(P1, @var{T})} in the @var{target} basis.
+%%
+%% Example
+%% @example
+%% % standard basis transform
+%% src = [0 0 1 0 0 1];
+%% % @var{target} transform, just a rotation by atan(2/3) followed by a scaling
+%% tgt = [0 0 .75 .5 -.5 .75];
+%% % compute transform
+%% trans = createBasisTransform(src, tgt);
+%% % transform the point (.25,1.25) into the point (1,1)
+%% p1 = [.25 1.25];
+%% p2 = transformPoint(p1, trans)
+%% ans =
+%% 1 1
+%% @end example
+%%
+%% @seealso{transforms2d}
+%% @end deftypefn
+
+function transfo = createBasisTransform(source, target)
+
+ % init basis transform to identity
+ t1 = eye(3);
+ t2 = eye(3);
+
+ if nargin==2
+ % from source to reference basis
+ t1(1:2, 1) = source(3:4);
+ t1(1:2, 2) = source(5:6);
+ t1(1:2, 3) = source(1:2);
+ else
+ % if only one input, use first input as target basis, and leave the
+ % first matrix to identity
+ target = source;
+ end
+
+ % from reference to target basis
+ t2(1:2, 1) = target(3:4);
+ t2(1:2, 2) = target(5:6);
+ t2(1:2, 3) = target(1:2);
+
+ % compute transfo
+ % same as: transfo = inv(t2)*t1;
+ transfo = t2\t1;
+
+endfunction
+
+%!demo
+%! % standard basis transform
+%! src = [0 0 1 0 0 1];
+%! % target transform, just a rotation by atan(2/3) followed by a scaling
+%! tgt = [0 0 .75 .5 -.5 .75];
+%! % compute transform
+%! trans = createBasisTransform(src, tgt);
+%! % transform the point (.25,1.25) into the point (1,1)
+%! p1 = [.25 1.25];
+%! p2 = transformPoint(p1, trans)
+
diff --git a/inst/geom2d/createCircle.m b/inst/geom2d/createCircle.m
new file mode 100644
index 0000000..3f9eb40
--- /dev/null
+++ b/inst/geom2d/createCircle.m
@@ -0,0 +1,123 @@
+%% Copyright (c) 2011, INRA
+%% 2003-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} {@var{circle} = } createCircle (@var{p1}, @var{p2}, @var{p3})
+%% @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.
+%% 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
+%% throuh the point @var{p2}.
+%%
+%% Works also when input are point arrays the same size, in this case the
+%% result has as many lines as the point arrays.
+%%
+%% Example
+%%
+%% @example
+%% % Draw a circle passing through 3 points.
+%% p1 = [10 15];
+%% p2 = [15 20];
+%% p3 = [10 25];
+%% circle = createCircle(p1, p2, p3);
+%% figure; hold on; axis equal; axis([0 50 0 50]);
+%% drawPoint([p1 ; p2; p3]);
+%% drawCircle(circle);
+%% @end example
+%%
+%% @seealso{circles2d, createDirectedCircle}
+%% @end deftypefn
+
+function circle = createCircle(varargin)
+
+ if nargin == 2
+ % inputs are the center and a point on the circle
+ p1 = varargin{1};
+ p2 = varargin{2};
+ 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};
+ p2 = varargin{2};
+ p3 = varargin{3};
+
+ % compute circle center
+ line1 = medianLine(p1, p2);
+ line2 = medianLine(p1, p3);
+ point = intersectLines(line1, line2);
+ x0 = point(:, 1);
+ y0 = point(:, 2);
+
+ % circle radius
+ r = hypot((p1(:,1)-x0), (p1(:,2)-y0));
+ end
+
+ % create array for returning result
+ circle = [x0 y0 r];
+
+endfunction
+
+%!test
+%! p1 = [10 15];
+%! p2 = [15 20];
+%! p3 = [10 25];
+%! exp = [10 20 5];
+%! circle = createCircle(p1, p2, p3);
+%! assertEqual(exp, circle);
+%! circle = createCircle(p3, p1, p2);
+%! assertEqual(exp, circle);
+%! circle = createCircle(p2, p3, p1);
+%! assertEqual(exp, circle);
+
+%!test
+%! p1 = [10 15];
+%! p2 = [15 20];
+%! p3 = [10 25];
+%! exp = [10 20 5];
+%! p1 = [p1; p1+10; p1+20; p1-5];
+%! p2 = [p2; p2+10; p2+20; p2-5];
+%! p3 = [p3; p3+10; p3+20; p3-5];
+%! exp = repmat(exp, 4, 1) + [0 0 0;10 10 0;20 20 0;-5 -5 0];
+%! circle = createCircle(p1, p2, p3);
+%! assertEqual(exp, circle);
+%! circle = createCircle(p3, p1, p2);
+%! assertEqual(exp, circle);
+%! circle = createCircle(p2, p3, p1);
+%! assertEqual(exp, circle);
+
diff --git a/inst/geom2d/createDirectedCircle.m b/inst/geom2d/createDirectedCircle.m
new file mode 100644
index 0000000..fdcdf7a
--- /dev/null
+++ b/inst/geom2d/createDirectedCircle.m
@@ -0,0 +1,92 @@
+%% Copyright (c) 2011, INRA
+%% 2005-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} {@var{circle} = } createDirectedCircle (@var{p1}, @var{p2}, @var{p3})
+%% @deftypefnx {Function File} {@var{circle} = } createDirectedCircle (@var{p1}, @var{p2})
+%% Create a circle from 2 or 3 points.
+%%
+%% Creates the circle passing through the 3 given points.
+%% C is a 1x4 array of the form: [XC YX R INV].
+%%
+%% When two points are given, creates the circle whith center @var{p1} and passing
+%% throuh the point @var{p2}.
+%%
+%% Works also when input are point arrays the same size, in this case the
+%% result has as many lines as the point arrays.
+%%
+%% Example
+%%
+%%
+%% @seealso{circles2d, createCircle}
+%% @end deftypefn
+
+function circle = createDirectedCircle(varargin)
+
+ if nargin == 2
+ % inputs are the center and a point on the circle
+ p1 = varargin{1};
+ p2 = varargin{2};
+ x0 = (p1(:,1) + p2(:,1))/2;
+ y0 = (p1(:,2) + p2(:,2))/2;
+ r = hypot((p2(:,1)-p1(:,1)), (p2(:,2)-p1(:,2)))/2;
+
+ % circle is direct by default
+ d = 0;
+
+ elseif nargin == 3
+ % inputs are three points on the circle
+ p1 = varargin{1};
+ p2 = varargin{2};
+ p3 = varargin{3};
+
+ % compute circle center
+ line1 = medianLine(p1, p2);
+ line2 = medianLine(p1, p3);
+ center = intersectLines(line1, line2);
+ x0 = center(:, 1);
+ y0 = center(:, 2);
+
+ % circle radius
+ r = hypot((p1(:,1)-x0), (p1(:,2)-y0));
+
+ % compute circle orientation
+ angle = angle3Points(p1, center, p2) + angle3Points(p2, center, p3);
+ d = angle>2*pi;
+ end
+
+
+ circle = [x0 y0 r d];
+
+endfunction
+
diff --git a/inst/geom2d/createEdge.m b/inst/geom2d/createEdge.m
new file mode 100644
index 0000000..4713410
--- /dev/null
+++ b/inst/geom2d/createEdge.m
@@ -0,0 +1,121 @@
+%% Copyright (c) 2011, INRA
+%% 2003-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} {@var{edge} = } createEdge (@var{p1}, @var{p2})
+%% @deftypefnx {Function File} {@var{edge} = } createEdge (@var{x0}, @var{y0}, @var{dx}, @var{dy})
+%% @deftypefnx {Function File} {@var{edge} = } createEdge (@var{param})
+%% @deftypefnx {Function File} {@var{edge} = } createEdge (@var{line}, @var{d})
+%% Create an edge between two points, or from a line.
+%%
+%% The internal format for edge representation is given by coordinates of
+%% two points : [x1 y1 x2 y2].
+%% This function can serve as a line to edge converter.
+%%
+%%
+%% Returns the edge between the two given points @var{p1} and @var{p2}.
+%%
+%% Returns the edge going through point (@var{x0}, @var{y0}) and with direction
+%% vector (@var{dx},@var{dy}).
+%%
+%% When @var{param} is an array of 4 values, creates the edge going through the
+%% point (param(1) param(2)), and with direction vector given by
+%% (param(3) param(4)).
+%%
+%% When @var{line} is given, creates the edge contained in @var{line}, with same
+%% direction and start point, but with length given by @var{d}.
+%%
+%%
+%% Note: in all cases, parameters can be vertical arrays of the same
+%% dimension. The result is then an array of edges, of dimensions [N*4].
+%%
+%% @seealso{edges2d, lines2d, drawEdge, clipEdge}
+%% @end deftypefn
+
+function edge = createEdge(varargin)
+
+ if length(varargin)==1
+ % Only one input parameter. It can be :
+ % - line angle
+ % - array of four parameters
+ % TODO : add control for arrays of lines.
+ var = varargin{1};
+
+ if size(var, 2)==4
+ % 4 parameters of the line in a single array.
+ %edge = var;
+ edge = zeros(size(var));
+ edge(:, 1:2) = var(:,1:2);
+ edge(:, 3:4) = edge(:, 1:2)+var(:,3:4);
+ elseif size(var, 2)==1
+ % 1 parameter : angle of the line, going through origin.
+ edge = [zeros(size(var,1)) zeros(size(var,1)) cos(var) sin(var)];
+ else
+ error('wrong number of dimension for arg1 : can be 1 or 4');
+ end
+
+ elseif length(varargin)==2
+ % 2 input parameters. They can be :
+ % - 2 points, then 2 arrays of 1*2 double,
+ % - a line, and a distance.
+ v1 = varargin{1};
+ v2 = varargin{2};
+ if size(v1, 2)==2
+ % first input parameter is first point, and second input is the
+ % second point.
+ %edge = [v1(:,1), v1(:,2), v2(:,1), v2(:,2)];
+ edge = [v1 v2];
+ else
+ % first input parameter is a line, and second one a distance.
+ angle = atan2(v1(:,4), v1(:,3));
+ edge = [v1(:,1), v1(:,2), v1(:,1)+v2.*cos(angle), v1(:,2)+v2.*sin(angle)];
+ end
+
+ elseif length(varargin)==3
+ % 3 input parameters :
+ % first one is a point belonging to the line,
+ % second and third ones are direction vector of the line (dx and dy).
+ p = varargin{1};
+ edge = [p(:,1) p(:,2) p(:,1)+varargin{2} p(:,2)+varargin{3}];
+
+ elseif length(varargin)==4
+ % 4 input parameters :
+ % they are x0, y0 (point belonging to line) and dx, dy (direction
+ % vector of the line).
+ % All parameters should have the same size.
+ edge = [varargin{1} varargin{2} varargin{1}+varargin{3} varargin{2}+varargin{4}];
+ else
+ error('Wrong number of arguments in ''createLine'' ');
+ end
+
+endfunction
diff --git a/inst/geom2d/createHomothecy.m b/inst/geom2d/createHomothecy.m
new file mode 100644
index 0000000..ce56505
--- /dev/null
+++ b/inst/geom2d/createHomothecy.m
@@ -0,0 +1,61 @@
+%% Copyright (c) 2011, INRA
+%% 2009-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} {@var{T} = } createHomothecy (@var{point}, @var{ratio})
+%% Create the the 3x3 matrix of an homothetic transform.
+%
+% @var{point} is the center of the homothecy, @var{ratio} is its factor.
+%
+% @seealso{transforms2d, transformPoint, createTranslation}
+%% @end deftypefn
+
+function trans = createHomothecy(point, ratio)
+
+ % extract coordinate of center
+ x0 = point(:,1);
+ y0 = point(:,2);
+
+ % compute coefficients of the matrix
+ m00 = ratio;
+ m01 = 0;
+ m02 = x0*(1-ratio);
+ m10 = 0;
+ m11 = ratio;
+ m12 = y0*(1-ratio);
+
+ % create transformation
+ trans = [m00 m01 m02; m10 m11 m12; 0 0 1];
+
+endfunction
+
diff --git a/inst/geom2d/createLine.m b/inst/geom2d/createLine.m
new file mode 100644
index 0000000..b9d48ce
--- /dev/null
+++ b/inst/geom2d/createLine.m
@@ -0,0 +1,163 @@
+%% Copyright (c) 2011, INRA
+%% 2003-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} {@var{line} =} createLine(varargin)
+%% Create a straight line from 2 points, or from other inputs
+%%
+%% Line is represented in a parametric form : [x0 y0 dx dy]
+%% x = x0 + t*dx
+%% y = y0 + t*dy;
+%%
+%%
+%% L = createLine(p1, p2);
+%% Returns the line going through the two given points.
+%%
+%% L = createLine(x0, y0, dx, dy);
+%% Returns the line going through point (x0, y0) and with direction
+%% vector(dx, dy).
+%%
+%% L = createLine(LINE);
+%% where LINE is an array of 4 values, creates the line going through the
+%% point (LINE(1) LINE(2)), and with direction given by vector (LINE(3)
+%% LINE(4)).
+%%
+%% L = createLine(THETA);
+%% Create a polar line originated at (0,0) and with angle THETA.
+%%
+%% L = createLine(RHO, THETA);
+%% Create a polar line with normal theta, and with min distance to origin
+%% equal to rho. rho can be negative, in this case, the line is the same
+%% as with CREATELINE(-rho, theta+pi), but the orientation is different.
+%%
+%%
+%% Note: in all cases, parameters can be vertical arrays of the same
+%% dimension. The result is then an array of lines, of dimensions [N*4].
+%%
+%% NOTE : A line can also be represented with a 1*5 array :
+%% [x0 y0 dx dy t].
+%% whith 't' being one of the following :
+%% - t=0 : line is a singleton (x0,y0)
+%% - t=1 : line is an edge segment, between points (x0,y0) and (x0+dx,
+%% y0+dy).
+%% - t=Inf : line is a Ray, originated from (x0,y0) and going to infinity
+%% in the direction(dx,dy).
+%% - t=-Inf : line is a Ray, originated from (x0,y0) and going to infinity
+%% in the direction(-dx,-dy).
+%% - t=NaN : line is a real straight line, and contains all points
+%% verifying the above equation.
+%% This seems us a convenient way to represent uniformly all kind of lines
+%% (including edges, rays, and even point).
+%%
+%% NOTE2 : Any line object can be represented using a 1x6 array :
+%% [x0 y0 dx dy t0 t1]
+%% the first 4 parameters define the supporting line,
+%% t0 represent the position of the first point on the line,
+%% and t1 the position of the last point.
+%% * for edges : t0 = 0, and t1=1
+%% * for straight lines : t0 = -inf, t1=inf
+%% * for rays : t0=0, t1=inf (or t0=-inf,t1=0 for inverted ray).
+%% I propose to call these objects 'lineArc'
+%%
+%% @seealso{lines2d, createEdge, createRay}
+%% @end deftypefn
+
+function line = createLine(varargin)
+
+ if length(varargin)==1
+ % Only one input parameter. It can be :
+ % - line angle
+ % - array of four parameters
+ % TODO : add control for arrays of lines.
+ var = varargin{1};
+
+ if size(var, 2)==4
+ % 4 parameters of the line in a single array.
+ line = var;
+ elseif size(var, 2)==1
+ % 1 parameter : angle of the line, going through origin.
+ line = [zeros(size(var)) zeros(size(var)) cos(var) sin(var)];
+ else
+ error('wrong number of dimension for arg1 : can be 1 or 4');
+ end
+
+ elseif length(varargin)==2
+ % 2 input parameters. They can be :
+ % - line angle and signed distance to origin.
+ % - 2 points, then 2 arrays of 1*2 double.
+ v1 = varargin{1};
+ v2 = varargin{2};
+ if size(v1, 2)==1
+ % first param is angle of line, and second param is signed distance
+ % to origin.
+ line = [v1.*cos(v2) v1.*sin(v2) -sin(v2) cos(v2)];
+ else
+ % first input parameter is first point, and second input is the
+ % second point.
+ line = [v1(:,1), v1(:,2), v2(:,1)-v1(:,1), v2(:,2)-v1(:,2)];
+ end
+
+ elseif length(varargin)==3
+ % 3 input parameters :
+ % first one is a point belonging to the line,
+ % second and third ones are direction vector of the line (dx and dy).
+ p = varargin{1};
+ line = [p(:,1) p(:,2) varargin{2} varargin{3}];
+
+ elseif length(varargin)==4
+ % 4 input parameters :
+ % they are x0, y0 (point belongng to line) and dx, dy (direction vector
+ % of the line).
+ % All parameters should have the same size.
+ line = [varargin{1} varargin{2} varargin{3} varargin{4}];
+ else
+ error('Wrong number of arguments in ''createLine'' ');
+ end
+
+endfunction
+
+%!test
+%! p1 = [1 1];
+%! p2 = [2 3];
+%! lin = createLine(p1, p2);
+%! assert (p1, lin(1,1:2), 1e-6);
+%! assert (p2-p1, lin(1,3:4), 1e-6);
+
+%!test
+%! p1 = [1 1;1 1];
+%! p2 = [2 3;2 4];
+%! lin = createLine(p1, p2);
+%! assert (2, size(lin, 1));
+%! assert (p1, lin(:,1:2), 1e-6);
+%! assert (p2-p1, lin(:,3:4), 1e-6);
+
diff --git a/inst/geom2d/createLineReflection.m b/inst/geom2d/createLineReflection.m
new file mode 100644
index 0000000..13e7203
--- /dev/null
+++ b/inst/geom2d/createLineReflection.m
@@ -0,0 +1,68 @@
+%% Copyright (c) 2011, INRA
+%% 2009-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} {@var{T} = } function_name (@var{line})
+%% Create the the 3x3 matrix of a line reflection.
+%%
+%% Where @var{line} is given as [x0 y0 dx dy], return the affine tansform
+%% corresponding to the desired line reflection.
+%%
+%% @seealso{lines2d, transforms2d, transformPoint,
+%% createTranslation, createHomothecy, createScaling}
+%% @end deftypefn
+
+function trans = createLineReflection(line)
+
+ % extract line parameters
+ x0 = line(:,1);
+ y0 = line(:,2);
+ dx = line(:,3);
+ dy = line(:,4);
+
+ % normalisation coefficient of line direction vector
+ delta = dx*dx + dy*dy;
+
+ % compute coefficients of transform
+ m00 = (dx*dx - dy*dy)/delta;
+ m01 = 2*dx*dy/delta;
+ m02 = 2*dy*(dy*x0 - dx*y0)/delta;
+ m10 = 2*dx*dy/delta;
+ m11 = (dy*dy - dx*dx)/delta;
+ m12 = 2*dx*(dx*y0 - dy*x0)/delta;
+
+ % create transformation
+ trans = [m00 m01 m02; m10 m11 m12; 0 0 1];
+
+endfunction
+
diff --git a/inst/geom2d/createRay.m b/inst/geom2d/createRay.m
new file mode 100644
index 0000000..69846cf
--- /dev/null
+++ b/inst/geom2d/createRay.m
@@ -0,0 +1,104 @@
+%% 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} { @var{ray} = } createRay (@var{point}, @var{angle})
+%% @deftypefnx {Function File} { @var{ray} = } createRay (@var{x0},@var{y0}, @var{angle})
+%% @deftypefnx {Function File} { @var{ray} = } createRay (@var{p1}, @var{p2})
+%% Create a ray (half-line), from various inputs.
+%%
+%% A Ray is represented in a parametric form: [x0 y0 dx dy].
+%% x = x0 + t*dx
+%% y = y0 + t*dy;
+%% for all t>0.
+%%
+%% @var{point} is a Nx2 array giving the starting point of the ray, and @var{angle} is the
+%% orientation of the ray respect to the positive x-axis. The ray origin can be specified with 2 input arguments @var{x0},@var{y0}.
+%%
+%% If two points @var{p1}, @var{p2} are given, creates a ray starting from point @var{p1} and going in the direction of point
+%% @var{p2}.
+%%
+%% Example
+%% @example
+%% origin = [3 4];
+%% theta = pi/6;
+%% ray = createRay(origin, theta);
+%% axis([0 10 0 10]);
+%% drawRay(ray);
+%% @end example
+%%
+%% @seealso{rays2d, createLine, points2d}
+%% @end deftypefn
+
+function ray = createRay(varargin)
+
+ if length(varargin)==2
+ p0 = varargin{1};
+ arg = varargin{2};
+ if size(arg, 2)==1
+ % second input is the ray angle
+ ray = [p0 cos(arg) sin(arg)];
+ else
+ % second input is another point
+ ray = [p0 arg-p0];
+ end
+
+ elseif length(varargin)==3
+ x = varargin{1};
+ y = varargin{2};
+ theta = varargin{3};
+ ray = [x y cos(theta) sin(theta)];
+
+ else
+ error("Wrong number of arguments in 'createRay'. ");
+ end
+
+endfunction
+
+%!shared p1,p2,ray
+%! p1 = [1 1];
+%! p2 = [2 3];
+%! ray = createRay(p1, p2);
+
+%!assert (p1, ray(1,1:2), 1e-6);
+%!assert (p2-p1, ray(1,3:4), 1e-6);
+
+%!shared p1,p2,ray
+%! p1 = [1 1;1 1];
+%! p2 = [2 3;2 4];
+%! ray = createRay(p1, p2);
+
+%!assert (2, size(ray, 1));
+%!assert (p1, ray(:,1:2), 1e-6);
+%!assert (p2-p1, ray(:,3:4), 1e-6);
+
diff --git a/inst/geom2d/createRotation.m b/inst/geom2d/createRotation.m
new file mode 100644
index 0000000..f1d4d74
--- /dev/null
+++ b/inst/geom2d/createRotation.m
@@ -0,0 +1,112 @@
+%% Copyright (c) 2011, INRA
+%% 2004-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} {@var{T} = } createRotation (@var{theta})
+%% @deftypefnx {Function File} {@var{T} = } createRotation (@var{point}, @var{theta})
+%% @deftypefnx {Function File} {@var{T} = } createRotation (@var{x0}, @var{y0}, @var{theta})
+%% Create the 3*3 matrix of a rotation.
+%%
+%% Returns the rotation corresponding to angle @var{theta} (in radians)
+%% The returned matrix has the form :
+%% [cos(theta) -sin(theta) 0]
+%% [sin(theta) cos(theta) 0]
+%% [0 0 1]
+%%
+%% @var{point} or (@var{x0},@var{y0}), specifies origin of rotation. The result is similar as performing
+%% translation(-@var{x0},-@var{y0}), rotation(@var{theta}), and translation(@var{x0},@var{y0}).
+%%
+%%
+%% @seealso{transforms2d, transformPoint, createTranslation, createScaling}
+%% @end deftypefn
+
+function trans = createRotation(varargin)
+
+ % default values
+ cx = 0;
+ cy = 0;
+ theta = 0;
+
+ % get input values
+ if length(varargin)==1
+ % only angle
+ theta = varargin{1};
+ elseif length(varargin)==2
+ % origin point (as array) and angle
+ var = varargin{1};
+ cx = var(1);
+ cy = var(2);
+ theta = varargin{2};
+ elseif length(varargin)==3
+ % origin (x and y) and angle
+ cx = varargin{1};
+ cy = varargin{2};
+ theta = varargin{3};
+ end
+
+ % compute coefs
+ cot = cos(theta);
+ sit = sin(theta);
+ tx = cy*sit - cx*cot + cx;
+ ty = -cy*cot - cx*sit + cy;
+
+ % create transformation matrix
+ trans = [cot -sit tx; sit cot ty; 0 0 1];
+
+endfunction
+
+%!test
+%! trans = createRotation(0);
+%! assert (trans, [1 0 0;0 1 0;0 0 1], 1e-6);
+
+%!test
+%! trans = createRotation(pi/2);
+%! assert (trans, [0 -1 0; 1 0 0; 0 0 1], 1e-6);
+
+%!test
+%! trans = createRotation(pi);
+%! assert (trans, [-1 0 0;0 -1 0;0 0 1], 1e-6);
+
+%!test
+%! trans = createRotation(3*pi/2);
+%! assert (trans, [0 1 0; -1 0 0; 0 0 1], 1e-6);
+
+%!test
+%! p0 = [3 5];
+%! theta = pi/3;
+%! trans1 = createRotation(p0, theta);
+%! t1 = createTranslation(-p0);
+%! rot = createRotation(theta);
+%! t2 = createTranslation(p0);
+%! trans2 = t2*rot*t1;
+%! assert (trans1, trans2, 1e-6);
diff --git a/inst/geom2d/createScaling.m b/inst/geom2d/createScaling.m
new file mode 100644
index 0000000..a88cbaa
--- /dev/null
+++ b/inst/geom2d/createScaling.m
@@ -0,0 +1,106 @@
+%% Copyright (c) 2011, INRA
+%% 2004-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} {@var{T} = } createScaling (@var{s})
+%% @deftypefnx {Function File} {@var{T} = } createScaling (@var{sx}, @var{sy})
+%% Create the 3x3 matrix of a scaling in 2 dimensions.
+%
+% Assume scaling @var{s} is equal n all directions unless @var{sx} and @var{sy} are given.
+% Returns the matrix corresponding to scaling in the 2 main directions.
+% The returned matrix has the form:
+% [SX 0 0]
+% [0 SY 0]
+% [0 0 1]
+%
+% @seealso{transforms2d, transformPoint, createTranslation, createRotation}
+%% @end deftypefn
+
+function trans = createScaling(varargin)
+
+ % defined default arguments
+ sx = 1;
+ sy = 1;
+ cx = 0;
+ cy = 0;
+
+ % process input arguments
+ if length(varargin)==1
+ % the argument is either the scaling factor in both direction,
+ % or a 1x2 array containing scaling factor in each direction
+ var = varargin{1};
+ sx = var(1);
+ sy = var(1);
+ if length(var)>1
+ sy = var(2);
+ end
+ elseif length(varargin)==2
+ % the 2 arguments are the scaling factors in each dimension
+ sx = varargin{1};
+ sy = varargin{2};
+ elseif length(varargin)==3
+ % first argument is center, 2nd and 3d are scaling factors
+ center = varargin{1};
+ cx = center(1);
+ cy = center(2);
+ sx = varargin{2};
+ sy = varargin{3};
+ end
+
+ % create result matrix
+ trans = [sx 0 cx*(1-sx); 0 sy cy*(1-sy); 0 0 1];
+
+endfunction
+
+%!test
+%! trans = createScaling(2);
+%! assert (trans, [2 0 0;0 2 0;0 0 1], 1e-6);
+
+%!test
+%! trans = createScaling(2, 3);
+%! assert (trans, [2 0 0;0 3 0;0 0 1], 1e-6);
+
+%!test
+%! trans = createScaling([2 3]);
+%! assert (trans, [2 0 0;0 3 0;0 0 1], 1e-6);
+
+%!test
+%! sx = 2;
+%! sy = 3;
+%! p0 = [4 5];
+%! trans1 = createScaling(p0, sx, sy);
+%! t1 = createTranslation(-p0);
+%! sca = createScaling(sx, sy);
+%! t2 = createTranslation(p0);
+%! trans2 = t2*sca*t1;
+%! assert (trans1, trans2, 1e-6);
diff --git a/inst/geom2d/createTranslation.m b/inst/geom2d/createTranslation.m
new file mode 100644
index 0000000..73f708c
--- /dev/null
+++ b/inst/geom2d/createTranslation.m
@@ -0,0 +1,71 @@
+%% Copyright (c) 2011, INRA
+%% 2004-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} {@var{T} = } createTranslation (@var{vector})
+%% @deftypefnx {Function File} {@var{T} = } createTranslation (@var{dx},@var{dy})
+%% Create the 3*3 matrix of a translation.
+%%
+%% Returns the matrix corresponding to a translation by the vector [@var{dx} @var{dy}].
+%% The components can be given as two arguments.
+%% The returned matrix has the form :
+%% [1 0 TX]
+%% [0 1 TY]
+%% [0 0 1]
+%%
+%% @seealso{transforms2d, transformPoint, createRotation, createScaling}
+%% @end deftypefn
+
+function trans = createTranslation(varargin)
+
+ % process input arguments
+ if isempty(varargin)
+ tx = 0;
+ ty = 0;
+ elseif length(varargin)==1
+ var = varargin{1};
+ tx = var(1);
+ ty = var(2);
+ else
+ tx = varargin{1};
+ ty = varargin{2};
+ end
+
+ % create the matrix representing the translation
+ trans = [1 0 tx ; 0 1 ty ; 0 0 1];
+
+endfunction
+
+%!test
+%! trans = createTranslation(2, 3);
+%! assert (trans, [1 0 2;0 1 3;0 0 1], 1e-6);
diff --git a/inst/geom2d/createVector.m b/inst/geom2d/createVector.m
new file mode 100644
index 0000000..1c0110d
--- /dev/null
+++ b/inst/geom2d/createVector.m
@@ -0,0 +1,54 @@
+%% Copyright (c) 2011, INRA
+%% 2010-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} {@var{vect} = } createVector (@var{p1}, @var{p2})
+%% Create a vector from two points.
+%%
+%% V12 = createVector(P1, P2)
+%% Creates the vector V12, defined as the difference between coordinates
+%% of points P1 and P2.
+%% P1 and P2 are row vectors with ND elements, ND being the space
+%% dimension.
+%%
+%% If one of the inputs is a N-by-Nd array, the other input is
+%% automatically repeated, and the result is N-by-Nd.
+%%
+%% If both inputs have the same size, the result also have the same size.
+%%
+%% @seealso{vectors2d, vectors3d, points2d}
+%% @end deftypefn
+function vect = createVector(p1, p2)
+ vect = bsxfun(@minus, p2, p1);
+endfunction
+
diff --git a/inst/geom2d/deg2rad.m b/inst/geom2d/deg2rad.m
new file mode 100644
index 0000000..39e39a3
--- /dev/null
+++ b/inst/geom2d/deg2rad.m
@@ -0,0 +1,58 @@
+%% Copyright (c) 2011, INRA
+%% 2004-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} {@var{rad} =} deg2rad(@var{deg})
+%% Convert angle from degrees to radians
+%%
+%% Usage:
+%% R = deg2rad(D)
+%% convert an angle in degrees to an angle in radians.
+%%
+%% Example
+%% deg2rad(180) % gives pi
+%% ans =
+%% 3.1416
+%% deg2rad(60) % gives pi/3
+%% ans =
+%% 1.0472
+%%
+%% @seealso{angles2d, rad2deg}
+%% @end deftypefn
+
+function rad = deg2rad(deg)
+
+ rad = deg*pi/180;
+
+endfunction
+
diff --git a/inst/geom2d/distancePointEdge.m b/inst/geom2d/distancePointEdge.m
new file mode 100644
index 0000000..1a689db
--- /dev/null
+++ b/inst/geom2d/distancePointEdge.m
@@ -0,0 +1,85 @@
+%% 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} {@var{dist} = } distancePointEdge (@var{point}, @var{edge})
+%% Minimum distance between a point and an edge
+%%
+%% DIST = distancePointEdge(POINT, EDGE);
+%% Return the euclidean distance between edge EDGE and point POINT.
+%% EDGE has the form: [x1 y1 x2 y2], and POINT is [x y].
+%%
+%% If EDGE is N-by-4 array, result is N-by-1 array computed for each edge.
+%% If POINT is a N-by-2 array, the result is computed for each point.
+%% If both POINT and EDGE are array, they must have the same number of
+%% rows, and the result is computed for each couple point(i,:);edge(i,:).
+%%
+%% [DIST POS] = distancePointEdge(POINT, EDGE);
+%% Also returns the position of closest point on the edge. POS is
+%% comprised between 0 (first point) and 1 (last point).
+%%
+%% @seealso{edges2d, points2d, distancePoints, distancePointLine}
+%% @end deftypefn
+
+function varargout = distancePointEdge(point, edge)
+ % direction vector of each edge
+ dx = edge(:, 3) - edge(:,1);
+ dy = edge(:, 4) - edge(:,2);
+
+ % compute position of points projected on the supporting line
+ % (Size of tp is the max number of edges or points)
+ delta = dx .* dx + dy .* dy;
+ tp = ((point(:, 1) - edge(:, 1)) .* dx + (point(:, 2) - edge(:, 2)) .* dy) ./ delta;
+
+ % ensure degenerated edges are correclty processed (consider the first
+ % vertex is the closest)
+ tp(delta < eps) = 0;
+
+ % change position to ensure projected point is located on the edge
+ tp(tp < 0) = 0;
+ tp(tp > 1) = 1;
+
+ % coordinates of projected point
+ p0 = [edge(:,1) + tp .* dx, edge(:,2) + tp .* dy];
+
+ % compute distance between point and its projection on the edge
+ dist = sqrt((point(:,1) - p0(:,1)) .^ 2 + (point(:,2) - p0(:,2)) .^ 2);
+
+ % process output arguments
+ varargout{1} = dist;
+ if nargout > 1
+ varargout{2} = tp;
+ end
+
+endfunction
+
diff --git a/inst/geom2d/distancePointLine.m b/inst/geom2d/distancePointLine.m
new file mode 100644
index 0000000..b1cfb88
--- /dev/null
+++ b/inst/geom2d/distancePointLine.m
@@ -0,0 +1,77 @@
+%% Copyright (c) 2011, INRA
+%% 2004-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} {@var{dist} = } distancePointLine (@var{point}, @var{line})
+%% Minimum distance between a point and a line
+%%
+%% D = distancePointLine(POINT, LINE)
+%% Return the euclidean distance between line LINE and point POINT.
+%%
+%% LINE has the form : [x0 y0 dx dy], and POINT is [x y].
+%%
+%% If LINE is N-by-4 array, result is N-by-1 array computes for each line.
+%%
+%% If POINT is N-by-2, then result is computed for each point.
+%%
+%% If both POINT and LINE are array, result is N-by-1, computed for each
+%% corresponding point and line.
+%%
+%%
+%% @seealso{lines2d, points2d, distancePoints, distancePointEdge}
+%% @end deftypefn
+
+function dist = distancePointLine(point, line)
+
+ if size(line, 1)==1 && size(point, 1)>1
+ line = repmat(line, [size(point, 1) 1]);
+ end
+
+ if size(point, 1)==1 && size(line, 1)>1
+ point = repmat(point, [size(line, 1) 1]);
+ end
+
+ dx = line(:, 3);
+ dy = line(:, 4);
+
+ % compute position of points projected on line
+ tp = ((point(:, 2) - line(:, 2)).*dy + (point(:, 1) - line(:, 1)).*dx) ./ (dx.*dx+dy.*dy);
+ p0 = line(:, 1:2) + [tp tp].*[dx dy];
+
+
+ % compute distances between points and their projections
+ dx = point - p0;
+ dist = sqrt(sum(dx.*dx, 2));
+
+endfunction
+
diff --git a/inst/geom2d/distancePoints.m b/inst/geom2d/distancePoints.m
new file mode 100644
index 0000000..33777da
--- /dev/null
+++ b/inst/geom2d/distancePoints.m
@@ -0,0 +1,204 @@
+%% Copyright (c) 2011, INRA
+%% 2004-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} {@var{d} = } distancePoints (@var{p1}, @var{p2})
+%% @deftypefnx {Function File} {@var{d} = } distancePoints (@var{p1}, @var{p2}, @var{norm})
+%% @deftypefnx {Function File} {@var{d} = } distancePoints (@dots{}, 'diag')
+%% Compute distance between two points.
+%%
+%% Returns the Euclidean distance between points @var{p1} and @var{p2}.
+%% If @var{p1} and @var{p2} are two arrays of points, result is a N1xN2 array
+%% containing distance between each point of @var{p1} and each point of @var{p2}.
+%%
+%% Is @var{norm} is given, computes distance using the specified norm. @var{norm}=2 corresponds to usual
+%% euclidean distance, @var{norm}=1 corresponds to Manhattan distance, @var{norm}=inf
+%% is assumed to correspond to maximum difference in coordinate. Other
+%% values (>0) can be specified.
+%%
+%% When 'diag' is given, computes only distances between @var{p1}(i,:) and @var{p2}(i,:).
+%%
+%% @seealso{points2d, minDistancePoints}
+%% @end deftypefn
+
+function dist = distancePoints(p1, p2, varargin)
+
+ %% Setup options
+
+ % default values
+ diag = false;
+ norm = 2;
+
+ % check first argument: norm or diag
+ if ~isempty(varargin)
+ var = varargin{1};
+ if isnumeric(var)
+ norm = var;
+ elseif strncmp('diag', var, 4)
+ diag = true;
+ end
+ varargin(1) = [];
+ end
+
+ % check last argument: diag
+ if ~isempty(varargin)
+ var = varargin{1};
+ if strncmp('diag', var, 4)
+ diag = true;
+ end
+ end
+
+
+ % number of points in each array and their dimension
+ n1 = size(p1, 1);
+ n2 = size(p2, 1);
+ d = size(p1, 2);
+
+ if diag
+ % compute distance only for apparied couples of pixels
+ dist = zeros(n1, 1);
+ if norm==2
+ % Compute euclidian distance. this is the default case
+ % Compute difference of coordinate for each pair of point
+ % and for each dimension. -> dist is a [n1*n2] array.
+ for i=1:d
+ dist = dist + (p2(:,i)-p1(:,i)).^2;
+ end
+ dist = sqrt(dist);
+ elseif norm==inf
+ % infinite norm corresponds to maximal difference of coordinate
+ for i=1:d
+ dist = max(dist, abs(p2(:,i)-p1(:,i)));
+ end
+ else
+ % compute distance using the specified norm.
+ for i=1:d
+ dist = dist + power((abs(p2(:,i)-p1(:,i))), norm);
+ end
+ dist = power(dist, 1/norm);
+ end
+ else
+ % compute distance for all couples of pixels
+ dist = zeros(n1, n2);
+ if norm==2
+ % Compute euclidian distance. this is the default case
+ % Compute difference of coordinate for each pair of point
+ % and for each dimension. -> dist is a [n1*n2] array.
+ for i=1:d
+ % equivalent to:
+ % dist = dist + ...
+ % (repmat(p1(:,i), [1 n2])-repmat(p2(:,i)', [n1 1])).^2;
+ dist = dist + (p1(:, i*ones(1, n2))-p2(:, i*ones(n1, 1))').^2;
+ end
+ dist = sqrt(dist);
+ elseif norm==inf
+ % infinite norm corresponds to maximal difference of coordinate
+ for i=1:d
+ dist = max(dist, abs(p1(:, i*ones(1, n2))-p2(:, i*ones(n1, 1))'));
+ end
+ else
+ % compute distance using the specified norm.
+ for i=1:d
+ % equivalent to:
+ % dist = dist + power((abs(repmat(p1(:,i), [1 n2]) - ...
+ % repmat(p2(:,i)', [n1 1]))), norm);
+ dist = dist + power((abs(p1(:, i*ones(1, n2))-p2(:, i*ones(n1, 1))')), norm);
+ end
+ dist = power(dist, 1/norm);
+ end
+ end
+
+endfunction
+
+%!shared pt1,pt2,pt3,pt4
+%! pt1 = [10 10];
+%! pt2 = [10 20];
+%! pt3 = [20 20];
+%! pt4 = [20 10];
+
+%!assert (distancePoints(pt1, pt2), 10, 1e-6);
+%!assert (distancePoints(pt2, pt3), 10, 1e-6);
+%!assert (distancePoints(pt1, pt3), 10*sqrt(2), 1e-6);
+%!assert (distancePoints(pt1, pt2, 1), 10, 1e-6);
+%!assert (distancePoints(pt2, pt3, 1), 10, 1e-6);
+%!assert (distancePoints(pt1, pt3, 1), 20, 1e-6);
+%!assert (distancePoints(pt1, pt2, inf), 10, 1e-6);
+%!assert (distancePoints(pt2, pt3, inf), 10, 1e-6);
+%!assert (distancePoints(pt1, pt3, inf), 10, 1e-6);
+%!assert (distancePoints(pt1, [pt1; pt2; pt3]), [0 10 10*sqrt(2)], 1e-6);
+
+%!test
+%! array1 = [pt1;pt2;pt3];
+%! array2 = [pt1;pt2;pt3;pt4];
+%! res = [0 10 10*sqrt(2) 10; 10 0 10 10*sqrt(2); 10*sqrt(2) 10 0 10];
+%! assert (distancePoints(array1, array2), res, 1e-6);
+%! assert (distancePoints(array2, array2, 'diag'), [0;0;0;0], 1e-6);
+
+%!test
+%! array1 = [pt1;pt2;pt3];
+%! array2 = [pt2;pt3;pt1];
+%! assert (distancePoints(array1, array2, inf, 'diag'), [10;10;10], 1e-6);
+
+%!shared pt1,pt2,pt3,pt4
+%! pt1 = [10 10 10];
+%! pt2 = [10 20 10];
+%! pt3 = [20 20 10];
+%! pt4 = [20 20 20];
+
+%!assert (distancePoints(pt1, pt2), 10, 1e-6);
+%!assert (distancePoints(pt2, pt3), 10, 1e-6);
+%!assert (distancePoints(pt1, pt3), 10*sqrt(2), 1e-6);
+%!assert (distancePoints(pt1, pt4), 10*sqrt(3), 1e-6);
+%!assert (distancePoints(pt1, pt2, inf), 10, 1e-6);
+%!assert (distancePoints(pt2, pt3, inf), 10, 1e-6);
+%!assert (distancePoints(pt1, pt3, inf), 10, 1e-6);
+%!assert (distancePoints(pt1, pt4, inf), 10, 1e-6);
+
+
+%!shared pt1,pt2,pt3,pt4
+%! pt1 = [10 10 30];
+%! pt2 = [10 20 30];
+%! pt3 = [20 20 30];
+%! pt4 = [20 20 40];
+
+%!assert (distancePoints(pt1, pt2, 1), 10, 1e-6);
+%!assert (distancePoints(pt2, pt3, 1), 10, 1e-6);
+%!assert (distancePoints(pt1, pt3, 1), 20, 1e-6);
+%!assert (distancePoints(pt1, pt4, 1), 30, 1e-6);
+
+%!test
+%! array1 = [pt1;pt2;pt3];
+%! array2 = [pt2;pt3;pt1];
+%! assert (distancePoints(array1, array2, 'diag'), [10;10;10*sqrt(2)], 1e-6);
+%! assert (distancePoints(array1, array2, 1, 'diag'), [10;10;20], 1e-6);
+
diff --git a/inst/geom2d/drawArrow.m b/inst/geom2d/drawArrow.m
new file mode 100644
index 0000000..2108207
--- /dev/null
+++ b/inst/geom2d/drawArrow.m
@@ -0,0 +1,142 @@
+%% Copyright (c) 2011, INRA
+%% 2004-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} {@var{h} = } drawArrow (@var{x1}, @var{y1}, @var{x2}, @var{y2})
+%% @deftypefnx {Function File} {@var{h} = } drawArrow ([@var{ @var{x1}} @var{ @var{y1}} @var{x2} @var{y2}])
+%% @deftypefnx {Function File} {@var{h} = } drawArrow (@dots{}, @var{L}, @var{W})
+%% @deftypefnx {Function File} {@var{h} = } drawArrow (@dots{}, @var{L}, @var{W},@var{TYPE})
+%% Draw an arrow on the current axis.
+%%
+%% draw an arrow between the points (@var{x1} @var{y1}) and (@var{x2} @var{y2}).
+%% The points can be given as a single array. @var{L}, @var{W} specify length
+%% and width of the arrow.
+%%
+%% Also specify arrow type. @var{TYPE} can be one of the following :
+%% 0: draw only two strokes
+%% 1: fill a triangle
+%% .5: draw a half arrow (try it to see ...)
+%%
+%% Arguments can be single values or array of size [N*1]. In this case,
+%% the function draws multiple arrows.
+%%
+%% @end deftypefn
+
+function varargout = drawArrow(varargin)
+
+ if isempty(varargin)
+ error('should specify at least one argument');
+ end
+
+ % parse arrow coordinate
+ var = varargin{1};
+ if size(var, 2)==4
+ @var{x1} = var(:,1);
+ @var{y1} = var(:,2);
+ x2 = var(:,3);
+ y2 = var(:,4);
+ varargin = varargin(2:end);
+ elseif length(varargin)>3
+ @var{x1} = varargin{1};
+ @var{y1} = varargin{2};
+ x2 = varargin{3};
+ y2 = varargin{4};
+ varargin = varargin(5:end);
+ else
+ error('wrong number of arguments, please read the doc');
+ end
+
+ l = 10*size(size( @var{x1}));
+ w = 5*ones(size( @var{x1}));
+ h = zeros(size( @var{x1}));
+
+ % exctract length of arrow
+ if ~isempty(varargin)
+ l = varargin{1};
+ if length( @var{x1})>length(l)
+ l = l(1)*ones(size( @var{x1}));
+ end
+ end
+
+ % extract width of arrow
+ if length(varargin)>1
+ w = varargin{2};
+ if length( @var{x1})>length(w)
+ w = w(1)*ones(size( @var{x1}));
+ end
+ end
+
+ % extract 'ratio' of arrow
+ if length(varargin)>2
+ h = varargin{3};
+ if length( @var{x1})>length(h)
+ h = h(1)*ones(size( @var{x1}));
+ end
+ end
+
+ hold on;
+ axis equal;
+
+ % angle of the edge
+ theta = atan2(y2- @var{y1}, x2- @var{x1});
+
+ % point on the 'left'
+ xa1 = x2 - l.*cos(theta) - w.*sin(theta)/2;
+ ya1 = y2 - l.*sin(theta) + w.*cos(theta)/2;
+ % point on the 'right'
+ xa2 = x2 - l.*cos(theta) + w.*sin(theta)/2;
+ ya2 = y2 - l.*sin(theta) - w.*cos(theta)/2;
+ % point on the middle of the arrow
+ xa3 = x2 - l.*cos(theta).*h;
+ ya3 = y2 - l.*sin(theta).*h;
+
+ % draw main edge
+ line([ @var{x1}'; x2'], [ @var{y1}'; y2'], 'color', [0 0 1]);
+
+ % draw only 2 wings
+ ind = find(h==0);
+ line([xa1(ind)'; x2(ind)'], [ya1(ind)'; y2(ind)'], 'color', [0 0 1]);
+ line([xa2(ind)'; x2(ind)'], [ya2(ind)'; y2(ind)'], 'color', [0 0 1]);
+
+ % draw a full arrow
+ ind = find(h~=0);
+ patch([x2(ind) xa1(ind) xa3(ind) xa2(ind) x2(ind)]', ...
+ [y2(ind) ya1(ind) ya3(ind) ya2(ind) y2(ind)]', [0 0 1]);
+
+
+ if nargout>0
+ varargout{1}=h;
+ end
+
+endfunction
+
diff --git a/inst/geom2d/drawBezierCurve.m b/inst/geom2d/drawBezierCurve.m
new file mode 100644
index 0000000..59be90c
--- /dev/null
+++ b/inst/geom2d/drawBezierCurve.m
@@ -0,0 +1,107 @@
+%% 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} drawBezierCurve (@var{points})
+%% @deftypefnx {Command} {Function File} drawBezierCurve (@var{pp})
+%% @deftypefnx {Command} {Function File} drawBezierCurve (..., @var{param}, @var{value}, ...)
+%% @deftypefnx {Command} {Function File} {@var{h} =}drawBezierCurve (...)
+%% Draw a cubic bezier curve defined by the control points @var{points}.
+%%
+%% With only one input argument, draws the Bezier curve defined by the 4 control
+%% points stored in @var{points}. @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). The curve could be described by its
+%% polynomial (output of @code{cbezier2poly}) @var{pp}, which should be a 2-by-4
+%% array.
+%%
+%% The optional @var{param}, @var{value} pairs specify additional drawing
+%% parameters, see the @code{plot} function for details. The specific parameter
+%% 'discretization' with an integer associated value defines the amount of
+%% points used to plot the curve. If the output is requiered, the function
+%% returns the handle to the created graphic object.
+%%
+%% @seealso{cbezier2poly, plot}
+%% @end deftypefn
+
+function varargout = drawBezierCurve(points, varargin)
+
+ % default number of discretization steps
+ N = 64;
+
+ % check if discretization step is specified
+ if ~isempty(varargin)
+ [tf idx] = ismember ({'discretization'},{varargin{1:2:end}});
+ if ~isempty(idx)
+ N = varargin{idx+1};
+ varargin(idx:idx+1) = [];
+ end
+ end
+
+ % parametrization variable for bezier (use N+1 points to have N edges)
+ t = linspace(0, 1, N+1);
+
+ if any(size(points) ~= [2 4])
+ [x y] = cbezier2poly(points,t);
+ else
+ % Got a polynomial description
+ x = polyval(points(1,:),t);
+ y = polyval(points(2,:),t);
+ end
+
+ % draw the curve
+ h = plot(x, y, varargin{:});
+
+ % eventually return a handle to the created object
+ if nargout > 0
+ varargout = {h};
+ end
+endfunction
+
+%!demo
+%! points = [0 0; 3 1; -2 1; 1 0];
+%! drawBezierCurve(points);
+%! hold on
+%! plot(points([1 4],1),points([1 4],2),'go');
+%! plot(points([2 3],1),points([2 3],2),'rs');
+%! line(points([1 2],1),points([1 2],2),'color','k');
+%! line(points([3 4],1),points([3 4],2),'color','k');
+%! h = drawBezierCurve(points, 'discretization', 6, 'color','r');
+%! hold off
+
+%!shared p
+%! p = [0 0; 3 1; -2 1; 1 0];
+%!error(drawBezier())
+%!error(drawBezier ('discretization'))
+%!error(drawBezier (p, 'discretization', 'a'))
+%!error(drawBezier (p(:)))
diff --git a/inst/geom2d/drawBox.m b/inst/geom2d/drawBox.m
new file mode 100644
index 0000000..b3bd6f8
--- /dev/null
+++ b/inst/geom2d/drawBox.m
@@ -0,0 +1,81 @@
+%% Copyright (c) 2011, INRA
+%% 2003-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} {@var{h} =} drawBox (@var{box})
+%% @deftypefnx {Function File} {@var{h} =} drawBox (@var{box}, @var{param}, @var{value}, ...)
+%% Draw a box defined by coordinate extents
+%%
+%% Draws a box defined by its extent: @var{box} = [@var{xmin} @var{xmax}
+%% @var{ymin} @var{ymax}]. Addtional
+%% arguments are passed to function @code{plot}. If requested, it returns the
+%% handle to the graphics object created.
+%%
+%% @seealso{drawOrientedBox, drawRect, plot}
+%% @end deftypefn
+
+function varargout = drawBox(box, varargin)
+
+ % default values
+ xmin = box(:,1);
+ xmax = box(:,2);
+ ymin = box(:,3);
+ ymax = box(:,4);
+
+ nBoxes = size(box, 1);
+ r = zeros(nBoxes, 1);
+
+ % iterate on boxes
+ for i = 1:nBoxes
+ % exract min and max values
+ tx(1) = xmin(i);
+ ty(1) = ymin(i);
+ tx(2) = xmax(i);
+ ty(2) = ymin(i);
+ tx(3) = xmax(i);
+ ty(3) = ymax(i);
+ tx(4) = xmin(i);
+ ty(4) = ymax(i);
+ tx(5) = xmin(i);
+ ty(5) = ymin(i);
+
+ % display polygon
+ r(i) = plot(tx, ty, varargin{:});
+ end
+
+ % format output
+ if nargout > 0
+ varargout = {r};
+ end
+
+endfunction
diff --git a/inst/geom2d/drawCenteredEdge.m b/inst/geom2d/drawCenteredEdge.m
new file mode 100644
index 0000000..f6ee571
--- /dev/null
+++ b/inst/geom2d/drawCenteredEdge.m
@@ -0,0 +1,152 @@
+%% Copyright (c) 2011, INRA
+%% 2005-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} {@var{h} =} drawCenteredEdge (@var{center}, @var{L}, @var{theta})
+%% @deftypefnx {Function File} {@var{h} =} drawCenteredEdge (@var{edge})
+%% @deftypefnx {Function File} {@var{h} =} drawCenteredEdge (@dots{}, @var{name},@var{value})
+%% Draw an edge centered on a point.
+%%
+%% drawCenteredEdge(CENTER, L, THETA)
+%% Draws an edge centered on point CENTER, with length L, and orientation
+%% THETA (given in degrees). Input arguments can also be arrays, that must
+%% all have the same number odf rows.
+%%
+%% drawCenteredEdge(EDGE)
+%% Concatenates edge parameters into a single N-by-4 array, containing:
+%% [XC YV L THETA].
+%%
+%% drawCenteredEdge(..., NAME, VALUE)
+%% Also specifies drawing options by using one or several parameter name -
+%% value pairs (see doc of plot function for details).
+%%
+%% H = drawCenteredEdge(...)
+%% Returns handle(s) to the created edges(s).
+%%
+%% @example
+%% % Draw an ellipse with its two axes
+%% figure(1); clf;
+%% center = [50 40];
+%% r1 = 30; r2 = 10;
+%% theta = 20;
+%% elli = [center r1 r2 theta];
+%% drawEllipse(elli, 'linewidth', 2);
+%% axis([0 100 0 100]); axis equal;
+%% hold on;
+%% edges = [center 2*r1 theta ; center 2*r2 theta+90];
+%% drawCenteredEdge(edges, 'linewidth', 2, 'color', 'g');
+%% @end example
+%%
+%% @seealso{edges2d, drawEdge}
+%% @end deftypefn
+
+function varargout = drawCenteredEdge(center, len, theta, varargin)
+
+ %% process input variables
+
+ if size(center, 2) == 4
+ % manage edge in single parameter
+
+ varargin = [{len, theta}, varargin];
+
+ len = center(:, 3);
+ theta = center(:, 4);
+ center = center(:, 1:2);
+
+ N = size(center, 1);
+
+ else
+ % parameters given in different arguments
+
+ % size of data
+ NP = size(center, 1);
+ NL = size(len, 1);
+ ND = size(theta, 1);
+ N = max([NP NL ND]);
+
+ % ensure all data have same size
+ if N > 1
+ if NP == 1, center = repmat(center, [N 1]); end
+ if NL == 1, len = repmat(len, [N 1]); end
+ if ND == 1, theta = repmat(theta, [N 1]); end
+ end
+
+ end
+
+ % extract drawing options
+ options = varargin(:);
+
+
+ %% Draw edges
+
+ % coordinates of center point
+ xc = center(:, 1);
+ yc = center(:, 2);
+
+ % convert angle to radians
+ theta = theta * pi / 180;
+
+ % computation shortcuts
+ cot = cos(theta);
+ sit = sin(theta);
+
+ % compute starting and ending points
+ x1 = xc - len .* cot / 2;
+ x2 = xc + len .* cot / 2;
+ y1 = yc - len .* sit / 2;
+ y2 = yc + len .* sit / 2;
+
+
+ % draw the edges
+ h = zeros(N, 1);
+ for i = 1:N
+ h(i) = plot([x1(i) x2(i)], [y1(i) y2(i)]);
+ end
+
+ % apply style to edges
+ if ~isempty(options) > 0
+ for i = 1:N
+ set(h(i), options{:});
+ end
+ end
+
+
+ %% Format output
+
+ % process output arguments
+ if nargout > 0
+ varargout = {h};
+ end
+
+endfunction
+
diff --git a/inst/geom2d/drawCircle.m b/inst/geom2d/drawCircle.m
new file mode 100644
index 0000000..a683dd0
--- /dev/null
+++ b/inst/geom2d/drawCircle.m
@@ -0,0 +1,132 @@
+%% Copyright (c) 2011, INRA
+%% 2003-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} {@var{h} = } drawCircle (@var{x0}, @var{y0}, @var{r})
+%% @deftypefnx {Function File} {@var{h} = } drawCircle (@var{circle})
+%% @deftypefnx {Function File} {@var{h} = } drawCircle (@var{center}, @var{radius})
+%% @deftypefnx {Function File} {@var{h} = } drawCircle (@dots{}, @var{nstep})
+%% @deftypefnx {Function File} {@var{h} = } drawCircle (@dots{}, @var{name}, @var{value})
+%% Draw a circle on the current axis
+%%
+%% drawCircle(X0, Y0, R);
+%% Draw the circle with center (X0,Y0) and the radius R. If X0, Y0 and R
+%% are column vectors of the same length, draw each circle successively.
+%%
+%% drawCircle(CIRCLE);
+%% Concatenate all parameters in a Nx3 array, where N is the number of
+%% circles to draw.
+%%
+%% drawCircle(CENTER, RADIUS);
+%% Specify CENTER as Nx2 array, and radius as a Nx1 array.
+%%
+%% drawCircle(..., NSTEP);
+%% Specify the number of edges that will be used to draw the circle.
+%% Default value is 72, creating an approximation of one point for each 5
+%% degrees.
+%%
+%% drawCircle(..., NAME, VALUE);
+%% Specifies plotting options as pair of parameters name/value. See plot
+%% documentation for details.
+%%
+%%
+%% H = drawCircle(...);
+%% return handles to each created curve.
+%%
+%% @seealso{circles2d, drawCircleArc, drawEllipse}
+%% @end deftypefn
+
+function varargout = drawCircle(varargin)
+
+ % process input parameters
+ var = varargin{1};
+ if size(var, 2) == 1
+ x0 = varargin{1};
+ y0 = varargin{2};
+ r = varargin{3};
+ varargin(1:3) = [];
+
+ elseif size(var, 2) == 2
+ x0 = var(:,1);
+ y0 = var(:,2);
+ r = varargin{2};
+ varargin(1:2) = [];
+
+ elseif size(var, 2) == 3
+ x0 = var(:,1);
+ y0 = var(:,2);
+ r = var(:,3);
+ varargin(1) = [];
+ else
+ error('bad format for input in drawCircle');
+ end
+
+ % ensure each parameter is column vector
+ x0 = x0(:);
+ y0 = y0(:);
+ r = r(:);
+
+ % default number of discretization steps
+ N = 72;
+
+ % check if discretization step is specified
+ if ~isempty(varargin)
+ var = varargin{1};
+ if length(var)==1 && isnumeric(var)
+ N = round(var);
+ varargin(1) = [];
+ end
+ end
+
+ % parametrization variable for circle (use N+1 as first point counts twice)
+ t = linspace(0, 2*pi, N+1);
+ cot = cos(t);
+ sit = sin(t);
+
+ % empty array for graphic handles
+ h = zeros(size(x0));
+
+ % compute discretization of each circle
+ for i = 1:length(x0)
+ xt = x0(i) + r(i) * cot;
+ yt = y0(i) + r(i) * sit;
+
+ h(i) = plot(xt, yt, varargin{:});
+ end
+
+ if nargout > 0
+ varargout = {h};
+ end
+
+endfunction
+
diff --git a/inst/geom2d/drawCircleArc.m b/inst/geom2d/drawCircleArc.m
new file mode 100644
index 0000000..fe5db04
--- /dev/null
+++ b/inst/geom2d/drawCircleArc.m
@@ -0,0 +1,123 @@
+%% Copyright (c) 2011, INRA
+%% 2003-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} {@var{h} = } drawCircleArc (@var{xc}, @var{yc}, @var{r}, @var{start}, @var{end})
+%% @deftypefnx {Function File} {@var{h} = } drawCircleArc (@var{arc})
+%% @deftypefnx {Function File} {@var{h} = } drawCircleArc (@dots{}, @var{param}, @var{value})
+%% Draw a circle arc on the current axis
+%%
+%% drawCircleArc(XC, YC, R, START, EXTENT);
+%% Draws circle with center (XC, YC), with radius R, starting from angle
+%% START, and with angular extent given by EXTENT. START and EXTENT angles
+%% are given in degrees.
+%%
+%% drawCircleArc(ARC);
+%% Puts all parameters into one single array.
+%%
+%% drawCircleArc(..., PARAM, VALUE);
+%% specifies plot properties by using one or several parameter name-value
+%% pairs.
+%%
+%% H = drawCircleArc(...);
+%% Returns a handle to the created line object.
+%%
+%% @example
+%% % Draw a red thick circle arc
+%% arc = [10 20 30 -120 240];
+%% figure;
+%% axis([-50 100 -50 100]);
+%% hold on
+%% drawCircleArc(arc, 'LineWidth', 3, 'Color', 'r')
+%% @end example
+%%
+%% @seealso{circles2d, drawCircle, drawEllipse}
+%% @end deftypefn
+
+function varargout = drawCircleArc(varargin)
+
+ if nargin == 0
+ error('Need to specify circle arc');
+ end
+
+ circle = varargin{1};
+ if size(circle, 2) == 5
+ x0 = circle(:,1);
+ y0 = circle(:,2);
+ r = circle(:,3);
+ start = circle(:,4);
+ extent = circle(:,5);
+ varargin(1) = [];
+
+ elseif length(varargin) >= 5
+ x0 = varargin{1};
+ y0 = varargin{2};
+ r = varargin{3};
+ start = varargin{4};
+ extent = varargin{5};
+ varargin(1:5) = [];
+
+ else
+ error('drawCircleArc: please specify center, radius and angles of circle arc');
+ end
+
+ % convert angles in radians
+ t0 = deg2rad(start);
+ t1 = t0 + deg2rad(extent);
+
+ % number of line segments
+ N = 60;
+
+ % initialize handles vector
+ h = zeros(length(x0), 1);
+
+ % draw each circle arc individually
+ for i = 1:length(x0)
+ % compute basis
+ t = linspace(t0(i), t1(i), N+1)';
+
+ % compute vertices coordinates
+ xt = x0(i) + r(i)*cos(t);
+ yt = y0(i) + r(i)*sin(t);
+
+ % draw the circle arc
+ h(i) = plot(xt, yt, varargin{:});
+ end
+
+ if nargout > 0
+ varargout = {h};
+ end
+
+
+endfunction
+
diff --git a/inst/geom2d/drawEdge.m b/inst/geom2d/drawEdge.m
new file mode 100644
index 0000000..1be7de2
--- /dev/null
+++ b/inst/geom2d/drawEdge.m
@@ -0,0 +1,164 @@
+%% Copyright (c) 2011, INRA
+%% 2004-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} {@var{h} = } drawEdge (@var{x1}, @var{y1}, @var{x2}, @var{y2})
+%% @deftypefnx {Function File} {@var{h} = } drawEdge ([@var{x1} @var{y1} @var{x2} @var{y2}])
+%% @deftypefnx {Function File} {@var{h} = } drawEdge ([@var{x1} @var{y1}], [@var{x2} @var{y2}])
+%% @deftypefnx {Function File} {@var{h} = } drawEdge (@var{x1}, @var{y1}, @var{z1}, @var{x2}, @var{y2}, @var{z2})
+%% @deftypefnx {Function File} {@var{h} = } drawEdge ([@var{x1} @var{y1} @var{z1} @var{x2} @var{y2} @var{z2}])
+%% @deftypefnx {Function File} {@var{h} = } drawEdge ([@var{x1} @var{y1} @var{z1}], [@var{x2} @var{y2} @var{z2}])
+%% @deftypefnx {Function File} {@var{h} = } drawEdge (@dots{}, @var{opt})
+%% Draw an edge given by 2 points.
+%%
+%% Draw an edge between the points (x1 y1) and (x2 y2). Data can be bundled as an edge.
+%% The function supports 3D edges.
+%% Arguments can be single values or array of size [Nx1]. In this case,
+%% the function draws multiple edges.
+%% @var{opt}, being a set of pairwise options, can
+%% specify color, line width and so on. These are passed to function @code{line}.
+%% The function returns handle(s) to created edges(s).
+%%
+%% @seealso{edges2d, drawCenteredEdge, drawLine, line}
+%% @end deftypefn
+
+function varargout = drawEdge(varargin)
+
+ % separate edge and optional arguments
+ [edge options] = parseInputArguments(varargin{:});
+
+ % draw the edges
+ if size(edge, 2)==4
+ h = drawEdge_2d(edge, options);
+ else
+ h = drawEdge_3d(edge, options);
+ end
+
+ % eventually return handle to created edges
+ if nargout>0
+ varargout{1}=h;
+ end
+
+endfunction
+
+function h = drawEdge_2d(edge, options)
+
+ h = -1*ones(size(edge, 1), 1);
+
+ for i=1:size(edge, 1)
+ if isnan(edge(i,1))
+ continue;
+ end
+ h(i) = line(...
+ [edge(i, 1) edge(i, 3)], ...
+ [edge(i, 2) edge(i, 4)], options{:});
+ end
+
+endfunction
+
+function h = drawEdge_3d(edge, options)
+
+ h = -1*ones(size(edge, 1), 1);
+
+ for i=1:size(edge, 1)
+ if isnan(edge(i,1))
+ continue;
+ end
+ h(i) = line( ...
+ [edge(i, 1) edge(i, 4)], ...
+ [edge(i, 2) edge(i, 5)], ...
+ [edge(i, 3) edge(i, 6)], options{:});
+ end
+
+endfunction
+
+function [edge options] = parseInputArguments(varargin)
+
+ % default values for parameters
+ edge = [];
+
+ % find the number of arguments defining edges
+ nbVal=0;
+ for i=1:nargin
+ if isnumeric(varargin{i})
+ nbVal = nbVal+1;
+ else
+ % stop at the first non-numeric value
+ break;
+ end
+ end
+
+ % extract drawing options
+ options = varargin(nbVal+1:end);
+
+ % ensure drawing options have correct format
+ if length(options)==1
+ options = [{'color'}, options];
+ end
+
+ % extract edges characteristics
+ if nbVal==1
+ % all parameters in a single array
+ edge = varargin{1};
+
+ elseif nbVal==2
+ % parameters are two points, or two arrays of points, of size N*2.
+ p1 = varargin{1};
+ p2 = varargin{2};
+ edge = [p1 p2];
+
+ elseif nbVal==4
+ % parameters are 4 parameters of the edge : x1 y1 x2 and y2
+ edge = [varargin{1} varargin{2} varargin{3} varargin{4}];
+
+ elseif nbVal==6
+ % parameters are 6 parameters of the edge : x1 y1 z1 x2 y2 and z2
+ edge = [varargin{1} varargin{2} varargin{3} varargin{4} varargin{5} varargin{6}];
+ end
+
+endfunction
+
+%!demo
+%! close
+%! points = rand(4,4);
+%! colorstr = 'rgbm';
+%! for i=1:4
+%! drawEdge (points(i,:),'color',colorstr(i),'linewidth',2);
+%! end
+%! axis tight;
+
+%!demo
+%! close
+%! drawEdge (rand(10,4),'linewidth',2);
+%! axis tight;
+
diff --git a/inst/geom2d/drawEllipse.m b/inst/geom2d/drawEllipse.m
new file mode 100644
index 0000000..51dc0e5
--- /dev/null
+++ b/inst/geom2d/drawEllipse.m
@@ -0,0 +1,141 @@
+%% Copyright (c) 2011, INRA
+%% 2003-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} {@var{h} = } drawEllipse (@var{elli})
+%% @deftypefnx {Function File} {@var{h} = } drawEllipse (@var{xc}, @var{yc}, @var{ra}, @var{rb})
+%% @deftypefnx {Function File} {@var{h} = } drawEllipse (@var{xc}, @var{yc}, @var{ra}, @var{rb}, @var{theta})
+%% @deftypefnx {Function File} {@var{h} = } drawEllipse (@dots{}, @var{param}, @var{value})
+%% Draw an ellipse on the current axis.
+%%
+%% drawEllipse(ELLI);
+%% Draws the ellipse ELLI in the form [XC YC RA RB THETA], with center
+%% (XC, YC), with main axis of half-length RA and RB, and orientation
+%% THETA in degrees counted counter-clockwise.
+%% Puts all parameters into one single array.
+%%
+%% drawEllipse(XC, YC, RA, RB);
+%% drawEllipse(XC, YC, RA, RB, THETA);
+%% Specifies ellipse parameters as separate arguments (old syntax).
+%%
+%% drawEllipse(..., NAME, VALUE);
+%% Specifies drawing style of ellipse, see the help of plot function.
+%%
+%% H = drawEllipse(...);
+%% Also returns handles to the created line objects.
+%%
+%% -> Parameters can also be arrays. In this case, all arrays are supposed
+%% to have the same size.
+%%
+%% Example:
+%% @example
+%% % Draw an ellipse centered in [50 50], with semi major axis length of
+%% % 40, semi minor axis length of 20, and rotated by 30 degrees.
+%% figure(1); clf; hold on;
+%% drawEllipse([50 50 40 20 30]);
+%% axis equal;
+%% @end example
+%%
+%% @seealso{ellipses2d, drawCircle, drawEllipseArc, ellipseAsPolygon}
+%% @end deftypefn
+
+function varargout = drawEllipse(varargin)
+
+ % extract dawing style strings
+ styles = {};
+ for i = 1:length(varargin)
+ if ischar(varargin{i})
+ styles = varargin(i:end);
+ varargin(i:end) = [];
+ break;
+ end
+ end
+
+ % extract ellipse parameters
+ if length(varargin)==1
+ % ellipse is given in a single array
+ ellipse = varargin{1};
+ x0 = ellipse(:, 1);
+ y0 = ellipse(:, 2);
+ a = ellipse(:, 3);
+ b = ellipse(:, 4);
+ if length(ellipse)>4
+ theta = ellipse(:, 5);
+ else
+ theta = zeros(size(x0));
+ end
+
+ elseif length(varargin)>=4
+ % ellipse parameters given as separate arrays
+ x0 = varargin{1};
+ y0 = varargin{2};
+ a = varargin{3};
+ b = varargin{4};
+ if length(varargin)>4
+ theta = varargin{5};
+ else
+ theta = zeros(size(x0));
+ end
+
+ else
+ error('drawEllipse: incorrect input arguments');
+ end
+
+
+ %% Process drawing of a set of ellipses
+
+ % angular positions of vertices
+ t = linspace(0, 2*pi, 145);
+
+ % compute position of points to draw each ellipse
+ h = zeros(length(x0), 1);
+ for i = 1:length(x0)
+ % pre-compute rotation angles (given in degrees)
+ cot = cosd(theta(i));
+ sit = sind(theta(i));
+
+ % compute position of points used to draw current ellipse
+ xt = x0(i) + a(i) * cos(t) * cot - b(i) * sin(t) * sit;
+ yt = y0(i) + a(i) * cos(t) * sit + b(i) * sin(t) * cot;
+
+ % stores handle to graphic object
+ h(i) = plot(xt, yt, styles{:});
+ end
+
+ % return handles if required
+ if nargout > 0
+ varargout = {h};
+ end
+
+endfunction
+
diff --git a/inst/geom2d/drawEllipseArc.m b/inst/geom2d/drawEllipseArc.m
new file mode 100644
index 0000000..123600d
--- /dev/null
+++ b/inst/geom2d/drawEllipseArc.m
@@ -0,0 +1,161 @@
+%% Copyright (c) 2011, INRA
+%% 2003-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} {@var{h} = } drawEllipseArc (@var{arc})
+%% Draw an ellipse arc on the current axis.
+%%
+%% drawEllipseArc(ARC)
+%% draw ellipse arc specified by ARC. ARC has the format:
+%% ARC = [XC YC A B THETA T1 T2]
+%% or:
+%% ARC = [XC YC A B T1 T2] (isothetic ellipse)
+%% with center (XC, YC), main axis of half-length A, second axis of
+%% half-length B, and ellipse arc running from t1 to t2 (both in degrees,
+%% in Counter-Clockwise orientation).
+%%
+%% Parameters can also be arrays. In this case, all arrays are suposed to
+%% have the same size...
+%%
+%% @example
+%% % draw an ellipse arc: center = [10 20], radii = 50 and 30, theta = 45
+%% arc = [10 20 50 30 45 -90 270];
+%% figure;
+%% axis([-50 100 -50 100]); axis equal;
+%% hold on
+%% drawEllipseArc(arc, 'color', 'r')
+%%
+%% % draw another ellipse arc, between angles -60 and 70
+%% arc = [10 20 50 30 45 -60 (60+70)];
+%% figure;
+%% axis([-50 100 -50 100]); axis equal;
+%% hold on
+%% drawEllipseArc(arc, 'LineWidth', 2);
+%% ray1 = createRay([10 20], deg2rad(-60+45));
+%% drawRay(ray1)
+%% ray2 = createRay([10 20], deg2rad(70+45));
+%% drawRay(ray2)
+%% @end example
+%%
+%% @seealso{ellipses2d, drawEllipse, drawCircleArc}
+%% @end deftypefn
+
+function varargout = drawEllipseArc(varargin)
+
+ %% Extract input arguments
+
+ % extract dawing style strings
+ styles = {};
+ for i = 1:length(varargin)
+ if ischar(varargin{i})
+ styles = varargin(i:end);
+ varargin(i:end) = [];
+ break;
+ end
+ end
+
+ if length(varargin)==1
+ ellipse = varargin{1};
+ x0 = ellipse(1);
+ y0 = ellipse(2);
+ a = ellipse(3);
+ b = ellipse(4);
+ if size(ellipse, 2)>6
+ theta = ellipse(5);
+ start = ellipse(6);
+ extent = ellipse(7);
+ else
+ theta = zeros(size(x0));
+ start = ellipse(5);
+ extent = ellipse(6);
+ end
+
+ elseif length(varargin)>=6
+ x0 = varargin{1};
+ y0 = varargin{2};
+ a = varargin{3};
+ b = varargin{4};
+ if length(varargin)>6
+ theta = varargin{5};
+ start = varargin{6};
+ extent = varargin{7};
+ else
+ theta = zeros(size(x0));
+ start = varargin{5};
+ extent = varargin{6};
+ end
+
+ else
+ error('drawellipse: please specify center x, center y and radii a and b');
+ end
+
+
+ %% Drawing
+
+ % allocate memory for handles
+ h = zeros(size(x0));
+
+ for i = 1:length(x0)
+ % start and end angles
+ t1 = deg2rad(start);
+ t2 = t1 + deg2rad(extent);
+
+ % vertices of ellipse
+ t = linspace(t1, t2, 60);
+
+ % convert angles to ellipse parametrisation
+ sup = cos(t) > 0;
+ t(sup) = atan(a(i) / b(i) * tan(t(sup)));
+ t(~sup) = atan2(a(i) / b(i) * tan(2*pi - t(~sup)), -1);
+ t = mod(t, 2*pi);
+
+ % precompute cos and sin of theta (given in degrees)
+ cot = cosd(theta(i));
+ sit = sind(theta(i));
+
+ % compute position of points
+ xt = x0(i) + a(i)*cos(t)*cot - b(i)*sin(t)*sit;
+ yt = y0(i) + a(i)*cos(t)*sit + b(i)*sin(t)*cot;
+
+ h(i) = plot(xt, yt, styles{:});
+ end
+
+
+ %% Process output arguments
+
+ if nargout > 0
+ varargout = {h};
+ end
+
+endfunction
+
diff --git a/inst/geom2d/drawLabels.m b/inst/geom2d/drawLabels.m
new file mode 100644
index 0000000..c762648
--- /dev/null
+++ b/inst/geom2d/drawLabels.m
@@ -0,0 +1,108 @@
+%% Copyright (c) 2011, INRA
+%% 2003-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} drawLabels (@var{x}, @var{y}, @var{lbl})
+%% @deftypefnx {Function File} drawLabels (@var{pos}, @var{lbl})
+%% @deftypefnx {Function File} drawLabels (@dots{}, @var{numbers}, @var{format})
+%% Draw labels at specified positions.
+%%
+%% DRAWLABELS(X, Y, LBL) draw labels LBL at position X and Y.
+%% LBL can be either a string array, or a number array. In this case,
+%% string are created by using sprintf function, with '%.2f' mask.
+%%
+%% DRAWLABELS(POS, LBL) draw labels LBL at position specified by POS,
+%% where POS is a N*2 int array.
+%%
+%% DRAWLABELS(..., NUMBERS, FORMAT) create labels using sprintf function,
+%% with the mask given by FORMAT (e. g. '%03d' or '5.3f'), and the
+%% corresponding values.
+%% @end deftypefn
+
+function varargout = drawLabels(varargin)
+
+ % check if enough inputs are given
+ if isempty(varargin)
+ error('wrong number of arguments in drawLabels');
+ end
+
+ % process input parameters
+ var = varargin{1};
+ if size(var, 2)==1
+ if length(varargin)<3
+ error('wrong number of arguments in drawLabels');
+ end
+ px = var;
+ py = varargin{2};
+ lbl = varargin{3};
+ varargin(1:3) = [];
+ else
+ if length(varargin)<2
+ error('wrong number of arguments in drawLabels');
+ end
+ px = var(:,1);
+ py = var(:,2);
+ lbl = varargin{2};
+ varargin(1:2) = [];
+ end
+
+ format = '%.2f';
+ if ~isempty(varargin)
+ format = varargin{1};
+ end
+ if size(format, 1)==1 && size(px, 1)>1
+ format = repmat(format, size(px, 1), 1);
+ end
+
+ labels = cell(length(px), 1);
+ if isnumeric(lbl)
+ for i=1:length(px)
+ labels{i} = sprintf(format(i,:), lbl(i));
+ end
+ elseif ischar(lbl)
+ for i=1:length(px)
+ labels{i} = lbl(i,:);
+ end
+ elseif iscell(lbl)
+ labels = lbl;
+ end
+ labels = char(labels);
+
+ h = text(px, py, labels);
+
+ if nargout>0
+ varargout{1}=h;
+ end
+
+endfunction
+
diff --git a/inst/geom2d/drawLine.m b/inst/geom2d/drawLine.m
new file mode 100644
index 0000000..c58eb89
--- /dev/null
+++ b/inst/geom2d/drawLine.m
@@ -0,0 +1,194 @@
+%% Copyright (c) 2011, INRA
+%% 2004-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} {@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
+%% contained in the axis, the function returns -1.
+%%
+%% Example
+%%
+%% @example
+%% figure; hold on; axis equal;
+%% axis([0 100 0 100]);
+%% drawLine([30 40 10 20]);
+%% drawLine([30 40 20 -10], 'color', 'm', 'linewidth', 2);
+%% @end example
+%%
+%% @seealso{lines2d, createLine, drawEdge}
+%% @end deftypefn
+
+function varargout = drawLine(lin, varargin)
+
+ % default style for drawing lines
+ varargin = [{'color', 'b'}, varargin];
+
+ % extract bounding box of the current axis
+ xlim = get(gca, 'xlim');
+ ylim = get(gca, 'ylim');
+
+ % clip lines with current axis box
+ clip = clipLine(lin, [xlim ylim]);
+ ok = isfinite(clip(:,1));
+
+ % initialize result array to invalide handles
+ h = -1*ones(size(lin, 1), 1);
+
+ % draw valid lines
+ h(ok) = line(clip(ok, [1 3])', clip(ok, [2 4])', varargin{:});
+
+ % return line handle if needed
+ if nargout>0
+ varargout{1}=h;
+ end
+
+endfunction
+
+%!demo
+%! figure; hold on; axis equal;
+%! axis([0 100 0 100]);
+%! 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));
diff --git a/inst/geom2d/drawOrientedBox.m b/inst/geom2d/drawOrientedBox.m
new file mode 100644
index 0000000..85a17a7
--- /dev/null
+++ b/inst/geom2d/drawOrientedBox.m
@@ -0,0 +1,113 @@
+%% Copyright (c) 2011, INRA
+%% 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} {@var{hb} = } drawOrientedBox (@var{box})
+%% @deftypefnx {Function File} {@var{hb} = } drawOrientedBox (@dots{}, @var{param}, @var{value})
+%% Draw centered oriented rectangle.
+%%
+%% Syntax
+%% drawOrientedBox(BOX)
+%% drawOrientedBox(BOX, 'PropertyName', propertyvalue, ...)
+%%
+%% Description
+%% drawOrientedBox(OBOX)
+%% Draws an oriented rectangle (or bounding box) on the current axis.
+%% OBOX is a 1-by-5 row vector containing box center, dimension (length
+%% and width) and orientation (in degrees):
+%% OBOX = [CX CY LENGTH WIDTH THETA].
+%%
+%% When OBOX is a N-by-5 array, the N boxes are drawn.
+%%
+%% HB = drawOrientedBox(...)
+%% Returns a handle to the created graphic object(s). Object style can be
+%% modified using syntaw like:
+%% set(HB, 'color', 'g', 'linewidth', 2);
+%%
+%% @seealso{drawPolygon, drawRect, drawBox}
+%% @end deftypefn
+
+function varargout = drawOrientedBox(box, varargin)
+
+ %% Parses input arguments
+
+ if nargin > 4 && sum(cellfun(@isnumeric, varargin(1:4))) == 4
+ cx = box;
+ cy = varargin{1};
+ hl = varargin{2} / 2;
+ hw = varargin{3} / 2;
+ theta = varargin{4};
+ varargin = varargin(5:end);
+ else
+ cx = box(:,1);
+ cy = box(:,2);
+ hl = box(:,3) / 2;
+ hw = box(:,4) / 2;
+ theta = box(:,5);
+ end
+
+
+ %% Draw each box
+
+ % allocate memory for graphical handle
+ hr = zeros(length(cx), 1);
+
+ % iterate on oriented boxes
+ for i = 1:length(cx)
+ % pre-compute angle data
+ cot = cosd(theta(i));
+ sit = sind(theta(i));
+
+ % x and y shifts
+ lc = hl(i) * cot;
+ ls = hl(i) * sit;
+ wc = hw(i) * cot;
+ ws = hw(i) * sit;
+
+ % coordinates of box vertices
+ vx = cx(i) + [-lc + ws; lc + ws ; lc - ws ; -lc - ws ; -lc + ws];
+ vy = cy(i) + [-ls - wc; ls - wc ; ls + wc ; -ls + wc ; -ls - wc];
+
+ % draw polygons
+ hr(i) = line(vx, vy, varargin{:});
+ end
+
+
+ %% Format output
+
+ if nargout > 0
+ varargout = {hr};
+ end
+
+endfunction
+
diff --git a/inst/geom2d/drawParabola.m b/inst/geom2d/drawParabola.m
new file mode 100644
index 0000000..004a3f2
--- /dev/null
+++ b/inst/geom2d/drawParabola.m
@@ -0,0 +1,142 @@
+%% Copyright (c) 2011, INRA
+%% 2006-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} {@var{h} = } drawParabola (@var{parabola})
+%% @deftypefnx {Function File} {@var{h} = } drawParabola (@var{parabola}, @var{t})
+%% @deftypefnx {Function File} {@var{h} = } drawParabola (@dots{}, @var{param}, @var{value})
+%% Draw a parabola on the current axis.
+%%
+%% drawParabola(PARABOLA);
+%% Draws a vertical parabola, defined by its vertex and its parameter.
+%% Such a parabola admits a vertical axis of symetry.
+%%
+%% The algebraic equation of parabola is given by:
+%% (Y - YV) = A * (X - VX)^2
+%% Where XV and YV are vertex coordinates and A is parabola parameter.
+%%
+%% A parametric equation of parabola is given by:
+%% x(t) = t + VX;
+%% y(t) = A * t^2 + VY;
+%%
+%% PARABOLA can also be defined by [XV YV A THETA], with theta being the
+%% angle of rotation of the parabola (in degrees and Counter-Clockwise).
+%%
+%% drawParabola(PARABOLA, T);
+%% Specifies which range of 't' are used for drawing parabola. If T is an
+%% array with only two values, the first and the last values are used as
+%% interval bounds, and several values are distributed within this
+%% interval.
+%%
+%% drawParabola(..., NAME, VALUE);
+%% Can specify one or several graphical options using parameter name-value
+%% pairs.
+%%
+%% H = drawParabola(...);
+%% Returns an handle to the created graphical object.
+%%
+%%
+%% Example:
+%% @example
+%% figure(1); clf; hold on;
+%% drawParabola([50 50 .2 30]);
+%% drawParabola([50 50 .2 30], [-1 1], 'color', 'r', 'linewidth', 2);
+%% axis equal;
+%% @end example
+%%
+%% @seealso{drawCircle, drawEllipse}
+%% @end deftypefn
+
+function varargout = drawParabola(varargin)
+
+ % Extract parabola
+ if nargin<1
+ error('geom2d:IllegalArgument', ...
+ 'Please specify parabola representation');
+ end
+
+ % input parabola is given as a packed array
+ parabola = varargin{1};
+ varargin(1) = [];
+ x0 = parabola(:,1);
+ y0 = parabola(:,2);
+ a = parabola(:,3);
+
+ if size(parabola, 2)>3
+ theta = parabola(:, 4);
+ else
+ theta = zeros(length(a), 1);
+ end
+
+ % extract parametrisation bounds
+ bounds = [-100 100];
+ if ~isempty(varargin)
+ var = varargin{1};
+ if isnumeric(var)
+ bounds = var;
+ varargin(1) = [];
+ end
+ end
+
+ % create parametrisation
+ if length(bounds)>2
+ t = bounds;
+ else
+ t = linspace(bounds(1), bounds(end), 100);
+ end
+
+ % create handle array (in the case of several parabola)
+ h = zeros(size(x0));
+
+ % draw each parabola
+ for i=1:length(x0)
+ % compute transformation
+ trans = ...
+ createTranslation(x0(i), y0(i)) * ...
+ createRotation(deg2rad(theta(i))) * ...
+ createScaling(1, a);
+
+ % compute points on the parabola
+ [xt yt] = transformPoint(t(:), t(:).^2, trans);
+
+ % draw it
+ h(i) = plot(xt, yt, varargin{:});
+ end
+
+ % process output arguments
+ if nargout>0
+ varargout{1}=h;
+ end
+
+endfunction
+
diff --git a/inst/geom2d/drawPoint.m b/inst/geom2d/drawPoint.m
new file mode 100644
index 0000000..7b5e503
--- /dev/null
+++ b/inst/geom2d/drawPoint.m
@@ -0,0 +1,91 @@
+%% Copyright (c) 2011, INRA
+%% 2004-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} {@var{h} = } drawPoint (@var{x}, @var{y})
+%% @deftypefnx {Function File} {@var{h} = } drawPoint (@var{coord})
+%% @deftypefnx {Function File} {@var{h} = } drawPoint (@dots{}, @var{opt})
+%% Draw the point on the axis.
+%
+% Draws points defined by coordinates @var{x} and @var{y}Y.
+% @var{x} and @var{y} should be array the same size. Coordinates can be
+% packed coordinates in a single [N*2] array @var{coord}. Options @var{opt}
+% are passed to the @code{plot} function.
+%
+% @seealso{points2d, clipPoints}
+%
+%% @end deftypefn
+
+function varargout = drawPoint(varargin)
+
+ % process input arguments
+ var = varargin{1};
+ if size(var, 2)==1
+ % points stored in separate arrays
+ px = varargin{1};
+ py = varargin{2};
+ varargin(1:2) = [];
+ else
+ % points packed in one array
+ px = var(:, 1);
+ py = var(:, 2);
+ varargin(1) = [];
+ end
+
+ % ensure we have column vectors
+ px = px(:);
+ py = py(:);
+
+ % default drawing options, but keep specified options if it has the form of
+ % a bundled string
+ if length(varargin)~=1
+ varargin = [{'linestyle', 'none', 'marker', 'o', 'color', 'b'}, varargin];
+ end
+
+ % plot the points, using specified drawing options
+ h = plot(px(:), py(:), varargin{:});
+
+ % process output arguments
+ if nargout>0
+ varargout{1}=h;
+ end
+
+endfunction
+
+%!demo
+%! drawPoint(10, 10);
+
+%!demo
+%! t = linspace(0, 2*pi, 20)';
+%! drawPoint([5*cos(t)+10 3*sin(t)+10], 'r+');
+
diff --git a/inst/geom2d/drawRay.m b/inst/geom2d/drawRay.m
new file mode 100644
index 0000000..a5a93ec
--- /dev/null
+++ b/inst/geom2d/drawRay.m
@@ -0,0 +1,66 @@
+%% Copyright (c) 2011, INRA
+%% 2003-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} {@var{h} = } drawRay (@var{ray})
+%% @deftypefnx {Function File} {@var{h} = } drawRay (@var{ray}, @var{param}, @var{value})
+%% Draw a ray on the current axis.
+%%
+%% With @var{ray} having the syntax: [x0 y0 dx dy], draws the ray starting from
+%% point (x0 y0) and going to direction (dx dy), clipped with the current
+%% window axis. @var{param}, @var{value} pairs are passed to function @code{line}.
+%%
+%% @seealso{rays2d, drawLine, line}
+%% @end deftypefn
+
+function varargout = drawRay(ray, varargin)
+
+ % get bounding box limits
+ bb = axis(gca);
+
+ % compute clipped shapes
+ [clipped isInside] = clipRay(ray, bb);
+
+ % allocate memory for handle
+ h = -ones(size(ray, 1), 1);
+
+ % draw visible rays
+ h(isInside) = drawEdge(clipped(isInside, :), varargin{:});
+
+ % process output
+ if nargout>0
+ varargout = {h};
+ end
+
+endfunction
+
diff --git a/inst/geom2d/drawRect.m b/inst/geom2d/drawRect.m
new file mode 100644
index 0000000..19f635e
--- /dev/null
+++ b/inst/geom2d/drawRect.m
@@ -0,0 +1,104 @@
+%% Copyright (c) 2011, INRA
+%% 2003-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} {@var{r} = } drawRect (@var{x}, @var{y}, @var{w}, @var{h})
+%% @deftypefnx {Function File} {@var{r} = } drawRect (@var{x}, @var{y}, @var{w}, @var{h}, @var{theta})
+%% @deftypefnx {Function File} {@var{r} = } drawRect (@var{coord})
+%% Draw rectangle on the current axis.
+%%
+%% r = DRAWRECT(x, y, w, h) draw rectangle with width W and height H, at
+%% position (X, Y).
+%% the four corners of rectangle are then :
+%% (X, Y), (X+W, Y), (X, Y+H), (X+W, Y+H).
+%%
+%% r = DRAWRECT(x, y, w, h, theta) also specifies orientation for
+%% rectangle. Theta is given in degrees.
+%%
+%% r = DRAWRECT(coord) is the same as DRAWRECT(X,Y,W,H), but all
+%% parameters are packed into one array, whose dimensions is 4*1 or 5*1.
+%%
+%%
+%% @seealso{drawBox, drawOrientedBox}
+%% @end deftypefn
+
+function varargout = drawRect(varargin)
+
+ % default values
+ theta = 0;
+
+ % get entered values
+ if length(varargin) > 3
+ x = varargin{1};
+ y = varargin{2};
+ w = varargin{3};
+ h = varargin{4};
+ if length(varargin)> 4
+ theta = varargin{5} * pi / 180;
+ end
+
+ else
+ coord = varargin{1};
+ x = coord(1);
+ y = coord(2);
+ w = coord(3);
+ h = coord(4);
+ if length(coord) > 4
+ theta = coord(5) * pi / 180;
+ end
+ end
+
+ r = zeros(size(x));
+ for i = 1:length(x)
+ tx = zeros(5, 1);
+ ty = zeros(5, 1);
+ tx(1) = x(i);
+ ty(1) = y(i);
+ tx(2) = x(i) + w(i) * cos(theta(i));
+ ty(2) = y(i) + w(i) * sin(theta(i));
+ tx(3) = x(i) + w(i) * cos(theta(i)) - h(i) * sin(theta(i));
+ ty(3) = y(i) + w(i) * sin(theta(i)) + h(i) * cos(theta(i));
+ tx(4) = x(i) - h(i) * sin(theta(i));
+ ty(4) = y(i) + h(i) * cos(theta(i));
+ tx(5) = x(i);
+ ty(5) = y(i);
+
+ r(i) = line(tx, ty);
+ end
+
+ if nargout > 0
+ varargout{1} = r;
+ end
+
+endfunction
+
diff --git a/inst/geom2d/drawShape.m b/inst/geom2d/drawShape.m
new file mode 100644
index 0000000..bed161a
--- /dev/null
+++ b/inst/geom2d/drawShape.m
@@ -0,0 +1,110 @@
+%% Copyright (c) 2011, INRA
+%% 2005-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} drawShape (@var{type}, @var{param})
+%% @deftypefnx {Function File} drawShape (@dots{}, @var{option})
+%% Draw various types of shapes (circles, polygons...).
+%%
+%% drawShape(TYPE, PARAM)
+%% Draw the shape of type TYPE, specified by given parameter PARAM. TYPE
+%% can be one of 'circle', 'ellipse', 'rect', 'polygon', 'curve'
+%% PARAM depend on the type. For example, if TYPE is 'circle', PARAM will
+%% contain [x0 y0 R].
+%%
+%% Examples :
+%% @example
+%% drawShape('circle', [20 10 30]);
+%% Draw circle centered on [20 10] with radius 10.
+%% drawShape('rect', [20 20 40 10 pi/3]);
+%% Draw rectangle centered on [20 20] with length 40 and width 10, and
+%% oriented pi/3 wrt axis Ox.
+%% @end example
+%%
+%% drawShape(..., OPTION)
+%% also specifies drawing options. OPTION can be 'draw' (default) or
+%% 'fill'.
+%% @end deftypefn
+function varargout = drawShape(type, param, varargin)
+
+ if ~iscell(type)
+ type = {type};
+ end
+ if ~iscell(param)
+ tmp = cell(1, size(param, 1));
+ for i=1:size(param, 1)
+ tmp{i} = param(i,:);
+ end
+ param = tmp;
+ end
+
+ option = 'draw';
+ if ~isempty(varargin)
+ var = varargin{1};
+ if strcmpi(var, 'fill')
+ option = 'fill';
+ end
+ end
+
+
+ % transform each shape into a polygon
+ shape = cell(1,length(type));
+ for i=1:length(type)
+ if strcmpi(type{i}, 'circle')
+ shape{i} = circleAsPolygon(param{i}, 128);
+ elseif strcmpi(type{i}, 'rect')
+ shape{i} = rectAsPolygon(param{i});
+ elseif strcmpi(type{i}, 'polygon')
+ shape{i} = param{i};
+ end
+ end
+
+
+ hold on;
+ h = zeros(length(shape), 1);
+ if strcmp(option, 'draw')
+ for i=1:length(shape)
+ h(i) = drawPolygon(shape{i});
+ end
+ else
+ for i=1:length(shape)
+ h(i) = fillPolygon(shape{i});
+ end
+ end
+
+ if nargout>0
+ varargout{1}=h;
+ end
+
+endfunction
+
diff --git a/inst/geom2d/edgeAngle.m b/inst/geom2d/edgeAngle.m
new file mode 100644
index 0000000..e1c1079
--- /dev/null
+++ b/inst/geom2d/edgeAngle.m
@@ -0,0 +1,61 @@
+%% Copyright (c) 2011, INRA
+%% 2003-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} {@var{theta} =} edgeAngle(@var{edge})
+%% Return angle of edge
+%%
+%% A = edgeAngle(EDGE)
+%% Returns the angle between horizontal, right-axis and the edge EDGE.
+%% Angle is given in radians, between 0 and 2*pi, in counter-clockwise
+%% direction.
+%% Notation for edge is [x1 y1 x2 y2] (coordinates of starting and ending
+%% points).
+%%
+%% Example
+%% p1 = [10 20];
+%% p2 = [30 40];
+%% rad2deg(edgeAngle([p1 p2]))
+%% ans =
+%% 45
+%%
+%% @seealso{edges2d, angles2d, edgeAngle, lineAngle, edgeLength}
+%% @end deftypefn
+
+function theta = edgeAngle(edge)
+
+ line = createLine(edge(:,1:2), edge(:,3:4));
+ theta = lineAngle(line);
+
+endfunction
+
diff --git a/inst/geom2d/edgeLength.m b/inst/geom2d/edgeLength.m
new file mode 100644
index 0000000..700a61f
--- /dev/null
+++ b/inst/geom2d/edgeLength.m
@@ -0,0 +1,60 @@
+%% Copyright (c) 2011, INRA
+%% 2004-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} {@var{len} = } edgeLength (@var{edge})
+%% Return length of an edge
+%%
+%% L = edgeLength(EDGE);
+%% Returns the length of an edge, with parametric representation:
+%% [x1 y1 x2 y2].
+%%
+%% The function also works for several edges, in this case input is a
+%% [N*4] array, containing parametric representation of each edge, and
+%% output is a [N*1] array containing length of each edge.
+%%
+%% @seealso{edges2d, edgeAngle}
+%% @end deftypefn
+
+function len = edgeLength(varargin)
+
+ % TODO : specify norm (euclidian, taxi, ...).
+
+ nargs = length(varargin);
+ if nargs == 1
+ edge = varargin{1};
+ len = sqrt(power(edge(:,3)-edge(:,1), 2) + power(edge(:,4)-edge(:,2), 2));
+ end
+
+endfunction
+
diff --git a/inst/geom2d/edgePosition.m b/inst/geom2d/edgePosition.m
new file mode 100644
index 0000000..38a1569
--- /dev/null
+++ b/inst/geom2d/edgePosition.m
@@ -0,0 +1,91 @@
+%% Copyright (c) 2011, INRA
+%% 2004-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} {@var{d} = } edgePosition (@var{point}, @var{edge})
+%% Return position of a point on an edge
+%%
+%% POS = edgePosition(POINT, EDGE);
+%% Computes position of point POINT on the edge EDGE, relative to the
+%% position of edge vertices.
+%% EDGE has the form [x1 y1 x2 y2],
+%% POINT has the form [x y], and is assumed to belong to edge.
+%% The position POS has meaning:
+%% POS<0: POINT is located before the first vertex
+%% POS=0: POINT is located on the first vertex
+%% 0<POS<1: POINT is located between the 2 vertices (on the edge)
+%% POS=1: POINT is located on the second vertex
+%% POS<0: POINT is located after the second vertex
+%%
+%% POS = edgePosition(POINT, EDGES);
+%% If EDGES is an array of NL edges, return NL positions, corresponding to
+%% each edge.
+%%
+%% POS = edgePosition(POINTS, EDGE);
+%% If POINTS is an array of NP points, return NP positions, corresponding
+%% to each point.
+%%
+%% POS = edgePosition(POINTS, EDGES);
+%% If POINTS is an array of NP points and edgeS is an array of NL edges,
+%% return an array of [NP NL] position, corresponding to each couple
+%% point-edge.
+%%
+%% @seealso{edges2d, createEdge, onEdge}
+%% @end deftypefn
+
+function d = edgePosition(point, edge)
+
+ % number of points and of edges
+ Nl = size(edge, 1);
+ Np = size(point, 1);
+
+ if Np==Nl
+ dxl = edge(:, 3)-edge(:,1);
+ dyl = edge(:, 4)-edge(:,2);
+ dxp = point(:, 1) - edge(:, 1);
+ dyp = point(:, 2) - edge(:, 2);
+
+ d = (dxp.*dxl + dyp.*dyl)./(dxl.*dxl+dyl.*dyl);
+
+ else
+ % expand one of the array to have the same size
+ dxl = repmat((edge(:,3)-edge(:,1))', Np, 1);
+ dyl = repmat((edge(:,4)-edge(:,2))', Np, 1);
+ dxp = repmat(point(:,1), 1, Nl) - repmat(edge(:,1)', Np, 1);
+ dyp = repmat(point(:,2), 1, Nl) - repmat(edge(:,2)', Np, 1);
+
+ d = (dxp.*dxl + dyp.*dyl)./(dxl.*dxl+dyl.*dyl);
+ end
+
+endfunction
+
diff --git a/inst/geom2d/edgeToLine.m b/inst/geom2d/edgeToLine.m
new file mode 100644
index 0000000..2f2cf58
--- /dev/null
+++ b/inst/geom2d/edgeToLine.m
@@ -0,0 +1,56 @@
+%% Copyright (c) 2011, INRA
+%% 2009-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} {@var{line} = } edgeToLine (@var{edge})
+%% Convert an edge to a straight line
+%%
+%% LINE = edgeToLine(EDGE);
+%% Returns the line containing the edge EDGE.
+%%
+%% Example
+%% edge = [2 3 4 5];
+%% line = edgeToLine(edge);
+%% figure(1); hold on; axis([0 10 0 10]);
+%% drawLine(line, 'color', 'g')
+%% drawEdge(edge, 'linewidth', 2)
+%%
+%% @seealso{edges2d, lines2d}
+%% @end deftypefn
+
+function line = edgeToLine(edge)
+
+ line = [edge(:, 1:2) edge(:, 3:4)-edge(:, 1:2)];
+
+endfunction
+
diff --git a/inst/geom2d/edges2d.m b/inst/geom2d/edges2d.m
new file mode 100644
index 0000000..299d4db
--- /dev/null
+++ b/inst/geom2d/edges2d.m
@@ -0,0 +1,56 @@
+%% Copyright (c) 2011, INRA
+%% 2008-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} edges2d ()
+%% Description of functions operating on planar edges
+%
+% An edge is represented by the corodinate of its end points:
+% EDGE = [X1 Y1 X2 Y2];
+%
+% A set of edges is represented by a N*4 array, each row representing an
+% edge.
+%
+%
+% @seealso{lines2d, rays2d, points2d
+% createEdge, edgeAngle, edgeLength, edgeToLine, midPoint
+% intersectEdges, intersectLineEdge, isPointOnEdge
+% clipEdge, transformEdge
+% drawEdge, drawCenteredEdge}
+%% @end deftypefn
+function edges2d(varargin)
+
+ help('edges2d');
+
+endfunction
+
diff --git a/inst/geom2d/ellipseAsPolygon.m b/inst/geom2d/ellipseAsPolygon.m
new file mode 100644
index 0000000..a8d2faf
--- /dev/null
+++ b/inst/geom2d/ellipseAsPolygon.m
@@ -0,0 +1,93 @@
+%% Copyright (c) 2011, INRA
+%% 2004-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} {@var{p} = } ellipseAsPolygon (@var{ell}, @var{n})
+%% Convert an ellipse into a series of points
+%%
+%% P = ellipseAsPolygon(ELL, N);
+%% converts ELL given as [x0 y0 a b] or [x0 y0 a b theta] into a polygon
+%% with N edges. The result P is (N+1)-by-2 array containing coordinates
+%% of the N+1 vertices of the polygon.
+%% The resulting polygon is closed, i.e. the last point is the same as the
+%% first one.
+%%
+%% P = ellipseAsPolygon(ELL);
+%% Use a default number of edges equal to 72. This result in one piont for
+%% each 5 degrees.
+%%
+%% [X Y] = ellipseAsPolygon(...);
+%% Return the coordinates o fvertices in two separate arrays.
+%%
+%% @seealso{ellipses2d, circleAsPolygon, rectAsPolygon, drawEllipse}
+%% @end deftypefn
+
+function varargout = ellipseAsPolygon(ellipse, N)
+
+ % default value for N
+ if nargin < 2
+ N = 72;
+ end
+
+ % angle of ellipse
+ theta = 0;
+ if size(ellipse, 2) > 4
+ theta = ellipse(:,5);
+ end
+
+ % get ellipse parameters
+ xc = ellipse(:,1);
+ yc = ellipse(:,2);
+ a = ellipse(:,3);
+ b = ellipse(:,4);
+
+ % create time basis
+ t = linspace(0, 2*pi, N+1)';
+
+ % pre-compute trig functions (angles is in degrees)
+ cot = cosd(theta);
+ sit = sind(theta);
+
+ % position of points
+ x = xc + a * cos(t) * cot - b * sin(t) * sit;
+ y = yc + a * cos(t) * sit + b * sin(t) * cot;
+
+ % format output depending on number of a param.
+ if nargout == 1
+ varargout = {[x y]};
+ elseif nargout == 2
+ varargout = {x, y};
+ end
+
+endfunction
+
diff --git a/inst/geom2d/ellipses2d.m b/inst/geom2d/ellipses2d.m
new file mode 100644
index 0000000..5009645
--- /dev/null
+++ b/inst/geom2d/ellipses2d.m
@@ -0,0 +1,50 @@
+%% Copyright (c) 2011, INRA
+%% 2008-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} ellipses2d ()
+%% Description of functions operating on ellipses.
+%%
+%% Ellipses are represented by their center, the length of their 2
+%% semi-axes length, and their angle from the Ox direction (in degrees).
+%% E = [XC YC A B THETA];
+%%
+%% @seealso{circles2d, inertiaEllipse, isPointInEllipse, ellipseAsPolygon
+%% drawEllipse, drawEllipseArc}
+%% @end deftypefn
+
+function ellipses2d(varargin)
+
+ help('ellipses2d');
+
+endfunction
diff --git a/inst/geom2d/enclosingCircle.m b/inst/geom2d/enclosingCircle.m
new file mode 100644
index 0000000..cd34ef2
--- /dev/null
+++ b/inst/geom2d/enclosingCircle.m
@@ -0,0 +1,98 @@
+%% 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} {@var{circle} = } enclosingCircle (@var{pts})
+%% Find the minimum circle enclosing a set of points.
+%%
+%% CIRCLE = enclosingCircle(POINTS);
+%% compute cirlce CIRCLE=[xc yc r] which enclose all points POINTS given
+%% as an [Nx2] array.
+%%
+%%
+%% Rewritten from a file from
+%% Yazan Ahed
+%% which was rewritten from a Java applet by Shripad Thite :
+%% @url{http://heyoka.cs.uiuc.edu/~thite/mincircle/}
+%%
+%% @seealso{circles2d, points2d, boxes2d}
+%% @end deftypefn
+
+function circle = enclosingCircle(pts)
+
+ % works on convex hull : it is faster
+ pts = pts(convhull(pts(:,1), pts(:,2)), :);
+
+ circle = recurseCircle(size(pts, 1), pts, 1, zeros(3, 2));
+
+endfunction
+
+function circ = recurseCircle(n, p, m, b)
+% n: number of points given
+% m: an argument used by the function. Always use 1 for m.
+% bnry: an argument (3x2 array) used by the function to set the points that
+% determines the circle boundry. You have to be careful when choosing this
+% array's values. I think the values should be somewhere outside your points
+% boundary. For my case, for example, I know the (x,y) I have will be something
+% in between (-5,-5) and (5,5), so I use bnry as:
+% [-10 -10
+% -10 -10
+% -10 -10]
+
+
+ if m==4
+ circ = createCircle(b(1,:), b(2,:), b(3,:));
+ return;
+ end
+
+ circ = [Inf Inf 0];
+
+ if m == 2
+ circ = [b(1,1:2) 0];
+ elseif m == 3
+ c = (b(1,:) + b(2,:))/2;
+ circ = [c distancePoints(b(1,:), c)];
+ end
+
+
+ for i = 1:n
+ if distancePoints(p(i,:), circ(1:2)) > circ(3)
+ if sum(b(:,1)==p(i,1) & b(:,2)==p(i,2)) == 0
+ b(m,:) = p(i,:);
+ circ = recurseCircle(i, p, m+1, b);
+ end
+ end
+ end
+
+endfunction
+
diff --git a/inst/geom2d/fitAffineTransform2d.m b/inst/geom2d/fitAffineTransform2d.m
new file mode 100644
index 0000000..ff66ebb
--- /dev/null
+++ b/inst/geom2d/fitAffineTransform2d.m
@@ -0,0 +1,73 @@
+%% Copyright (c) 2011, INRA
+%% 2009-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} {@var{T} = } fitAffineTransform2d (@var{pts1}, @var{pts2})
+%% Fit an affine transform using two point sets.
+%%
+%% Example
+%%
+%% @example
+%% N = 10;
+%% pts = rand(N, 2)*10;
+%% trans = createRotation(3, 4, pi/4);
+%% pts2 = transformPoint(pts, trans);
+%% pts3 = pts2 + randn(N, 2)*2;
+%% fitted = fitAffineTransform2d(pts, pts2)
+%%@end example
+%%
+%% @seealso{transforms2d}
+%% @end deftypefn
+
+function trans = fitAffineTransform2d(pts1, pts2)
+
+ % number of points
+ N = size(pts1, 1);
+
+ % main matrix of the problem
+ A = [...
+ pts1(:,1) pts1(:,2) ones(N,1) zeros(N, 3) ; ...
+ zeros(N, 3) pts1(:,1) pts1(:,2) ones(N,1) ];
+
+ % conditions initialisations
+ B = [pts2(:,1) ; pts2(:,2)];
+
+ % compute coefficients using least square
+ coefs = A\B;
+
+ % format to a matrix
+ trans = [coefs(1:3)' ; coefs(4:6)'; 0 0 1];
+
+endfunction
+
+
diff --git a/inst/geom2d/hexagonalGrid.m b/inst/geom2d/hexagonalGrid.m
new file mode 100644
index 0000000..dd5a8a1
--- /dev/null
+++ b/inst/geom2d/hexagonalGrid.m
@@ -0,0 +1,122 @@
+%% 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} {@var{pts} = } hexagonalGrid (@var{bounds}, @var{origin}, @var{size})
+%% Generate hexagonal grid of points in the plane.
+%%
+%% usage
+%% PTS = hexagonalGrid(BOUNDS, ORIGIN, SIZE)
+%% generate points, lying in the window defined by BOUNDS (=[xmin ymin
+%% xmax ymax]), starting from origin with a constant step equal to size.
+%% SIZE is constant and is equals to the length of the sides of each
+%% hexagon.
+%%
+%% TODO: add possibility to use rotated grid
+%% @end deftypefn
+
+function varargout = hexagonalGrid(bounds, origin, size, varargin)
+
+ size = size(1);
+ dx = 3*size;
+ dy = size*sqrt(3);
+
+
+
+ % consider two square grids with different centers
+ pts1 = squareGrid(bounds, origin + [0 0], [dx dy], varargin{:});
+ pts2 = squareGrid(bounds, origin + [dx/3 0], [dx dy], varargin{:});
+ pts3 = squareGrid(bounds, origin + [dx/2 dy/2], [dx dy], varargin{:});
+ pts4 = squareGrid(bounds, origin + [-dx/6 dy/2], [dx dy], varargin{:});
+
+ % gather points
+ pts = [pts1;pts2;pts3;pts4];
+
+
+
+
+ % eventually compute also edges, clipped by bounds
+ % TODO : manage generation of edges
+ if nargout>1
+ edges = zeros([0 4]);
+ x0 = origin(1);
+ y0 = origin(2);
+
+ % find all x coordinate
+ x1 = bounds(1) + mod(x0-bounds(1), dx);
+ x2 = bounds(3) - mod(bounds(3)-x0, dx);
+ lx = (x1:dx:x2)';
+
+ % horizontal edges : first find y's
+ y1 = bounds(2) + mod(y0-bounds(2), dy);
+ y2 = bounds(4) - mod(bounds(4)-y0, dy);
+ ly = (y1:dy:y2)';
+
+ % number of points in each coord, and total number of points
+ ny = length(ly);
+ nx = length(lx);
+
+ if bounds(1)-x1+dx<size
+ disp('intersect bounding box');
+ end
+
+ if bounds(3)-x2<size
+ disp('intersect 2');
+ edges = [edges;repmat(x2, [ny 1]) ly repmat(bounds(3), [ny 1]) ly];
+ x2 = x2-dx;
+ lx = (x1:dx:x2)';
+ nx = length(lx);
+ end
+
+ for i=1:length(ly)
+ ind = (1:nx)';
+ tmpEdges(ind, 1) = lx;
+ tmpEdges(ind, 2) = ly(i);
+ tmpEdges(ind, 3) = lx+size;
+ tmpEdges(ind, 4) = ly(i);
+ edges = [edges; tmpEdges];
+ end
+
+ end
+
+ % process output arguments
+ if nargout>0
+ varargout{1} = pts;
+
+ if nargout>1
+ varargout{2} = edges;
+ end
+ end
+
+endfunction
+
diff --git a/inst/geom2d/inertiaEllipse.m b/inst/geom2d/inertiaEllipse.m
new file mode 100644
index 0000000..533ce65
--- /dev/null
+++ b/inst/geom2d/inertiaEllipse.m
@@ -0,0 +1,96 @@
+%% Copyright (c) 2011, INRA
+%% 2008-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} {@var{ell} = } inertiaEllipse (@var{pts})
+%% Inertia ellipse of a set of points
+%%
+%% ELL = inertiaEllipse(PTS);
+%% where PTS is a N*2 array containing coordinates of N points, computes
+%% the inertia ellispe of the set of points.
+%%
+%% The result has the form:
+%% ELL = [XC YC A B THETA],
+%% with XC and YC being the center of mass of the point set, A and B are
+%% the lengths of the inertia ellipse (see below), and THETA is the angle
+%% of the main inertia axis with the horizontal (counted in degrees
+%% between 0 and 180).
+%% A and B are the standard deviations of the point coordinates when
+%% ellipse is aligned with the inertia axes.
+%%
+%% @example
+%% pts = randn(100, 2);
+%% pts = transformPoint(pts, createScaling(5, 2));
+%% pts = transformPoint(pts, createRotation(pi/6));
+%% pts = transformPoint(pts, createTranslation(3, 4));
+%% ell = inertiaEllipse(pts);
+%% figure(1); clf; hold on;
+%% drawPoint(pts);
+%% drawEllipse(ell, 'linewidth', 2, 'color', 'r');
+%% @end example
+%%
+%% @seealso{ellipses2d, drawEllipse}
+%% @end deftypefn
+
+function ell = inertiaEllipse(points)
+
+ % ellipse center
+ xc = mean(points(:,1));
+ yc = mean(points(:,2));
+
+ % recenter points
+ x = points(:,1) - xc;
+ y = points(:,2) - yc;
+
+ % number of points
+ n = size(points, 1);
+
+ % inertia parameters
+ Ixx = sum(x.^2) / n;
+ Iyy = sum(y.^2) / n;
+ Ixy = sum(x.*y) / n;
+
+ % compute ellipse semi-axis lengths
+ common = sqrt( (Ixx - Iyy)^2 + 4 * Ixy^2);
+ ra = sqrt(2) * sqrt(Ixx + Iyy + common);
+ rb = sqrt(2) * sqrt(Ixx + Iyy - common);
+
+ % compute ellipse angle in degrees
+ theta = atan2(2 * Ixy, Ixx - Iyy) / 2;
+ theta = rad2deg(theta);
+
+ % create the resulting inertia ellipse
+ ell = [xc yc ra rb theta];
+
+endfunction
+
diff --git a/inst/geom2d/intersectBoxes.m b/inst/geom2d/intersectBoxes.m
new file mode 100644
index 0000000..1e1d9fc
--- /dev/null
+++ b/inst/geom2d/intersectBoxes.m
@@ -0,0 +1,76 @@
+%% Copyright (c) 2011, INRA
+%% 2010-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} {@var{box} =} intersectBoxes (@var{box1}, @var{box2})
+%% Intersection of two bounding boxes.
+%%
+%% Example
+%%
+%% @example
+%% box1 = [5 20 5 30];
+%% box2 = [0 15 0 15];
+%% intersectBoxes(box1, box2)
+%% ans =
+%% 5 15 5 15
+%% @end example
+%%
+%% @seealso{boxes2d, drawBox, mergeBoxes}
+%% @end deftypefn
+
+function bb = intersectBoxes(box1, box2)
+
+ % unify sizes of data
+ if size(box1,1) == 1
+ box1 = repmat(box1, size(box2,1), 1);
+ elseif size(box2, 1) == 1
+ box2 = repmat(box2, size(box1,1), 1);
+ elseif size(box1,1) != size(box2,1)
+ error('geom2d:Error',"Bad size for inputs.\n");
+ end
+
+ % compute extreme coords
+ mini = min(box1(:,[2 4]), box2(:,[2 4]));
+ maxi = max(box1(:,[1 3]), box2(:,[1 3]));
+
+ % concatenate result into a new box structure
+ bb = [maxi(:,1) mini(:,1) maxi(:,2) mini(:,2)];
+
+endfunction
+
+%!test
+%! box1 = [5 20 10 25];
+%! box2 = [0 15 15 20];
+%! res = [5 15 15 20];
+%! bb = intersectBoxes(box1, box2);
+%! assert (res, bb, 1e-6);
diff --git a/inst/geom2d/intersectCircles.m b/inst/geom2d/intersectCircles.m
new file mode 100644
index 0000000..7ef7a0e
--- /dev/null
+++ b/inst/geom2d/intersectCircles.m
@@ -0,0 +1,129 @@
+%% 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} {@var{points} = } intersectCircles (@var{circle1}, @var{circle2})
+%% Intersection points of two circles.
+%%
+%% POINTS = intersectCircles(CIRCLE1, CIRCLE2)
+%% Computes the intersetion point of the two circles CIRCLE1 and CIRCLE1.
+%% Both circles are given with format: [XC YC R], with (XC,YC) being the
+%% coordinates of the center and R being the radius.
+%% POINTS is a 2-by-2 array, containing coordinate of an intersection
+%% point on each row.
+%% In the case of tangent circles, the intersection is returned twice. It
+%% can be simplified by using the 'unique' function.
+%%
+%% Example
+%% % intersection points of two distant circles
+%% c1 = [0 0 10];
+%% c2 = [10 0 10];
+%% pts = intersectCircles(c1, c2)
+%% pts =
+%% 5 -8.6603
+%% 5 8.6603
+%%
+%% % intersection points of two tangent circles
+%% c1 = [0 0 10];
+%% c2 = [20 0 10];
+%% pts = intersectCircles(c1, c2)
+%% pts =
+%% 10 0
+%% 10 0
+%% pts2 = unique(pts, 'rows')
+%% pts2 =
+%% 10 0
+%%
+%% References
+%% http://local.wasp.uwa.edu.au/~pbourke/geometry/2circle/
+%% http://mathworld.wolfram.com/Circle-CircleIntersection.html
+%%
+%% @seealso{circles2d, intersectLineCircle, radicalAxis}
+%% @end deftypefn
+
+function points = intersectCircles(circle1, circle2)
+
+ % adapt sizes of inputs
+ n1 = size(circle1, 1);
+ n2 = size(circle2, 1);
+ if n1 ~= n2
+ if n1 > 1 && n2 == 1
+ circle2 = repmat(circle2, n1, 1);
+ elseif n2 > 1 && n1 == 1
+ circle1 = repmat(circle1, n2, 1);
+ else
+ error('Both input should have same number of rows');
+ end
+ end
+
+ % extract center and radius of each circle
+ center1 = circle1(:, 1:2);
+ center2 = circle2(:, 1:2);
+ r1 = circle1(:,3);
+ r2 = circle2(:,3);
+
+ % allocate memory for result
+ nPoints = length(r1);
+ points = NaN * ones(2*nPoints, 2);
+
+ % distance between circle centers
+ d12 = distancePoints(center1, center2, 'diag');
+
+ % get indices of circle couples with intersections
+ inds = d12 >= abs(r1 - r2) & d12 <= (r1 + r2);
+
+ if sum(inds) == 0
+ return;
+ end
+
+ % angle of line from center1 to center2
+ angle = angle2Points(center1(inds,:), center2(inds,:));
+
+ % position of intermediate point, located at the intersection of the
+ % radical axis with the line joining circle centers
+ d1m = d12(inds) / 2 + (r1(inds).^2 - r2(inds).^2) ./ (2 * d12(inds));
+ tmp = polarPoint(center1(inds, :), d1m, angle);
+
+ % distance between intermediate point and each intersection point
+ h = sqrt(r1(inds).^2 - d1m.^2);
+
+ % indices of valid intersections
+ inds2 = find(inds)*2;
+ inds1 = inds2 - 1;
+
+ % create intersection points
+ points(inds1, :) = polarPoint(tmp, h, angle - pi/2);
+ points(inds2, :) = polarPoint(tmp, h, angle + pi/2);
+
+endfunction
+
diff --git a/inst/geom2d/intersectEdges.m b/inst/geom2d/intersectEdges.m
new file mode 100644
index 0000000..85a2bb1
--- /dev/null
+++ b/inst/geom2d/intersectEdges.m
@@ -0,0 +1,175 @@
+%% Copyright (c) 2011, INRA
+%% 2003-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} {@var{point} = } intersectEdges (@var{edge1}, @var{edge2})
+%% Return all intersections between two set of edges
+%%
+%% P = intersectEdges(E1, E2);
+%% returns the intersection point of lines L1 and L2. E1 and E2 are 1-by-4
+%% arrays, containing parametric representation of each edge (in the form
+%% [x1 y1 x2 y2], see 'createEdge' for details).
+%%
+%% In case of colinear edges, returns [Inf Inf].
+%% In case of parallel but not colinear edges, returns [NaN NaN].
+%%
+%% If each input is [N*4] array, the result is a [N*2] array containing
+%% intersections of each couple of edges.
+%% If one of the input has N rows and the other 1 row, the result is a
+%% [N*2] array.
+%%
+%% @seealso{edges2d, intersectLines}
+%% @end deftypefn
+
+function point = intersectEdges(edge1, edge2)
+ %% Initialisations
+
+ % ensure input arrays are same size
+ N1 = size(edge1, 1);
+ N2 = size(edge2, 1);
+
+ % ensure input have same size
+ if N1~=N2
+ if N1==1
+ edge1 = repmat(edge1, [N2 1]);
+ N1 = N2;
+ elseif N2==1
+ edge2 = repmat(edge2, [N1 1]);
+ end
+ end
+
+ % tolerance for precision
+ tol = 1e-14;
+
+ % initialize result array
+ x0 = zeros(N1, 1);
+ y0 = zeros(N1, 1);
+
+
+ %% Detect parallel and colinear cases
+
+ % indices of parallel edges
+ %par = abs(dx1.*dy2 - dx1.*dy2)<tol;
+ par = isParallel(edge1(:,3:4)-edge1(:,1:2), edge2(:,3:4)-edge2(:,1:2));
+
+ % indices of colinear edges
+ % equivalent to: |(x2-x1)*dy1 - (y2-y1)*dx1| < eps
+ col = abs( (edge2(:,1)-edge1(:,1)).*(edge1(:,4)-edge1(:,2)) - ...
+ (edge2(:,2)-edge1(:,2)).*(edge1(:,3)-edge1(:,1)) )<tol & par;
+
+ % Parallel edges have no intersection -> return [NaN NaN]
+ x0(par & ~col) = NaN;
+ y0(par & ~col) = NaN;
+
+
+ %% Process colinear edges
+
+ % colinear edges may have 0, 1 or infinite intersection
+ % Discrimnation based on position of edge2 vertices on edge1
+ if sum(col)>0
+ % array for storing results of colinear edges
+ resCol = Inf*ones(size(col));
+
+ % compute position of edge2 vertices wrt edge1
+ t1 = edgePosition(edge2(col, 1:2), edge1(col, :));
+ t2 = edgePosition(edge2(col, 3:4), edge1(col, :));
+
+ % control location of vertices: we want t1<t2
+ if t1>t2
+ tmp = t1;
+ t1 = t2;
+ t2 = tmp;
+ end
+
+ % edge totally before first vertex or totally after last vertex
+ resCol(col(t2<-eps)) = NaN;
+ resCol(col(t1>1+eps)) = NaN;
+
+ % set up result into point coordinate
+ x0(col) = resCol;
+ y0(col) = resCol;
+
+ % touches on first point of first edge
+ touch = col(abs(t2)<1e-14);
+ x0(touch) = edge1(touch, 1);
+ y0(touch) = edge1(touch, 2);
+
+ % touches on second point of first edge
+ touch = col(abs(t1-1)<1e-14);
+ x0(touch) = edge1(touch, 3);
+ y0(touch) = edge1(touch, 4);
+ end
+
+
+ %% Process non parallel cases
+
+ % process intersecting edges whose interecting lines intersect
+ i = find(~par);
+
+ % use a test to avoid process empty arrays
+ if sum(i)>0
+ % extract base parameters of supporting lines for non-parallel edges
+ x1 = edge1(i,1);
+ y1 = edge1(i,2);
+ dx1 = edge1(i,3)-x1;
+ dy1 = edge1(i,4)-y1;
+ x2 = edge2(i,1);
+ y2 = edge2(i,2);
+ dx2 = edge2(i,3)-x2;
+ dy2 = edge2(i,4)-y2;
+
+ % compute intersection points of supporting lines
+ delta = (dx2.*dy1-dx1.*dy2);
+ x0(i) = ((y2-y1).*dx1.*dx2 + x1.*dy1.*dx2 - x2.*dy2.*dx1) ./ delta;
+ y0(i) = ((x2-x1).*dy1.*dy2 + y1.*dx1.*dy2 - y2.*dx2.*dy1) ./ -delta;
+
+ % compute position of intersection points on each edge
+ % t1 is position on edge1, t2 is position on edge2
+ t1 = ((y0(i)-y1).*dy1 + (x0(i)-x1).*dx1) ./ (dx1.*dx1+dy1.*dy1);
+ t2 = ((y0(i)-y2).*dy2 + (x0(i)-x2).*dx2) ./ (dx2.*dx2+dy2.*dy2);
+
+ % check position of points on edges.
+ % it should be comprised between 0 and 1 for both t1 and t2.
+ % if not, the edges do not intersect
+ out = t1<-tol | t1>1+tol | t2<-tol | t2>1+tol;
+ x0(i(out)) = NaN;
+ y0(i(out)) = NaN;
+ end
+
+
+ %% format output arguments
+
+ point = [x0 y0];
+
+endfunction
+
diff --git a/inst/geom2d/intersectLineCircle.m b/inst/geom2d/intersectLineCircle.m
new file mode 100644
index 0000000..890a685
--- /dev/null
+++ b/inst/geom2d/intersectLineCircle.m
@@ -0,0 +1,106 @@
+%% Copyright (c) 2011, INRA
+%% 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} {@var{points} = } intersectLineCircle (@var{line}, @var{circle})
+%% Intersection point(s) of a line and a circle
+%%
+%% INTERS = intersectLineCircle(LINE, CIRCLE);
+%% Returns a 2-by-2 array, containing on each row the coordinates of an
+%% intersection point. If the line and circle do not intersect, the result
+%% is filled with NaN.
+%%
+%% Example
+%% % base point
+%% center = [10 0];
+%% % create vertical line
+%% l1 = [center 0 1];
+%% % circle
+%% c1 = [center 5];
+%% pts = intersectLineCircle(l1, c1)
+%% pts =
+%% 10 -5
+%% 10 5
+%% % draw the result
+%% figure; clf; hold on;
+%% axis([0 20 -10 10]);
+%% drawLine(l1);
+%% drawCircle(c1);
+%% drawPoint(pts, 'rx');
+%% axis equal;
+%%
+%% @seealso{lines2d, circles2d, intersectLines, intersectCircles}
+%% @end deftypefn
+
+function points = intersectLineCircle(line, circle)
+
+ % local precision
+ eps = 1e-14;
+
+ % center parameters
+ center = circle(:, 1:2);
+ radius = circle(:, 3);
+
+ % line parameters
+ dp = line(:, 1:2) - center;
+ vl = line(:, 3:4);
+
+ % coefficient of second order equation
+ a = sum(line(:, 3:4).^2, 2);
+ b = 2*sum(dp .* vl, 2);
+ c = sum(dp.^2, 2) - radius.^2;
+
+ % discriminant
+ delta = b .^ 2 - 4 * a .* c;
+
+ if delta > eps
+ % find two roots of second order equation
+ u1 = (-b - sqrt(delta)) / 2 ./ a;
+ u2 = (-b + sqrt(delta)) / 2 ./ a;
+
+ % convert into 2D coordinate
+ points = [line(1:2) + u1 * line(3:4) ; line(1:2) + u2 * line(3:4)];
+
+ elseif abs(delta) < eps
+ % find unique root, and convert to 2D coord.
+ u = -b / 2 ./ a;
+ points = line(1:2) + u*line(3:4);
+
+ else
+ % fill with NaN
+ points = NaN * ones(2, 2);
+ return;
+ end
+
+endfunction
+
diff --git a/inst/geom2d/intersectLineEdge.m b/inst/geom2d/intersectLineEdge.m
new file mode 100644
index 0000000..90908c8
--- /dev/null
+++ b/inst/geom2d/intersectLineEdge.m
@@ -0,0 +1,106 @@
+%% Copyright (c) 2011, INRA
+%% 2003-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} {@var{point} = } intersecLineEdge (@var{line}, @var{edge})
+%% Return intersection between a line and an edge.
+%%
+%% Returns the intersection point of lines @var{line} and edge @var{edge}.
+%% @var{line} is a 1x4 array containing parametric representation of the line
+%% (in the form [x0 y0 dx dy], see @code{createLine} for details).
+%% @var{edge} is a 1x4 array containing coordinates of first and second point
+%% (in the form [x1 y1 x2 y2], see @code{createEdge} for details).
+%%
+%% In case of colinear line and edge, returns [Inf Inf].
+%% If line does not intersect edge, returns [NaN NaN].
+%%
+%% If each input is [N*4] array, the result is a [N*2] array containing
+%% intersections for each couple of edge and line.
+%% If one of the input has N rows and the other 1 row, the result is a
+%% [N*2] array.
+%%
+%% @seealso{lines2d, edges2d, intersectEdges, intersectLine}
+%% @end deftypefn
+
+function point = intersectLineEdge(lin, edge)
+ x0 = lin(:,1);
+ y0 = lin(:,2);
+ dx1 = lin(:,3);
+ dy1 = lin(:,4);
+ x1 = edge(:,1);
+ y1 = edge(:,2);
+ x2 = edge(:,3);
+ y2 = edge(:,4);
+ dx2 = x2-x1;
+ dy2 = y2-y1;
+
+ N1 = length(x0);
+ N2 = length(x1);
+
+ % indices of parallel lines
+ par = abs(dx1.*dy2-dx2.*dy1)<1e-14;
+
+ % indices of colinear lines
+ col = abs((x1-x0).*dy1-(y1-y0).*dx1)<1e-14 & par ;
+
+ xi(col) = Inf;
+ yi(col) = Inf;
+ xi(par & ~col) = NaN;
+ yi(par & ~col) = NaN;
+
+ i = ~par;
+
+ % compute intersection points
+ if N1==N2
+ xi(i) = ((y1(i)-y0(i)).*dx1(i).*dx2(i) + x0(i).*dy1(i).*dx2(i) - x1(i).*dy2(i).*dx1(i)) ./ ...
+ (dx2(i).*dy1(i)-dx1(i).*dy2(i)) ;
+ yi(i) = ((x1(i)-x0(i)).*dy1(i).*dy2(i) + y0(i).*dx1(i).*dy2(i) - y1(i).*dx2(i).*dy1(i)) ./ ...
+ (dx1(i).*dy2(i)-dx2(i).*dy1(i)) ;
+ elseif N1==1
+ xi(i) = ((y1(i)-y0).*dx1.*dx2(i) + x0.*dy1.*dx2(i) - x1(i).*dy2(i).*dx1) ./ ...
+ (dx2(i).*dy1-dx1.*dy2(i)) ;
+ yi(i) = ((x1(i)-x0).*dy1.*dy2(i) + y0.*dx1.*dy2(i) - y1(i).*dx2(i).*dy1) ./ ...
+ (dx1.*dy2(i)-dx2(i).*dy1) ;
+ elseif N2==1
+ xi(i) = ((y1-y0(i)).*dx1(i).*dx2 + x0(i).*dy1(i).*dx2 - x1(i).*dy2.*dx1(i)) ./ ...
+ (dx2.*dy1(i)-dx1(i).*dy2) ;
+ yi(i) = ((x1-x0(i)).*dy1(i).*dy2 + y0(i).*dx1(i).*dy2 - y1(i).*dx2.*dy1(i)) ./ ...
+ (dx1(i).*dy2-dx2.*dy1(i)) ;
+ end
+
+ point = [xi' yi'];
+ out = find(~isPointOnEdge(point, edge));
+ point(out, :) = repmat([NaN NaN], [length(out) 1]);
+
+endfunction
+
diff --git a/inst/geom2d/intersectLines.m b/inst/geom2d/intersectLines.m
new file mode 100644
index 0000000..2c959e2
--- /dev/null
+++ b/inst/geom2d/intersectLines.m
@@ -0,0 +1,178 @@
+%% Copyright (c) 2011, INRA
+%% 2003-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} {@var{point} =} intersectLines (@var{line1}, @var{line2})
+%% @deftypefnx {Function File} {@var{point} =} intersectLines (@var{line1}, @var{line2},@var{eps})
+%% Return all intersection points of N lines in 2D.
+%%
+%% Returns the intersection point of lines @var{line1} and @var{line2}.
+%% @var{line1} and @var{line2} are [1*4]
+%% arrays, containing parametric representation of each line (in the form
+%% [x0 y0 dx dy], see @code{createLine} for details).
+%%
+%% In case of colinear lines, returns [Inf Inf].
+%% In case of parallel but not colinear lines, returns [NaN NaN].
+%%
+%% If each input is [N*4] array, the result is a [N*2] array containing
+%% intersections of each couple of lines.
+%% If one of the input has N rows and the other 1 row, the result is a
+%% [N*2] array.
+%%
+%% A third input argument specifies the tolerance for detecting parallel lines.
+%% Default is 1e-14.
+%%
+%% Example
+%%
+%% @example
+%% line1 = createLine([0 0], [10 10]);
+%% line2 = createLine([0 10], [10 0]);
+%% point = intersectLines(line1, line2)
+%% point =
+%% 5 5
+%% @end example
+%%
+%% @seealso{lines2d, edges2d, intersectEdges, intersectLineEdge, intersectLineCircle}
+%% @end deftypefn
+
+function point = intersectLines(line1, line2, varargin)
+
+ % extreact tolerance
+ tol = 1e-14;
+ if !isempty(varargin)
+ tol = varargin{1};
+ end
+
+ x1 = line1(:,1);
+ y1 = line1(:,2);
+ dx1 = line1(:,3);
+ dy1 = line1(:,4);
+
+ x2 = line2(:,1);
+ y2 = line2(:,2);
+ dx2 = line2(:,3);
+ dy2 = line2(:,4);
+
+ N1 = length(x1);
+ N2 = length(x2);
+
+ % indices of parallel lines
+ par = abs(dx1.*dy2 - dx2.*dy1) < tol;
+
+ % indices of colinear lines
+ col = abs((x2-x1) .* dy1 - (y2-y1) .* dx1) < tol & par ;
+
+ x0(col) = Inf;
+ y0(col) = Inf;
+ x0(par & !col) = NaN;
+ y0(par & !col) = NaN;
+
+ i = !par;
+
+ % compute intersection points
+ if N1==N2
+ x0(i) = ((y2(i)-y1(i)).*dx1(i).*dx2(i) + x1(i).*dy1(i).*dx2(i) - x2(i).*dy2(i).*dx1(i)) ./ ...
+ (dx2(i).*dy1(i)-dx1(i).*dy2(i)) ;
+ y0(i) = ((x2(i)-x1(i)).*dy1(i).*dy2(i) + y1(i).*dx1(i).*dy2(i) - y2(i).*dx2(i).*dy1(i)) ./ ...
+ (dx1(i).*dy2(i)-dx2(i).*dy1(i)) ;
+
+ elseif N1==1
+ x0(i) = ((y2(i)-y1).*dx1.*dx2(i) + x1.*dy1.*dx2(i) - x2(i).*dy2(i).*dx1) ./ ...
+ (dx2(i).*dy1-dx1.*dy2(i)) ;
+ y0(i) = ((x2(i)-x1).*dy1.*dy2(i) + y1.*dx1.*dy2(i) - y2(i).*dx2(i).*dy1) ./ ...
+ (dx1.*dy2(i)-dx2(i).*dy1) ;
+
+ elseif N2==1
+ x0(i) = ((y2-y1(i)).*dx1(i).*dx2 + x1(i).*dy1(i).*dx2 - x2.*dy2.*dx1(i)) ./ ...
+ (dx2.*dy1(i)-dx1(i).*dy2) ;
+ y0(i) = ((x2-x1(i)).*dy1(i).*dy2 + y1(i).*dx1(i).*dy2 - y2.*dx2.*dy1(i)) ./ ...
+ (dx1(i).*dy2-dx2.*dy1(i)) ;
+
+ else
+ % formattage a rajouter
+ x0(i) = ((y2(i)-y1(i)).*dx1(i).*dx2(i) + x1(i).*dy1(i).*dx2(i) - x2(i).*dy2(i).*dx1(i)) ./ ...
+ (dx2(i).*dy1(i)-dx1(i).*dy2(i)) ;
+ y0(i) = ((x2(i)-x1(i)).*dy1(i).*dy2(i) + y1(i).*dx1(i).*dy2(i) - y2(i).*dx2(i).*dy1(i)) ./ ...
+ (dx1(i).*dy2(i)-dx2(i).*dy1(i)) ;
+ end
+
+ % concatenate result
+ point = [x0' y0'];
+
+endfunction
+
+%!test % basic test with two orthogonal lines
+%! line1 = [3 1 0 1];
+%! line2 = [1 4 1 0];
+%! assert (intersectLines(line1, line2), [3 4], 1e-6);
+
+%!test % orthognal diagonal lines
+%! line1 = [0 0 3 2];
+%! line2 = [5 -1 4 -6];
+%! assert (intersectLines(line1, line2), [3 2], 1e-6);
+
+%!test % one diagonal and one horizontal line
+%! line1 = [10 2 25 0];
+%! line2 = [5 -1 4 -6];
+%! assert (intersectLines(line1, line2), [3 2], 1e-6);
+
+%!test % check for dx and dy very big compared to other line
+%! line1 = [3 1 0 1000];
+%! line2 = [1 4 -14 0];
+%! assert (intersectLines(line1, line2), [3 4], 1e-6);
+
+%!test
+%! line1 = [2 0 20000 30000];
+%! line2 = [1 6 1 -1];
+%! assert (intersectLines(line1, line2), [4 3], 1e-6);
+
+%!test
+%! line1 = [3 1 0 1];
+%! line2 = repmat([1 4 1 0], 5, 1);
+%! res = repmat([3 4], 5, 1);
+%! inters = intersectLines(line1, line2);
+%! assert (res, inters, 1e-6);
+
+%!test
+%! line1 = repmat([3 1 0 1], 5, 1);
+%! line2 = [1 4 1 0];
+%! res = repmat([3 4], 5, 1);
+%! inters = intersectLines(line1, line2);
+%! assert (res, inters, 1e-6);
+
+%!test
+%! line1 = repmat([3 1 0 1], 5, 1);
+%! line2 = repmat([1 4 1 0], 5, 1);
+%! res = repmat([3 4], 5, 1);
+%! inters = intersectLines(line1, line2);
+%! assert (res, inters, 1e-6);
diff --git a/inst/geom2d/isCounterClockwise.m b/inst/geom2d/isCounterClockwise.m
new file mode 100644
index 0000000..44eeb77
--- /dev/null
+++ b/inst/geom2d/isCounterClockwise.m
@@ -0,0 +1,156 @@
+%% Copyright (c) 2011, INRA
+%% 2010-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} {@var{ccw} = } isCounterClockwise (@var{p1}, @var{p2}, @var{p3})
+%% @deftypefnx {Function File} {@var{ccw} = } isCounterClockwise (@var{p1}, @var{p2}, @var{p3},@var{tol})
+%% Compute relative orientation of 3 points
+%%
+%% Computes the orientation of the 3 points. The returns is:
+%% +1 if the path @var{p1}-> @var{p2}-> @var{p3} turns Counter-Clockwise (i.e., the point @var{p3}
+%% is located "on the left" of the line @var{p1}- @var{p2})
+%% -1 if the path turns Clockwise (i.e., the point @var{p3} lies "on the right"
+%% of the line @var{p1}- @var{p2})
+%% 0 if the point @var{p3} is located on the line segment [ @var{p1} @var{p2}].
+%%
+%% This function can be used in more complicated algorithms: detection of
+%% line segment intersections, convex hulls, point in triangle...
+%%
+%% @var{ccw} = isCounterClockwise( @var{p1}, @var{p2}, @var{p3}, EPS);
+%% Specifies the threshold used for detecting colinearity of the 3 points.
+%% Default value is 1e-12 (absolute).
+%%
+%% Example
+%%
+%% @example
+%% isCounterClockwise([0 0], [10 0], [10 10])
+%% ans =
+%% 1
+%% isCounterClockwise([0 0], [0 10], [10 10])
+%% ans =
+%% -1
+%% isCounterClockwise([0 0], [10 0], [5 0])
+%% ans =
+%% 0
+%% @end example
+%%
+%% @seealso{points2d, isPointOnLine, isPointInTriangle}
+%% @end deftypefn
+
+function res = isCounterClockwise(p1, p2, p3, varargin)
+
+ % get threshold value
+ eps = 1e-12;
+ if ~isempty(varargin)
+ eps = varargin{1};
+ end
+
+ % ensure all data have same size
+ np = max([size(p1, 1) size(p2, 1) size(p3,1)]);
+ if np > 1
+ if size(p1,1) == 1
+ p1 = repmat(p1, np, 1);
+ end
+ if size(p2,1) == 1
+ p2 = repmat(p2, np, 1);
+ end
+ if size(p3,1) == 1
+ p3 = repmat(p3, np, 1);
+ end
+ end
+
+ % init with 0
+ res = zeros(np, 1);
+
+ % extract vector coordinates
+ x0 = p1(:, 1);
+ y0 = p1(:, 2);
+ dx1 = p2(:, 1) - x0;
+ dy1 = p2(:, 2) - y0;
+ dx2 = p3(:, 1) - x0;
+ dy2 = p3(:, 2) - y0;
+
+ % check non colinear cases
+ res(dx1 .* dy2 > dy1 .* dx2) = 1;
+ res(dx1 .* dy2 < dy1 .* dx2) = -1;
+
+ % case of colinear points
+ ind = abs(dx1 .* dy2 - dy1 .* dx2) < eps;
+ res(ind( (dx1(ind) .* dx2(ind) < 0) | (dy1(ind) .* dy2(ind) < 0) )) = -1;
+ res(ind( hypot(dx1(ind), dy1(ind)) < hypot(dx2(ind), dy2(ind)) )) = 1;
+
+endfunction
+
+%!shared p0,pu,pd,pl,pr
+%! p0 = [2, 3]; % center point
+%! pu = [2, 4]; % up point
+%! pd = [2, 2]; % down point
+%! pl = [1, 3]; % left point
+%! pr = [3, 3]; % right point
+
+%!assert (+1, isCounterClockwise(pl, p0, pu));
+%!assert (+1, isCounterClockwise(pd, p0, pl));
+%!assert (+1, isCounterClockwise(pr, p0, pd));
+%!assert (+1, isCounterClockwise(pu, p0, pr));
+
+% turn 90° right => return -1
+%!assert (-1, isCounterClockwise(pl, p0, pd));
+%!assert (-1, isCounterClockwise(pd, p0, pr));
+%!assert (-1, isCounterClockwise(pr, p0, pu));
+%!assert (-1, isCounterClockwise(pu, p0, pl));
+
+%!test % turn 90° left => return +1
+%! pts1 = [pl;pd;pr;pu;pl;pd;pr;pu];
+%! pts2 = [p0;p0;p0;p0;p0;p0;p0;p0];
+%! pts3 = [pu;pl;pd;pr;pd;pr;pu;pl];
+%! expected = [1;1;1;1;-1;-1;-1;-1];
+%! result = isCounterClockwise(pts1, pts2, pts3);
+%! assert (result, expected, 1e-6);
+
+% aligned with p0-p1-p2 => return +1
+%!assert (+1, isCounterClockwise(pl, p0, pr));
+%!assert (+1, isCounterClockwise(pu, p0, pd));
+%!assert (+1, isCounterClockwise(pr, p0, pl));
+%!assert (+1, isCounterClockwise(pd, p0, pu));
+
+% aligned ]ith p0-p2-p1 => return 0
+%!assert (0, isCounterClockwise(pl, pr, p0));
+%!assert (0, isCounterClockwise(pu, pd, p0));
+%!assert (0, isCounterClockwise(pr, pl, p0));
+%!assert (0, isCounterClockwise(pd, pu, p0));
+
+% aligned with p1-p0-p2 => return -1
+%!assert (-1, isCounterClockwise(p0, pl, pr));
+%!assert (-1, isCounterClockwise(p0, pu, pd));
+%!assert (-1, isCounterClockwise(p0, pr, pl));
+%!assert (-1, isCounterClockwise(p0, pr, pl));
diff --git a/inst/geom2d/isLeftOriented.m b/inst/geom2d/isLeftOriented.m
new file mode 100644
index 0000000..9c85d9e
--- /dev/null
+++ b/inst/geom2d/isLeftOriented.m
@@ -0,0 +1,59 @@
+%% Copyright (c) 2011, INRA
+%% 2005-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} {@var{b} = } isLeftOriented (@var{point}, @var{line})
+%% Test if a point is on the left side of a line
+%%
+%% B = isLeftOriented(POINT, LINE);
+%% Returns TRUE if the point lies on the left side of the line with
+%% respect to the line direction.
+%%
+%% @seealso{lines2d, points2d, isCounterClockwise, isPointOnLine, distancePointLine}
+%% @end deftypefn
+
+function b = isLeftOriented(point, line)
+ Nl = size(line, 1);
+ Np = size(point, 1);
+
+ x0 = repmat(line(:,1)', Np, 1);
+ y0 = repmat(line(:,2)', Np, 1);
+ dx = repmat(line(:,3)', Np, 1);
+ dy = repmat(line(:,4)', Np, 1);
+ xp = repmat(point(:,1), 1, Nl);
+ yp = repmat(point(:,2), 1, Nl);
+
+
+ b = (xp-x0).*dy-(yp-y0).*dx < 0;
+
+endfunction
diff --git a/inst/geom2d/isParallel.m b/inst/geom2d/isParallel.m
new file mode 100644
index 0000000..d3334db
--- /dev/null
+++ b/inst/geom2d/isParallel.m
@@ -0,0 +1,97 @@
+%% Copyright (c) 2011, INRA
+%% 2006-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} {@var{b} = } isParallel (@var{v1}, @var{v2})
+%% @deftypefnx {Function File} {@var{b} = } isParallel (@var{v1}, @var{v2},@var{tol})
+%% Check parallelism of two vectors
+%%
+%% @var{v1} and @var{v2} are 2 row vectors of length Nd, Nd being the dimension,
+%% returns @code{true} if the vectors are parallel, and @code{false} otherwise.
+%%
+%% Also works when @var{v1} and @var{v2} are two [NxNd] arrays with same number of
+%% rows. In this case, return a [Nx1] array containing @code{true} at the positions
+%% of parallel vectors.
+%%
+%% @var{tol} specifies the accuracy of numerical computation. Default value is 1e-14.
+%%
+%% Example
+%%
+%% @example
+%% isParallel([1 2], [2 4])
+%% ans =
+%% 1
+%% isParallel([1 2], [1 3])
+%% ans =
+%% 0
+%% @end example
+%%
+%% @seealso{vectors2d, isPerpendicular, lines2d}
+%% @end deftypefn
+
+%% FIXME or erase me
+%% Also works when one of @var{v1} or @var{v2} is scalar and the other one is [NxNd]
+%% array, in this case return [Nx1] results.
+
+function b = isParallel(v1, v2, varargin)
+
+ % default accuracy
+ acc = 1e-14;
+ if ~isempty(varargin)
+ acc = abs(varargin{1});
+ end
+
+ % adapt size of inputs if needed
+ n1 = size(v1, 1);
+ n2 = size(v2, 1);
+ if n1 ~= n2
+ if n1 == 1
+ v1 = v1(ones(n2,1), :);
+ elseif n2 == 1
+ v2 = v2(ones(n1,1), :);
+ end
+ end
+
+ % performs computation
+ if size(v1, 2) == 2
+ b = abs(v1(:, 1) .* v2(:, 2) - v1(:, 2) .* v2(:, 1)) < acc;
+ else
+ % computation in space
+ b = vectorNorm(cross(v1, v2, 2)) < acc;
+ end
+
+endfunction
+
+%!assert (isParallel ([1 2], [2 4]))
+%!assert (!isParallel ([1 2], [1 3]))
+%!error (isParallel (3, rand(4,2)))
diff --git a/inst/geom2d/isPerpendicular.m b/inst/geom2d/isPerpendicular.m
new file mode 100644
index 0000000..cdf5567
--- /dev/null
+++ b/inst/geom2d/isPerpendicular.m
@@ -0,0 +1,95 @@
+%% Copyright (c) 2011, INRA
+%% 2006-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} {@var{b} = } isPerpendicular (@var{v1}, @var{v2})
+%% @deftypefnx {Function File} {@var{b} = } isPerpendicula (@var{v1}, @var{v2},@var{tol})
+%% heck orthogonality of two vectors.
+%%
+%% @var{v1} and @var{v2} are 2 row vectors of length Nd, Nd being the dimension,
+%% returns @code{true} if the vectors are perpendicular, and @code{false} otherwise.
+%%
+%% Also works when @var{v1} and @var{v2} are two [NxNd] arrays with same number of
+%% rows. In this case, return a [Nx1] array containing @code{true} at the positions
+%% of parallel vectors.
+%%
+%% @var{tol} specifies the accuracy of numerical computation. Default value is 1e-14.
+%%
+%% Example
+%%
+%% @example
+% isPerpendicular([1 2 0], [0 0 2])
+%% ans =
+%% 1
+% isPerpendicular([1 2 1], [1 3 2])
+%% ans =
+%% 0
+%% @end example
+%%
+%% @seealso{vectors2d, isParallel, lines2d}
+%% @end deftypefn
+
+%% FIXME or erase me
+%% Also works when one of @var{v1} or @var{v2} is scalar and the other one is [NxNd]
+%% array, in this case return [Nx1] results.
+
+function b = isPerpendicular(v1, v2, varargin)
+
+ % default accuracy
+ acc = 1e-14;
+ if ~isempty(varargin)
+ acc = abs(varargin{1});
+ end
+
+ % adapt size of inputs
+ n1 = size(v1, 1);
+ n2 = size(v2, 1);
+ if n1~=n2
+ if n1==1
+ v1 = v1(ones(n2, 1), :);
+ elseif n2==1
+ v2 = v2(ones(n1, 1), :);
+ else
+ error('Inputs must either have same size, or one must be scalar');
+ end
+ end
+
+ % performs test
+ b = abs(dot(v1, v2, 2)) < acc;
+
+endfunction
+
+%!assert (isPerpendicular ([1 2 0], [0 0 2]))
+%!assert (!isPerpendicular([1 2 1], [1 3 2]))
+%!error (isPerpendicular(1, rand(4,3)))
+
diff --git a/inst/geom2d/isPointInCircle.m b/inst/geom2d/isPointInCircle.m
new file mode 100644
index 0000000..eeafd0b
--- /dev/null
+++ b/inst/geom2d/isPointInCircle.m
@@ -0,0 +1,67 @@
+%% Copyright (c) 2011, INRA
+%% 2004-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} {@var{b} = } isPointInCircle (@var{point}, @var{circle})
+%% Test if a point is located inside a given circle
+%%
+%% B = isPointInCircle(POINT, CIRCLE)
+%% Returns true if point is located inside the circle, i.e. if distance to
+%% circle center is lower than the circle radius.
+%%
+%% B = isPointInCircle(POINT, CIRCLE, TOL)
+%% Specifies the tolerance value
+%%
+%% Example:
+%% isPointInCircle([1 0], [0 0 1])
+%% isPointInCircle([0 0], [0 0 1])
+%% returns true, whereas
+%% isPointInCircle([1 1], [0 0 1])
+%% return false
+%%
+%% @seealso{circles2d, isPointOnCircle}
+%% @end deftypefn
+
+function b = isPointInCircle(point, circle, varargin)
+
+ % extract computation tolerance
+ tol = 1e-14;
+ if ~isempty(varargin)
+ tol = varargin{1};
+ end
+
+ d = sqrt(sum(power(point - circle(:,1:2), 2), 2));
+ b = d-circle(:,3)<=tol;
+
+endfunction
+
diff --git a/inst/geom2d/isPointInEllipse.m b/inst/geom2d/isPointInEllipse.m
new file mode 100644
index 0000000..f69fc68
--- /dev/null
+++ b/inst/geom2d/isPointInEllipse.m
@@ -0,0 +1,81 @@
+%% Copyright (c) 2011, INRA
+%% 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} {@var{b} = } isPointInellipse (@var{point}, @var{ellipse})
+%% Check if a point is located inside a given ellipse
+%%
+%% B = isPointInEllipse(POINT, ELLIPSE)
+%% Returns true if point is located inside the given ellipse.
+%%
+%% B = isPointInEllipse(POINT, ELLIPSE, TOL)
+%% Specifies the tolerance value
+%%
+%% Example:
+%% isPointInEllipse([1 0], [0 0 2 1 0])
+%% ans =
+%% 1
+%% isPointInEllipse([0 0], [0 0 2 1 0])
+%% ans =
+%% 1
+%% isPointInEllipse([1 1], [0 0 2 1 0])
+%% ans =
+%% 0
+%% isPointInEllipse([1 1], [0 0 2 1 30])
+%% ans =
+%% 1
+%%
+%% @seealso{ellipses2d, isPointInCircle}
+%% @end deftypefn
+
+function b = isPointInEllipse(point, ellipse, varargin)
+
+ % extract computation tolerance
+ tol = 1e-14;
+ if ~isempty(varargin)
+ tol = varargin{1};
+ end
+
+ % compute ellipse to unit circle transform
+ rot = createRotation(-deg2rad(ellipse(5)));
+ sca = createScaling(1./ellipse(3:4));
+ trans = sca * rot;
+
+ % transform points to unit circle basis
+ pTrans = bsxfun(@minus, point, ellipse(:,1:2));
+ pTrans = transformPoint(pTrans, trans);
+
+ % test if distance to origin smaller than 1
+ b = sqrt(sum(power(pTrans, 2), 2)) - 1 <= tol;
+
+endfunction
diff --git a/inst/geom2d/isPointOnCircle.m b/inst/geom2d/isPointOnCircle.m
new file mode 100644
index 0000000..b8679b2
--- /dev/null
+++ b/inst/geom2d/isPointOnCircle.m
@@ -0,0 +1,65 @@
+%% Copyright (c) 2011, INRA
+%% 2003-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} {@var{b} = } isPointOnCircle (@var{point}, @var{circle})
+%% Test if a point is located on a given circle.
+%%
+%% B = isPointOnCircle(POINT, CIRCLE)
+%% return true if point is located on the circle, i.e. if the distance to
+%% the circle center equals the radius up to an epsilon value.
+%%
+%% B = isPointOnCircle(POINT, CIRCLE, TOL)
+%% Specifies the tolerance value.
+%%
+%% Example:
+%% isPointOnCircle([1 0], [0 0 1])
+%% returns true, whereas
+%% isPointOnCircle([1 1], [0 0 1])
+%% return false
+%%
+%% @seealso{circles2d, isPointInCircle}
+%% @end deftypefn
+
+function b = isPointOnCircle(point, circle, varargin)
+
+ tol = 1e-14;
+ if ~isempty(varargin)
+ tol = varargin{1};
+ end
+
+ d = sqrt(sum(power(point - circle(:,1:2), 2), 2));
+ b = abs(d-circle(:,3))<tol;
+
+endfunction
+
diff --git a/inst/geom2d/isPointOnEdge.m b/inst/geom2d/isPointOnEdge.m
new file mode 100644
index 0000000..eb2d3da
--- /dev/null
+++ b/inst/geom2d/isPointOnEdge.m
@@ -0,0 +1,294 @@
+%% Copyright (c) 2011, INRA
+%% 2003-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} {@var{b} = } isPointOnEdge (@var{point}, @var{edge})
+%% @deftypefnx {Function File} {@var{b} = } isPointOnEdge (@var{point}, @var{edge}, @var{tol})
+%% @deftypefnx {Function File} {@var{b} = } isPointOnEdge (@var{point}, @var{edgearray})
+%% @deftypefnx {Function File} {@var{b} = } isPointOnEdge (@var{pointarray}, @var{edgearray})
+%% Test if a point belongs to an edge.
+%
+% with @var{point} being [xp yp], and @var{edge} being [x1 y1 x2 y2], returns TRUE if
+% the point is located on the edge, and FALSE otherwise.
+%
+% Specify an optilonal tolerance value @var{tol}. The tolerance is given as a
+% fraction of the norm of the edge direction vector. Default is 1e-14.
+%
+% When one of the inputs has several rows, return the result of the test
+% for each element of the array tested against the single parameter.
+%
+% When both @var{pointarray} and @var{edgearray} have the same number of rows,
+% returns a column vector with the same number of rows.
+% When the number of rows are different and both greater than 1, returns
+% a Np-by-Ne matrix of booleans, containing the result for each couple of
+% point and edge.
+%
+% @seealso{edges2d, points2d, isPointOnLine}
+%% @end deftypefn
+
+function b = isPointOnEdge(point, edge, varargin)
+
+ % extract computation tolerance
+ tol = 1e-14;
+ if ~isempty(varargin)
+ tol = varargin{1};
+ end
+
+ % number of edges and of points
+ Np = size(point, 1);
+ Ne = size(edge, 1);
+
+ % adapt size of inputs if needed, and extract elements for computation
+ if Np == Ne
+ % When the number of points and edges is the same, the one-to-one test
+ % will be computed, so there is no need to repeat matrices
+ dx = edge(:,3) - edge(:,1);
+ dy = edge(:,4) - edge(:,2);
+ lx = point(:,1) - edge(:,1);
+ ly = point(:,2) - edge(:,2);
+
+ elseif Np == 1
+ % one point, several edges
+ dx = edge(:, 3) - edge(:, 1);
+ dy = edge(:, 4) - edge(:, 2);
+ lx = point(ones(Ne, 1), 1) - edge(:, 1);
+ ly = point(ones(Ne, 1), 2) - edge(:, 2);
+
+ elseif Ne == 1
+ % several points, one edge
+ dx = (edge(3) - edge(1)) * ones(Np, 1);
+ dy = (edge(4) - edge(2)) * ones(Np, 1);
+ lx = point(:, 1) - edge(1);
+ ly = point(:, 2) - edge(2);
+
+ else
+ % Np points and Ne edges:
+ % Create an array for each parameter, so that the result will be a
+ % Np-by-Ne matrix of booleans (requires more memory, and uses repmat)
+
+ x0 = repmat(edge(:, 1)', Np, 1);
+ y0 = repmat(edge(:, 2)', Np, 1);
+ dx = repmat(edge(:,3)', Np, 1) - x0;
+ dy = repmat(edge(:,4)', Np, 1) - y0;
+
+ lx = repmat(point(:, 1), 1, Ne) - x0;
+ ly = repmat(point(:, 2), 1, Ne) - y0;
+ end
+
+ % test if point is located on supporting line
+ b1 = (abs(lx.*dy - ly.*dx) ./ hypot(dx, dy)) < tol;
+
+ % compute position of point with respect to edge bounds
+ % use different tests depending on line angle
+ ind = abs(dx) > abs(dy);
+ t = zeros(size(dx));
+ t(ind) = lx( ind) ./ dx( ind);
+ t(~ind) = ly(~ind) ./ dy(~ind);
+
+ % check if point is located between edge bounds
+ b = t >- tol & t-1 < tol & b1;
+
+endfunction
+
+%!shared points, vertices, edges
+
+%!demo
+%! % create a point array
+%! points = [10 10;15 10; 30 10];
+%! % create an edge array
+%! vertices = [10 10;20 10;20 20;10 20];
+%! edges = [vertices vertices([2:end 1], :)];
+%!
+%! % Test one point and one edge
+%! isPointOnEdge(points(1,:), edges(1,:))
+%! isPointOnEdge(points(3,:), edges(1,:))
+
+%!demo
+%! % create a point array
+%! points = [10 10;15 10; 30 10];
+%! % create an edge array
+%! vertices = [10 10;20 10;20 20;10 20];
+%! edges = [vertices vertices([2:end 1], :)];
+%!
+%! % Test one point and several edges
+%! isPointOnEdge(points(1,:), edges)'
+
+%!demo
+%! % create a point array
+%! points = [10 10;15 10; 30 10];
+%! % create an edge array
+%! vertices = [10 10;20 10;20 20;10 20];
+%! edges = [vertices vertices([2:end 1], :)];
+%!
+%! % Test several points and one edge
+%! isPointOnEdge(points, edges(1,:))'
+
+%!demo
+%! % create a point array
+%! points = [10 10;15 10; 30 10];
+%! % create an edge array
+%! vertices = [10 10;20 10;20 20;10 20];
+%! edges = [vertices vertices([2:end 1], :)];
+%!
+%! % Test N points and N edges
+%! isPointOnEdge(points, edges(1:3,:))'
+
+%!demo
+%! % create a point array
+%! points = [10 10;15 10; 30 10];
+%! % create an edge array
+%! vertices = [10 10;20 10;20 20;10 20];
+%! edges = [vertices vertices([2:end 1], :)];
+%!
+%! % Test NP points and NE edges
+%! isPointOnEdge(points, edges)
+
+%!test
+%! p1 = [10 20];
+%! p2 = [80 20];
+%! edge = [p1 p2];
+%! p0 = [10 20];
+%! assert (isPointOnEdge(p0, edge));
+%! p0 = [80 20];
+%! assert (isPointOnEdge(p0, edge));
+%! p0 = [50 20];
+%! assert (isPointOnEdge(p0, edge));
+%! p0 = [9.99 20];
+%! assert (!isPointOnEdge(p0, edge));
+%! p0 = [80.01 20];
+%! assert (!isPointOnEdge(p0, edge));
+%! p0 = [50 21];
+%! assert (!isPointOnEdge(p0, edge));
+%! p0 = [79 19];
+%! assert (!isPointOnEdge(p0, edge));
+
+%!test
+%! p1 = [20 10];
+%! p2 = [20 80];
+%! edge = [p1 p2];
+%! p0 = [20 10];
+%! assert (isPointOnEdge(p0, edge));
+%! p0 = [20 80];
+%! assert (isPointOnEdge(p0, edge));
+%! p0 = [20 50];
+%! assert (isPointOnEdge(p0, edge));
+%! p0 = [20 9.99];
+%! assert (!isPointOnEdge(p0, edge));
+%! p0 = [20 80.01];
+%! assert (!isPointOnEdge(p0, edge));
+%! p0 = [21 50];
+%! assert (!isPointOnEdge(p0, edge));
+%! p0 = [19 79];
+%! assert (!isPointOnEdge(p0, edge));
+
+%!test
+%! p1 = [10 20];
+%! p2 = [60 70];
+%! edge = [p1 p2];
+%! assert (isPointOnEdge(p1, edge));
+%! assert (isPointOnEdge(p2, edge));
+%! p0 = [11 21];
+%! assert (isPointOnEdge(p0, edge));
+%! p0 = [59 69];
+%! assert (isPointOnEdge(p0, edge));
+%! p0 = [9.99 19.99];
+%! assert (!isPointOnEdge(p0, edge));
+%! p0 = [60.01 70.01];
+%! assert (!isPointOnEdge(p0, edge));
+%! p0 = [30 50.01];
+%! assert (!isPointOnEdge(p0, edge));
+
+%!test
+%! edge = [10 20 80 20; 20 10 20 80; 20 10 60 70];
+%! p0 = [20 20];
+%! assert ([true ; true ; false], isPointOnEdge(p0, edge));
+
+%!test
+%! k = 1e15;
+%! p1 = [10 20]*k;
+%! p2 = [60 70]*k;
+%! edge = [p1 p2];
+%! assert (isPointOnEdge(p1, edge));
+%! assert (isPointOnEdge(p2, edge));
+%! p0 = [11 21]*k;
+%! assert (isPointOnEdge(p0, edge));
+%! p0 = [59 69]*k;
+%! assert (isPointOnEdge(p0, edge));
+%! p0 = [9.99 19.99]*k;
+%! assert (!isPointOnEdge(p0, edge));
+%! p0 = [60.01 70.01]*k;
+%! assert (!isPointOnEdge(p0, edge));
+%! p0 = [30 50.01]*k;
+%! assert (!isPointOnEdge(p0, edge));
+
+%!test
+%! k = 1e-10;
+%! p1 = [10 20]*k;
+%! p2 = [60 70]*k;
+%! edge = [p1 p2];
+%! assert (isPointOnEdge(p1, edge));
+%! assert (isPointOnEdge(p2, edge));
+%! p0 = [11 21]*k;
+%! assert (isPointOnEdge(p0, edge));
+%! p0 = [59 69]*k;
+%! assert (isPointOnEdge(p0, edge));
+%! p0 = [9.99 19.99]*k;
+%! assert (!isPointOnEdge(p0, edge));
+%! p0 = [60.01 70.01]*k;
+%! assert (!isPointOnEdge(p0, edge));
+%! p0 = [30 50.01]*k;
+%! assert (!isPointOnEdge(p0, edge));
+
+%!test
+%! p1 = [10 20];
+%! p2 = [80 20];
+%! edge = [p1 p2];
+%! p0 = [10 20; 80 20; 50 20;50 21];
+%! exp = [true;true;true;false];
+%! assert (exp, isPointOnEdge(p0, edge));
+
+%!test
+%! p1 = [10 20];
+%! p2 = [80 20];
+%! edge = [p1 p2];
+%! p0 = [40 20];
+%! exp = [true;true;true;true];
+%! assert (exp, isPointOnEdge(p0, [edge;edge;edge;edge]));
+
+%!test
+%! edge1 = [10 20 80 20];
+%! edge2 = [30 10 30 80];
+%! edges = [edge1; edge2];
+%! p0 = [40 20;30 90];
+%! exp = [true;false];
+%! assert (exp, isPointOnEdge(p0, edges));
diff --git a/inst/geom2d/isPointOnLine.m b/inst/geom2d/isPointOnLine.m
new file mode 100644
index 0000000..effcca1
--- /dev/null
+++ b/inst/geom2d/isPointOnLine.m
@@ -0,0 +1,72 @@
+%% Copyright (c) 2011, INRA
+%% 2003-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} {@var{b} = } isPointOnLine (@var{point}, @var{line})
+%% Test if a point belongs to a line
+%%
+%% B = isPointOnLine(POINT, LINE)
+%% with POINT being [xp yp], and LINE being [x0 y0 dx dy].
+%% Returns 1 if point lies on the line, 0 otherwise.
+%%
+%% If POINT is an N*2 array of points, B is a N*1 array of booleans.
+%%
+%% If LINE is a N*4 array of line, B is a 1*N array of booleans.
+%%
+%% @seealso {lines2d, points2d, isPointOnEdge, isPointOnRay, angle3Points}
+%% @end deftypefn
+
+function b = isPointOnLine(point, line, varargin)
+
+ % extract computation tolerance
+ tol = 1e-14;
+ if ~isempty(varargin)
+ tol = varargin{1};
+ end
+
+ % number of lines and of points
+ Nl = size(line, 1);
+ Np = size(point, 1);
+
+ % adapt the size of inputs
+ x0 = repmat(line(:,1)', Np, 1);
+ y0 = repmat(line(:,2)', Np, 1);
+ dx = repmat(line(:,3)', Np, 1);
+ dy = repmat(line(:,4)', Np, 1);
+ xp = repmat(point(:,1), 1, Nl);
+ yp = repmat(point(:,2), 1, Nl);
+
+ % test if lines are colinear
+ b = abs((xp-x0).*dy-(yp-y0).*dx)./hypot(dx, dy) < tol;
+
+endfunction
diff --git a/inst/geom2d/isPointOnRay.m b/inst/geom2d/isPointOnRay.m
new file mode 100644
index 0000000..1d69310
--- /dev/null
+++ b/inst/geom2d/isPointOnRay.m
@@ -0,0 +1,94 @@
+%% 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} {@var{b} = } isPointOnRay (@var{point}, @var{ray})
+%% @deftypefnx {Function File} {@var{b} = } isPointOnRay (@var{point}, @var{ray}, @var{tol})
+%% Test if a point belongs to a ray
+%%
+%% @var{b} = isPointOnRay(@var{point}, @var{ray});
+%% Returns @code{true} if point @var{point} belongs to the ray @var{ray}.
+%% @var{point} is given by [x y] and RAY by [x0 y0 dx dy]. @var{tol} gives the
+%% tolerance for the calculations.
+%%
+%% @seealso{rays2d, points2d, isPointOnLine}
+%% @end deftypefn
+
+function b = isPointOnRay(point, ray, varargin)
+
+ % extract computation tolerance
+ tol = 1e-14;
+ if ~isempty(varargin)
+ tol = varargin{1};
+ end
+
+ % number of rays and points
+ Nr = size(ray, 1);
+ Np = size(point, 1);
+
+ % if several rays or several points, adapt sizes of arrays
+ x0 = repmat(ray(:,1)', Np, 1);
+ y0 = repmat(ray(:,2)', Np, 1);
+ dx = repmat(ray(:,3)', Np, 1);
+ dy = repmat(ray(:,4)', Np, 1);
+ xp = repmat(point(:,1), 1, Nr);
+ yp = repmat(point(:,2), 1, Nr);
+
+ % test if points belongs to the supporting line
+ b1 = abs ( (xp-x0).*dy - (yp-y0).*dx ) ./ hypot(dx, dy) < tol;
+
+ % check if points lie the good direction on the rays
+ ind = abs (dx) > abs (dy);
+ t = zeros (size (b1));
+ t(ind) = (xp(ind)-x0(ind))./dx(ind);
+ t(~ind) = (yp(~ind)-y0(~ind))./dy(~ind);
+
+ % combine the two tests
+ b = b1 & (t >= 0);
+
+endfunction
+
+%!shared ray
+%! p1 = [10 20];
+%! p2 = [80 20];
+%! ray = createRay (p1, p2);
+
+%!assert (isPointOnRay([10 20], ray));
+%!assert (isPointOnRay([80 20], ray));
+%!assert (isPointOnRay([50 20], ray));
+%!assert (isPointOnRay([50 20+1e-3], ray,1e-2));
+%!assert ( !isPointOnRay([50 20+1e-3], ray,1e-4));
+%!assert ( !isPointOnRay([9.99 20], ray));
+%!assert ( !isPointOnRay([80 20.01], ray));
+%!assert ( !isPointOnRay([50 21], ray));
+%!assert ( !isPointOnRay([79 19], ray));
diff --git a/inst/geom2d/lineAngle.m b/inst/geom2d/lineAngle.m
new file mode 100644
index 0000000..edc37b0
--- /dev/null
+++ b/inst/geom2d/lineAngle.m
@@ -0,0 +1,105 @@
+%% Copyright (c) 2011, INRA
+%% 2003-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} {@var{theta} =} lineAngle(varargin)
+%% Computes angle between two straight lines
+%%
+%% A = lineAngle(LINE);
+%% Returns the angle between horizontal, right-axis and the given line.
+%% Angle is fiven in radians, between 0 and 2*pi, in counter-clockwise
+%% direction.
+%%
+%% A = lineAngle(LINE1, LINE2);
+%% Returns the directed angle between the two lines. Angle is given in
+%% radians between 0 and 2*pi, in counter-clockwise direction.
+%%
+%% @seealso{lines2d, angles2d, createLine, normalizeAngle}
+%% @end deftypefn
+
+function theta = lineAngle(varargin)
+
+ nargs = length(varargin);
+ if nargs == 1
+ % angle of one line with horizontal
+ line = varargin{1};
+ theta = mod(atan2(line(:,4), line(:,3)) + 2*pi, 2*pi);
+
+ elseif nargs==2
+ % angle between two lines
+ theta1 = lineAngle(varargin{1});
+ theta2 = lineAngle(varargin{2});
+ theta = mod(bsxfun(@minus, theta2, theta1)+2*pi, 2*pi);
+ end
+
+endfunction
+
+% horizontal
+%!test
+%! line1 = createLine([2 3 1 0]);
+%! assert (lineAngle(line1), 0, 1e-6);
+
+%!test
+%! line1 = createLine([2 3 0 1]);
+%! assert (lineAngle(line1), pi/2, 1e-6);
+
+%!test
+%! line1 = createLine([2 3 1 1]);
+%! assert (lineAngle(line1), pi/4, 1e-6);
+
+%!test
+%! line1 = createLine([2 3 5 -1]);
+%! assert (lineAngle(line1), mod(atan2(-1, 5)+2*pi, 2*pi), 1e-6);
+
+%!test
+%! line1 = createLine([2 3 5000 -1000]);
+%! assert (lineAngle(line1), mod(atan2(-1, 5)+2*pi, 2*pi), 1e-6);
+
+%!test
+%! line1 = createLine([2 3 -1 0]);
+%! assert (lineAngle(line1), pi, 1e-6);
+
+% test lineAngle with two parameters : angle between 2 lines
+% check for 2 orthogonal lines
+%!test
+%! line1 = createLine([1 3 1 0]);
+%! line2 = createLine([-2 -1 0 1]);
+%! assert (lineAngle(line1, line2), pi/2, 1e-6);
+%! assert (lineAngle(line2, line1), 3*pi/2, 1e-6);
+
+% check for 2 orthogonal lines, with very different parametrizations
+%!test
+%! line1 = createLine([1 3 1 1]);
+%! line2 = createLine([-2 -1 -1000 1000]);
+%! assert (lineAngle(line1, line2), pi/2, 1e-6);
+%! assert (lineAngle(line2, line1), 3*pi/2, 1e-6);
diff --git a/inst/geom2d/linePosition.m b/inst/geom2d/linePosition.m
new file mode 100644
index 0000000..bd7c242
--- /dev/null
+++ b/inst/geom2d/linePosition.m
@@ -0,0 +1,139 @@
+%% Copyright (c) 2011, INRA
+%% 2004-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 PUR@var{pos}E
+%% 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
+%% @var{pos}SIBILITY 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} {@var{pos} =} linePosition (@var{point}, @var{line})
+%% Position of a point on a line.
+%%
+%% Computes position of point @var{point} on the line @var{line}, relative to origin
+%% point and direction vector of the line.
+%% @var{line} has the form [x0 y0 dx dy],
+%% @var{point} has the form [x y], and is assumed to belong to line.
+%%
+%% If @var{line} is an array of NL lines, return NL positions, corresponding to
+%% each line.
+%%
+%% If @var{point} is an array of NP points, return NP positions, corresponding
+%% to each point.
+%%
+%% If @var{point} is an array of NP points and @var{line}S is an array of NL lines,
+%% return an array of [NP NL] position, corresponding to each couple
+%% point-line.
+%%
+%% Example
+%%
+%% @example
+%% line = createLine([10 30], [30 90]);
+%% linePosition([20 60], line)
+%% ans =
+%% .5
+%% @end example
+%%
+%% @seealso{lines2d, createLine, projPointOnLine, isPointOnLine}
+%% @end deftypefn
+
+function d = linePosition(point, lin)
+
+ % number of inputs
+ Nl = size(lin, 1);
+ Np = size(point, 1);
+
+ if Np == Nl
+ % if both inputs have the same size, no problem
+ dxl = lin(:, 3);
+ dyl = lin(:, 4);
+ dxp = point(:, 1) - lin(:, 1);
+ dyp = point(:, 2) - lin(:, 2);
+
+ elseif Np == 1
+ % one point, several lines
+ dxl = lin(:, 3);
+ dyl = lin(:, 4);
+ dxp = point(ones(Nl, 1), 1) - lin(:, 1);
+ dyp = point(ones(Nl, 1), 2) - lin(:, 2);
+
+ elseif Nl == 1
+ % one lin, several points
+ dxl = lin(ones(Np, 1), 3);
+ dyl = lin(ones(Np, 1), 4);
+ dxp = point(:, 1) - lin(1);
+ dyp = point(:, 2) - lin(2);
+
+ else
+ % expand one of the array to have the same size
+ dxl = repmat(lin(:,3)', Np, 1);
+ dyl = repmat(lin(:,4)', Np, 1);
+ dxp = repmat(point(:,1), 1, Nl) - repmat(lin(:,1)', Np, 1);
+ dyp = repmat(point(:,2), 1, Nl) - repmat(lin(:,2)', Np, 1);
+ end
+
+ % compute position
+ d = (dxp.*dxl + dyp.*dyl) ./ (dxl.^2 + dyl.^2);
+
+endfunction
+
+%!demo
+%! point = [20 60;10 30;25 75];
+%! lin = createLine([10 30], [30 90]);
+%! pos = linePosition(point, lin)
+%!
+%! plot(point(:,1),point(:,2),'ok');
+%! hold on
+%! drawLine(lin,'color','r');
+%! plot(lin(1)+lin(3)*pos,lin(2)+lin(4)*pos,'xb')
+%! hold off
+
+%!test
+%! point = [20 60];
+%! lin = createLine([10 30], [30 90]);
+%! res = .5;
+%! pos = linePosition(point, lin);
+%! assert (res, pos);
+
+%!test
+%! point = [20 60;10 30;25 75];
+%! lin = createLine([10 30], [30 90]);
+%! res = [.5; 0; .75];
+%! pos = linePosition(point, lin);
+%! assert (res, pos);
+
+%!test
+%! point = [20 60];
+%! lin1 = createLine([10 30], [30 90]);
+%! lin2 = createLine([0 0], [20 60]);
+%! lin3 = createLine([20 60], [40 120]);
+%! lines = [lin1;lin2;lin3];
+%! res = [.5; 1; 0];
+%! pos = linePosition(point, lines);
+%! assert (res, pos);
+
diff --git a/inst/geom2d/lines2d.m b/inst/geom2d/lines2d.m
new file mode 100644
index 0000000..696b87a
--- /dev/null
+++ b/inst/geom2d/lines2d.m
@@ -0,0 +1,66 @@
+%% 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} lines2d ()
+%% Description of functions operating on planar lines.
+%
+% The term 'line' refers to a planar straight line, which is an unbounded
+% curve. Line segments defined between 2 points, which are bounded, are
+% called 'edge', and are presented in file 'edges2d'.
+%
+% A straight line is defined by a point (its origin), and a vector (its
+% direction). The different parameters are bundled into a row vector:
+% LINE = [x0 y0 dx dy];
+%
+% A line contains all points (x,y) such that:
+% x = x0 + t*dx
+% y = y0 + t*dy;
+% for all t between -infinity and +infinity.
+%
+% @seealso{points2d, vectors2d, edges2d, rays2d
+% createLine, cartesianLine, medianLine, edgeToLine
+% orthogonalLine, parallelLine, bisector, radicalAxis
+% lineAngle, linePosition, projPointOnLine
+% isPointOnLine, distancePointLine, isLeftOriented
+% intersectLines, intersectLineEdge, clipLine
+% invertLine, transformLine, drawLine
+% lineFit}
+%% @end deftypefn
+
+function lines2d(varargin)
+
+ help('lines2d');
+
+endfunction
+
diff --git a/inst/geom2d/medianLine.m b/inst/geom2d/medianLine.m
new file mode 100644
index 0000000..3f99c73
--- /dev/null
+++ b/inst/geom2d/medianLine.m
@@ -0,0 +1,137 @@
+%% Copyright (c) 2011, INRA
+%% 2003-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} {@var{line} = } medianLine (@var{p1}, @var{p2})
+%% @deftypefnx {Function File} {@var{line} = } medianLine (@var{pts})
+%% @deftypefnx {Function File} {@var{line} = } medianLine (@var{edge})
+%% Create a median line between two points.
+%%
+%% Create the median line of points @var{p1} and @var{p2}, that is the line containing
+%% all points located at equal distance of @var{p1} and @var{p2}.
+%%
+%% Creates the median line of 2 points, given as a 2*2 array @var{pts}. Array has
+%% the form:
+%% [ [ x1 y1 ] ; [ x2 y2 ] ]
+%%
+%% 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
+%% % Draw the median line of two points
+%% P1 = [10 20];
+%% P2 = [30 50];
+%% med = medianLine(P1, P2);
+%% figure; axis square; axis([0 100 0 100]);
+%% drawEdge([P1 P2], 'linewidth', 2, 'color', 'k');
+%% drawLine(med)
+%%
+%% % Draw the median line of an edge
+%% P1 = [50 60];
+%% P2 = [80 30];
+%% edge = createEdge(P1, P2);
+%% figure; axis square; axis([0 100 0 100]);
+%% drawEdge(edge, 'linewidth', 2)
+%% med = medianLine(edge);
+%% drawLine(med)
+%% @end example
+%%
+%% @seealso{lines2d, createLine, orthogonalLine}
+%% @end deftypefn
+
+function lin = medianLine(varargin)
+
+ nargs = length(varargin);
+ x0 = 0;
+ y0 = 0;
+ dx = 0;
+ dy = 0;
+
+ if nargs == 1
+ tab = varargin{1};
+ if size(tab, 2)==2
+ % input is an array of two points
+ x0 = tab(1,1);
+ y0 = tab(1,2);
+ dx = tab(2,1)-x0;
+ dy = tab(2,2)-y0;
+ else
+ % input is an edge
+ x0 = tab(:, 1);
+ y0 = tab(:, 2);
+ 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);
+ y0 = p1(:, 2);
+ dx = bsxfun(@minus, p2(:, 1), x0);
+ dy = bsxfun(@minus, p2(:, 2), y0);
+
+ else
+ error('Too many input arguments');
+ end
+
+ % compute median using middle point of the edge, and the direction vector
+ % rotated by 90 degrees counter-clockwise
+ lin = [bsxfun(@plus, x0, dx/2), bsxfun(@plus, y0, dy/2), -dy, dx];
+
+endfunction
+
+%!test
+%! p1 = [0 0];
+%! p2 = [10 0];
+%! exp = [5 0 0 10];
+%! lin = medianLine(p1, p2);
+%! assertElementsAlmostEqual(exp, lin);
+
+%!test
+%! p1 = [0 0];
+%! p2 = [10 0];
+%! exp = [5 0 0 10];
+%! lin = medianLine([p1 p2]);
+%! assertElementsAlmostEqual(exp, lin);
+
+%!test
+%! 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);
diff --git a/inst/geom2d/mergeBoxes.m b/inst/geom2d/mergeBoxes.m
new file mode 100644
index 0000000..a6dede6
--- /dev/null
+++ b/inst/geom2d/mergeBoxes.m
@@ -0,0 +1,77 @@
+%% Copyright (c) 2011, INRA
+%% 2010-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} {@var{box} =} mergeBoxes (@var{box1}, @var{box2})
+%% Merge two boxes, by computing their greatest extent.
+%%
+% Example
+%%
+%% @example
+%% box1 = [5 20 5 30];
+%% box2 = [0 15 0 15];
+%% mergeBoxes(box1, box2)
+%% ans =
+%% 0 20 0 30
+%% @end example
+%%
+%% @seealso{boxes2d, drawBox, intersectBoxes}
+%% @end deftypefn
+
+function bb = mergeBoxes(box1, box2)
+
+ % unify sizes of data
+ if size(box1,1) == 1
+ box1 = repmat(box1, size(box2,1), 1);
+ elseif size(box2, 1) == 1
+ box2 = repmat(box2, size(box1,1), 1);
+ elseif size(box1,1) != size(box2,1)
+ error('geom2d:Error', 'Bad size for inputs');
+ end
+
+ % compute extreme coords
+ mini = min(box1(:,[1 3]), box2(:,[1 3]));
+ maxi = max(box1(:,[2 4]), box2(:,[2 4]));
+
+ % concatenate result into a new box structure
+ bb = [mini(:,1) maxi(:,1) mini(:,2) maxi(:,2)];
+
+endfunction
+
+%!test
+%! box1 = [5 20 10 25];
+%! box2 = [0 15 15 20];
+%! res = [0 20 10 25];
+%! bb = mergeBoxes(box1, box2);
+%! assert (res, bb, 1e-6);
+
diff --git a/inst/geom2d/midPoint.m b/inst/geom2d/midPoint.m
new file mode 100644
index 0000000..2b41e22
--- /dev/null
+++ b/inst/geom2d/midPoint.m
@@ -0,0 +1,170 @@
+%% Copyright (c) 2011, INRA
+%% 2010-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} {@var{mid} = } midPoint (@var{p1}, @var{p2})
+%% @deftypefnx {Function File} {@var{mid} = } midPoint (@var{edge})
+%% @deftypefnx {Function File} {[@var{midx}, @var{midy}] = } midPoint (@var{edge})
+%% Middle point of two points or of an edge
+%%
+%% Computes the middle point of the two points @var{p1} and @var{p2}.
+%%
+%% If an edge is given, computes the middle point of the edge given by @var{edge}.
+%% @var{edge} has the format: [X1 Y1 X2 Y2], and @var{mid} has the format [XMID YMID],
+%% with XMID = (X1+X2)/2, and YMID = (Y1+Y2)/2.
+%%
+%% If two output arguments are given, it returns the result as two separate variables or arrays.
+%%
+%% Works also when @var{edge} is a N-by-4 array, in this case the result is a
+%% N-by-2 array containing the midpoint of each edge.
+%%
+%% Example
+%%
+%% @example
+%% p1 = [10 20];
+%% p2 = [30 40];
+%% midPoint([p1 p2])
+%% ans =
+%% 20 30
+%% @end example
+%%
+%% @seealso{edges2d, points2d}
+%% @end deftypefn
+
+function varargout = midPoint(varargin)
+
+ if nargin == 1
+ % input is an edge
+ edge = varargin{1};
+ mid = [mean(edge(:, [1 3]), 2) mean(edge(:, [2 4]), 2)];
+
+ elseif nargin == 2
+ % input are two points
+ p1 = varargin{1};
+ p2 = varargin{2};
+
+ % assert inputs are equal
+ n1 = size(p1, 1);
+ n2 = size(p2, 1);
+ if n1 != n2 && min(n1, n2)>1
+ error('geom2d:midPoint', ...
+ 'Inputs must have same size, or one must have length 1');
+ end
+
+ % compute middle point
+ mid = bsxfun(@plus, p1, p2) / 2;
+ end
+
+ % process output arguments
+ if nargout<=1
+ varargout{1} = mid;
+ else
+ varargout = {mid(:,1), mid(:,2)};
+ end
+
+endfunction
+
+%!test
+%! p1 = [10 20];
+%! p2 = [30 40];
+%! exp = [20 30];
+%! mid = midPoint(p1, p2);
+%! assert (mid, exp);
+
+%!test
+%! p1 = [ ...
+%! 10 20 ; ...
+%! 30 40 ; ...
+%! 50 60 ; ...
+%! ];
+%! p2 = [ ...
+%! 30 40; ...
+%! 50 60; ...
+%! 70 80];
+%! exp = [...
+%! 20 30; ...
+%! 40 50; ...
+%! 60 70];
+%! mid = midPoint(p1, p2);
+%! assert (mid, exp);
+
+%!test
+%! p1 = [30 40];
+%! p2 = [ ...
+%! 30 40; ...
+%! 50 60; ...
+%! 70 80];
+%! exp = [...
+%! 30 40; ...
+%! 40 50; ...
+%! 50 60];
+%! mid = midPoint(p1, p2);
+%! assert (mid, exp);
+
+%!test
+%! p1 = [ ...
+%! 10 20 ; ...
+%! 30 40 ; ...
+%! 50 60 ; ...
+%! ];
+%! p2 = [30 40];
+%! exp = [...
+%! 20 30; ...
+%! 30 40; ...
+%! 40 50];
+%! mid = midPoint(p1, p2);
+%! assert (mid, exp);
+
+%!test
+%! p1 = [ ...
+%! 10 20 ; ...
+%! 30 40 ; ...
+%! 50 60 ; ...
+%! ];
+%! p2 = [30 40];
+%! expX = [20 ; 30 ; 40];
+%! expY = [30 ; 40 ; 50];
+%! [x y] = midPoint(p1, p2);
+%! assert (x, expX);
+%! assert (y, expY);
+
+%!test
+%! edge = [10 20 30 40];
+%! exp = [20 30];
+%! mid = midPoint(edge);
+%! assert (mid, exp);
+%! edge = [10 20 30 40; 30 40 50 60; 50 60 70 80];
+%! exp = [20 30;40 50; 60 70];
+%! mid = midPoint(edge);
+%! assert (mid, exp);
+
diff --git a/inst/geom2d/minDistancePoints.m b/inst/geom2d/minDistancePoints.m
new file mode 100644
index 0000000..2c7103d
--- /dev/null
+++ b/inst/geom2d/minDistancePoints.m
@@ -0,0 +1,280 @@
+%% Copyright (c) 2011, INRA
+%% 2004-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} {@var{dist} = } minDistancePoints (@var{pts})
+%% @deftypefnx {Function File} {@var{dist} = } minDistancePoints (@var{pts1},@var{pts2})
+%% @deftypefnx {Function File} {@var{dist} = } minDistancePoints (@dots{},@var{norm})
+%% @deftypefnx {Function File} {[@var{dist} @var{i} @var{j}] = } minDistancePoints (@var{pts1}, @var{pts2}, @dots{})
+%% @deftypefnx {Function File} {[@var{dist} @var{j}] = } minDistancePoints (@var{pts1}, @var{pts2}, @dots{})
+%% Minimal distance between several points.
+%%
+%% Returns the minimum distance between all couple of points in @var{pts}. @var{pts} is
+%% an array of [NxND] values, N being the number of points and ND the
+%% dimension of the points.
+%%
+%% Computes for each point in @var{pts1} the minimal distance to every point of
+%% @var{pts2}. @var{pts1} and @var{pts2} are [NxD] arrays, where N is the number of points,
+%% and D is the dimension. Dimension must be the same for both arrays, but
+%% number of points can be different.
+%% The result is an array the same length as @var{pts1}.
+%%
+%% When @var{norm} is provided, it uses a user-specified norm. @var{norm}=2 means euclidean norm (the default),
+%% @var{norm}=1 is the Manhattan (or "taxi-driver") distance.
+%% Increasing @var{norm} growing up reduces the minimal distance, with a limit
+%% to the biggest coordinate difference among dimensions.
+%%
+%%
+%% Returns indices @var{i} and @var{j} of the 2 points which are the closest. @var{dist}
+%% verifies relation:
+%% @var{dist} = distancePoints(@var{pts}(@var{i},:), @var{pts}(@var{j},:));
+%%
+%% If only 2 output arguments are given, it returns the indices of points which are the closest. @var{j} has the
+%% same size as @var{dist}. for each I It verifies the relation :
+%% @var{dist}(I) = distancePoints(@var{pts1}(I,:), @var{pts2}(@var{J},:));
+%%
+%%
+%% Examples:
+%%
+%% @example
+%% % minimal distance between random planar points
+%% points = rand(20,2)*100;
+%% minDist = minDistancePoints(points);
+%%
+%% % minimal distance between random space points
+%% points = rand(30,3)*100;
+%% [minDist ind1 ind2] = minDistancePoints(points);
+%% minDist
+%% distancePoints(points(ind1, :), points(ind2, :))
+%% % results should be the same
+%%
+%% % minimal distance between 2 sets of points
+%% points1 = rand(30,2)*100;
+%% points2 = rand(30,2)*100;
+%% [minDists inds] = minDistancePoints(points1, points2);
+%% minDists(10)
+%% distancePoints(points1(10, :), points2(inds(10), :))
+%% % results should be the same
+%% @end example
+%%
+%% @seealso{points2d, distancePoints}
+%% @end deftypefn
+
+function varargout = minDistancePoints(p1, varargin)
+
+ %% Initialisations
+
+ % default norm (euclidean)
+ n = 2;
+
+ % flag for processing of all points
+ allPoints = false;
+
+ % process input variables
+ if isempty(varargin)
+ % specify only one array of points, not the norm
+ p2 = p1;
+
+ elseif length(varargin)==1
+ var = varargin{1};
+ if length(var)>1
+ % specify two arrays of points
+ p2 = var;
+ allPoints = true;
+ else
+ % specify array of points and the norm
+ n = var;
+ p2 = p1;
+ end
+
+ else
+ % specify two array of points and the norm
+ p2 = varargin{1};
+ n = varargin{2};
+ allPoints = true;
+ end
+
+
+ % number of points in each array
+ n1 = size(p1, 1);
+ n2 = size(p2, 1);
+
+ % dimension of points
+ d = size(p1, 2);
+
+
+ %% Computation of distances
+
+ % allocate memory
+ dist = zeros(n1, n2);
+
+ % different behaviour depending on the norm used
+ if n==2
+ % Compute euclidian distance. this is the default case
+ % Compute difference of coordinate for each pair of point ([n1*n2] array)
+ % and for each dimension. -> dist is a [n1*n2] array.
+ % in 2D: dist = dx.*dx + dy.*dy;
+ for i=1:d
+ dist = dist + (repmat(p1(:,i), [1 n2])-repmat(p2(:,i)', [n1 1])).^2;
+ end
+
+ % compute minimal distance:
+ if ~allPoints
+ % either on all couple of points
+ mat = repmat((1:n1)', [1 n1]);
+ ind = mat < mat';
+ [minSqDist ind] = min(dist(ind));
+ else
+ % or for each point of P1
+ [minSqDist ind] = min(dist, [], 2);
+ end
+
+ % convert squared distance to distance
+ minDist = sqrt(minSqDist);
+ elseif n==inf
+ % infinite norm corresponds to maximum absolute value of differences
+ % in 2D: dist = max(abs(dx) + max(abs(dy));
+ for i=1:d
+ dist = max(dist, abs(p1(:,i)-p2(:,i)));
+ end
+ else
+ % compute distance using the specified norm.
+ % in 2D: dist = power(abs(dx), n) + power(abs(dy), n);
+ for i=1:d
+ dist = dist + power((abs(repmat(p1(:,i), [1 n2])-repmat(p2(:,i)', [n1 1]))), n);
+ end
+
+ % compute minimal distance
+ if ~allPoints
+ % either on all couple of points
+ mat = repmat((1:n1)', [1 n1]);
+ ind = mat < mat';
+ [minSqDist ind] = min(dist(ind));
+ else
+ % or for each point of P1
+ [minSqDist ind] = min(dist, [], 2);
+ end
+
+ % convert squared distance to distance
+ minDist = power(minSqDist, 1/n);
+ end
+
+
+
+ if ~allPoints
+ % convert index in array to row ad column subindices.
+ % This uses the fact that index are sorted in a triangular matrix,
+ % with the last index of each column being a so-called triangular
+ % number
+ ind2 = ceil((-1+sqrt(8*ind+1))/2);
+ ind1 = ind - ind2*(ind2-1)/2;
+ ind2 = ind2 + 1;
+ end
+
+
+ %% format output parameters
+
+ % format output depending on number of asked parameters
+ if nargout<=1
+ varargout{1} = minDist;
+ elseif nargout==2
+ % If two arrays are asked, 'ind' is an array of indices, one for each
+ % point in var{pts}1, corresponding to the result in minDist
+ varargout{1} = minDist;
+ varargout{2} = ind;
+ elseif nargout==3
+ % If only one array is asked, minDist is a scalar, ind1 and ind2 are 2
+ % indices corresponding to the closest points.
+ varargout{1} = minDist;
+ varargout{2} = ind1;
+ varargout{3} = ind2;
+ end
+
+endfunction
+
+%!test
+%! pts = [50 10;40 60;30 30;20 0;10 60;10 30;0 10];
+%! assert (minDistancePoints(pts), 20);
+
+%!test
+%! pts = [10 10;25 5;20 20;30 20;10 30];
+%! [dist ind1 ind2] = minDistancePoints(pts);
+%! assert (10, dist, 1e-6);
+%! assert (3, ind1, 1e-6);
+%! assert (4, ind2, 1e-6);
+
+%!test
+%! pts = [0 80;10 60;20 40;30 20;40 0;0 0;100 0;0 100;0 -10;-10 -20];
+%! assert (minDistancePoints([40 50], pts), 10*sqrt(5), 1e-6);
+%! assert (minDistancePoints([25 30], pts), 5*sqrt(5), 1e-6);
+%! assert (minDistancePoints([30 40], pts), 10, 1e-6);
+%! assert (minDistancePoints([20 40], pts), 0, 1e-6);
+
+%!test
+%! pts1 = [40 50;25 30;40 20];
+%! pts2 = [0 80;10 60;20 40;30 20;40 0;0 0;100 0;0 100;0 -10;-10 -20];
+%! res = [10*sqrt(5);5*sqrt(5);10];
+%! assert (minDistancePoints(pts1, pts2), res, 1e-6);
+
+%!test
+%! pts = [50 10;40 60;40 30;20 0;10 60;10 30;0 10];
+%! assert (minDistancePoints(pts, 1), 30, 1e-6);
+%! assert (minDistancePoints(pts, 100), 20, 1e-6);
+
+%!test
+%! pts = [0 80;10 60;20 40;30 20;40 0;0 0;100 0;0 100;0 -10;-10 -20];
+%! assert (minDistancePoints([40 50], pts, 2), 10*sqrt(5), 1e-6);
+%! assert (minDistancePoints([25 30], pts, 2), 5*sqrt(5), 1e-6);
+%! assert (minDistancePoints([30 40], pts, 2), 10, 1e-6);
+%! assert (minDistancePoints([20 40], pts, 2), 0, 1e-6);
+%! assert (minDistancePoints([40 50], pts, 1), 30, 1e-6);
+%! assert (minDistancePoints([25 30], pts, 1), 15, 1e-6);
+%! assert (minDistancePoints([30 40], pts, 1), 10, 1e-6);
+%! assert (minDistancePoints([20 40], pts, 1), 0, 1e-6);
+
+%!test
+%! pts1 = [40 50;25 30;40 20];
+%! pts2 = [0 80;10 60;20 40;30 20;40 0;0 0;100 0;0 100;0 -10;-10 -20];
+%! res1 = [10*sqrt(5);5*sqrt(5);10];
+%! assert (minDistancePoints(pts1, pts2, 2), res1, 1e-6);
+%! res2 = [30;15;10];
+%! assert (minDistancePoints(pts1, pts2, 1), res2);
+
+%!test
+%! pts1 = [40 50;20 30;40 20];
+%! pts2 = [0 80;10 60;20 40;30 20;40 0;0 0;100 0;0 100;0 -10;-10 -20];
+%! dists0 = [10*sqrt(5);10;10];
+%! inds1 = [3;3;4];
+%! [minDists inds] = minDistancePoints(pts1, pts2);
+%! assert (dists0, minDists);
+%! assert (inds1, inds);
diff --git a/inst/geom2d/normalizeAngle.m b/inst/geom2d/normalizeAngle.m
new file mode 100644
index 0000000..9c0f988
--- /dev/null
+++ b/inst/geom2d/normalizeAngle.m
@@ -0,0 +1,96 @@
+%% Copyright (c) 2011, INRA
+%% 2008-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} {@var{alpha2} =} normalizeAngle (@var{alpha})
+%% @deftypefnx {Function File} {@var{alpha2} =} normalizeAngle (@var{alpha}, @var{center})
+%% Normalize an angle value within a 2*PI interval
+%%
+%% ALPHA2 = normalizeAngle(ALPHA);
+%% ALPHA2 is the same as ALPHA modulo 2*PI and is positive.
+%%
+%% ALPHA2 = normalizeAngle(ALPHA, CENTER);
+%% Specifies the center of the angle interval.
+%% If CENTER==0, the interval is [-pi ; +pi]
+%% If CENTER==PI, the interval is [0 ; 2*pi] (default).
+%%
+%% Example:
+%% % normalization between 0 and 2*pi (default)
+%% normalizeAngle(5*pi)
+%% ans =
+%% 3.1416
+%%
+%% % normalization between -pi and +pi
+%% normalizeAngle(7*pi/2, 0)
+%% ans =
+%% -1.5708
+%%
+%% References
+%% Follows the same convention as apache commons library, see:
+%% http://commons.apache.org/math/api-2.2/org/apache/commons/math/util/MathUtils.html%%
+%%
+%% @seealso{vectorAngle, lineAngle}
+%% @end deftypefn
+
+function alpha = normalizeAngle(alpha, varargin)
+
+ center = pi;
+ if ~isempty(varargin)
+ center = varargin{1};
+ end
+
+ alpha = mod(alpha-center+pi, 2*pi) + center-pi;
+
+endfunction
+
+%!assert (pi/2, normalizeAngle (pi/2), 1e-6);
+%!assert (pi, normalizeAngle (pi), 1e-6);
+%!assert (3*pi/2, normalizeAngle (3*pi/2), 1e-6);
+%!assert (pi/2, normalizeAngle (pi/2, pi), 1e-6);
+%!assert (pi, normalizeAngle (pi, pi), 1e-6);
+%!assert (3*pi/2, normalizeAngle (3*pi/2, pi), 1e-6);
+
+%!test
+%! theta = linspace(0, 2*pi-.1, 100);
+%! assert(theta, normalizeAngle (theta), 1e-6);
+
+%!assert (0, normalizeAngle (0, 0), 1e-6);
+%!assert (pi/2, normalizeAngle (pi/2, 0), 1e-6);
+%!assert (-pi, normalizeAngle (-pi, 0), 1e-6);
+%!assert (-pi/2, normalizeAngle (7*pi/2, 0), 1e-6);
+
+%!test
+%! theta = linspace(-pi+.1, pi-.1, 100);
+%! assert(theta, normalizeAngle (theta, 0), 1e-6);
+
+
diff --git a/inst/geom2d/normalizeVector.m b/inst/geom2d/normalizeVector.m
new file mode 100644
index 0000000..f7b7d0c
--- /dev/null
+++ b/inst/geom2d/normalizeVector.m
@@ -0,0 +1,72 @@
+%% Copyright (c) 2011, INRA
+%% 2004-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} {@var{vn} = } normalizeVector (@var{v})
+%% Normalize a vector to have norm equal to 1
+%%
+%% Returns the normalization of vector @var{v}, such that ||@var{v}|| = 1.
+%% @var{v} can be either a row or a column vector.
+%%
+%% When @var{v} is a MxN array, normalization is performed for each row of the
+%% array.
+%%
+%% Example:
+%%
+%% @example
+%% vn = normalizeVector([3 4])
+%% vn =
+%% 0.6000 0.8000
+%% vectorNorm(vn)
+%% ans =
+%% 1
+%% @end example
+%%
+%% @seealso{vectors2d, vectorNorm}
+%% @end deftypefn
+
+function vn = normalizeVector(v)
+
+ dim = size(v);
+
+ if dim(1)==1 || dim(2)==1
+ vn = v / sqrt(sum(v.^2));
+ else
+ %same as: vn = v./repmat(sqrt(sum(v.*v, 2)), [1 dim(2)]);
+ vn = bsxfun(@rdivide, v, sqrt(sum(v.^2, 2)));
+ end
+
+endfunction
+
+%!assert (1,vectorNorm (normalizeVector ([3 4])))
+
diff --git a/inst/geom2d/orthogonalLine.m b/inst/geom2d/orthogonalLine.m
new file mode 100644
index 0000000..368b530
--- /dev/null
+++ b/inst/geom2d/orthogonalLine.m
@@ -0,0 +1,64 @@
+%% Copyright (c) 2011, INRA
+%% 2003-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} {@var{perp} = } orthogonalLine (@var{line}, @var{point})
+%% Create a line orthogonal to another one.
+%
+% Returns the line orthogonal to the line @var{line} and going through the
+% point given by @var{point}. Directed angle from @var{line} to @var{perp} is pi/2.
+% @var{line} is given as [x0 y0 dx dy] and @var{point} is [xp yp].
+%
+% @seealso{lines2d, parallelLine}
+%% @end deftypefn
+
+function res = orthogonalLine(line, point)
+
+ N = max(size(point, 1), size(line, 1));
+
+ if size(point, 1)>1
+ res = point;
+ else
+ res = ones(N, 1)*point;
+ end
+
+ if size(line, 1)>1
+ res(:,3) = -line(:,4);
+ res(:,4) = line(:,3);
+ else
+ res(:,3) = -ones(N,1)*line(4);
+ res(:,4) = ones(N,1)*line(3);
+ end
+
+endfunction
+
diff --git a/inst/geom2d/parallelLine.m b/inst/geom2d/parallelLine.m
new file mode 100644
index 0000000..86b9029
--- /dev/null
+++ b/inst/geom2d/parallelLine.m
@@ -0,0 +1,63 @@
+%% Copyright (c) 2011, INRA
+%% 2003-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} {@var{res} = } parallelLine (@var{line}, @var{point})
+%% @deftypefnx {Function File} {@var{res} = } parallelLine (@var{line}, @var{dist})
+%% Create a line parallel to another one.
+%%
+%% Returns the line with same direction vector than @var{line} and going through
+%% the point given by @var{point}.
+%% @var{line} is given as [x0 y0 dx dy] and @var{point} is [xp yp].
+%%
+%% Uses relative distance to specify position. The new line will be
+%% located at distance @var{dist}, counted positive in the right side of @var{line}
+%% and negative in the left side.
+%%
+%% @seealso{lines2d, orthogonalLine, distancePointLine}
+%% @end deftypefn
+
+function res = parallelLine(line, point)
+
+ if size(point, 1)==1
+ % use a distance. Compute position of point located at distance DIST on
+ % the line orthogonal to the first one.
+ point = pointOnLine([line(:,1) line(:,2) line(:,4) -line(:,3)], point);
+ end
+
+ % normal case: compute line through a point with given direction
+ res = zeros(1, 4);
+ res(1:2) = point;
+ res(3:4) = line(3:4);
+
+endfunction
diff --git a/inst/geom2d/pointOnLine.m b/inst/geom2d/pointOnLine.m
new file mode 100644
index 0000000..25a3b52
--- /dev/null
+++ b/inst/geom2d/pointOnLine.m
@@ -0,0 +1,53 @@
+%% Copyright (c) 2011, INRA
+%% 2004-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} {@var{point} = } pointOnLine (@var{line}, @var{d})
+%% Create a point on a line at a given position on the line.
+%%
+%% Creates the point belonging to the line @var{line}, and located at the
+%% distance @var{d} from the line origin.
+%% @var{line} has the form [x0 y0 dx dy].
+%% @var{line} and @var{d} should have the same number N of rows. The result will have
+%% N rows and 2 column (x and y positions).
+%%
+%% @seealso{lines2d, points2d, onLine, onLine, linePosition}
+%% @end deftypefn
+
+function point = pointOnLine(lin, pos)
+
+ ang = lineAngle(lin);
+ point = [lin(:,1) + pos .* cos(ang), lin(:,2) + pos .* sin(ang)];
+
+endfunction
+
diff --git a/inst/geom2d/points2d.m b/inst/geom2d/points2d.m
new file mode 100644
index 0000000..ad61bd2
--- /dev/null
+++ b/inst/geom2d/points2d.m
@@ -0,0 +1,60 @@
+%% Copyright (c) 2011, INRA
+%% 2008-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} points2d ()
+%% Description of functions operating on points.
+%%
+%% A point is defined by its two cartesian coordinate, put into a row
+%% vector of 2 elements:
+%% P = [x y];
+%%
+%% Several points are stores in a matrix with two columns, one for the
+%% x-coordinate, one for the y-coordinate.
+%% PTS = [x1 y1 ; x2 y2 ; x3 y3];
+%%
+%% Example
+%% P = [5 6];
+%%
+%% @seealso{centroid, midPoint, polarPoint, pointOnLine
+%% isCounterClockwise, angle2Points, angle3Points, angleSort
+%% distancePoints, minDistancePoints
+%% transformPoint, clipPoints, drawPoint}
+%% @end deftypefn
+
+function points2d
+
+ help('points2d');
+
+endfunction
+
diff --git a/inst/geom2d/polarPoint.m b/inst/geom2d/polarPoint.m
new file mode 100644
index 0000000..6ba4537
--- /dev/null
+++ b/inst/geom2d/polarPoint.m
@@ -0,0 +1,83 @@
+%% Copyright (c) 2011, INRA
+%% 2004-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} {@var{point} = } polarPoint (@var{rho}, @var{theta})
+%% @deftypefnx {Function File} {@var{point} = } polarPoint (@var{theta})
+%% @deftypefnx {Function File} {@var{point} = } polarPoint (@var{point}, @var{rho}, @var{theta})
+%% @deftypefnx {Function File} {@var{point} = } polarPoint (@var{x0}, @var{y0}, @var{rho}, @var{theta})
+%%Create a point from polar coordinates (rho + theta)
+%%
+%% Creates a point using polar coordinate. @var{theta} is angle with horizontal
+%% (counted counter-clockwise, and in radians), and @var{rho} is the distance to
+%% origin. If only angle is given radius @var{rho} is assumed to be 1.
+%%
+%% If a point is given, adds the coordinate of the point to the coordinate of the specified
+%% point. For example, creating a point with :
+%% P = polarPoint([10 20], 30, pi/2);
+%% will give a result of [40 20].
+%%
+%% @seealso{points2d}
+%% @end deftypefn
+
+function point = polarPoint(varargin)
+
+ % default values
+ x0 = 0; y0=0;
+ rho = 1;
+ theta =0;
+
+ % process input parameters
+ if length(varargin)==1
+ theta = varargin{1};
+ elseif length(varargin)==2
+ rho = varargin{1};
+ theta = varargin{2};
+ elseif length(varargin)==3
+ var = varargin{1};
+ x0 = var(:,1);
+ y0 = var(:,2);
+ rho = varargin{2};
+ theta = varargin{3};
+ elseif length(varargin)==4
+ x0 = varargin{1};
+ y0 = varargin{2};
+ rho = varargin{3};
+ theta = varargin{4};
+ end
+
+ point = [x0 + rho.*cos(theta) , y0+rho.*sin(theta)];
+
+endfunction
+
+
diff --git a/inst/geom2d/private/assertAlmostEqual.m b/inst/geom2d/private/assertAlmostEqual.m
new file mode 100644
index 0000000..1ed9788
--- /dev/null
+++ b/inst/geom2d/private/assertAlmostEqual.m
@@ -0,0 +1,26 @@
+%% 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} {} assertAlmostEqual ()
+%% Wrapper. Not documented.
+%%
+%% @end deftypefn
+
+function assertAlmostEqual(a,b)
+
+ assert(b,a,1e-6);
+
+endfunction
diff --git a/inst/geom2d/private/assertElementsAlmostEqual.m b/inst/geom2d/private/assertElementsAlmostEqual.m
new file mode 100644
index 0000000..83dff6d
--- /dev/null
+++ b/inst/geom2d/private/assertElementsAlmostEqual.m
@@ -0,0 +1,26 @@
+%% 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} {} assertElementsAlmostEqual ()
+%% Wrapper. Not documented.
+%%
+%% @end deftypefn
+
+function assertElementsAlmostEqual(a,b)
+
+ assert(b,a,1e-6);
+
+endfunction
diff --git a/inst/geom2d/private/assertEqual.m b/inst/geom2d/private/assertEqual.m
new file mode 100644
index 0000000..a14ec83
--- /dev/null
+++ b/inst/geom2d/private/assertEqual.m
@@ -0,0 +1,26 @@
+%% 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} {} assertEqual ()
+%% Wrapper. Not documented.
+%%
+%% @end deftypefn
+
+function assertEqual(a,b)
+
+ assert(b,a);
+
+endfunction
diff --git a/inst/geom2d/private/assertFalse.m b/inst/geom2d/private/assertFalse.m
new file mode 100644
index 0000000..cb8a2c8
--- /dev/null
+++ b/inst/geom2d/private/assertFalse.m
@@ -0,0 +1,26 @@
+%% 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} {} assertFalse ()
+%% Wrapper. Not documented.
+%%
+%% @end deftypefn
+
+function assertFalse(a)
+
+ assert(!a);
+
+endfunction
diff --git a/inst/geom2d/private/assertTrue.m b/inst/geom2d/private/assertTrue.m
new file mode 100644
index 0000000..e603ab1
--- /dev/null
+++ b/inst/geom2d/private/assertTrue.m
@@ -0,0 +1,26 @@
+%% 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} {} assertTrue ()
+%% Wrapper. Not documented.
+%%
+%% @end deftypefn
+
+function assertTrue(a)
+
+ assert(a);
+
+endfunction
diff --git a/inst/geom2d/projPointOnLine.m b/inst/geom2d/projPointOnLine.m
new file mode 100644
index 0000000..8748d63
--- /dev/null
+++ b/inst/geom2d/projPointOnLine.m
@@ -0,0 +1,69 @@
+%% Copyright (c) 2011, INRA
+%% 2005-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} {@var{point} = } projPointOnLine (@var{pt1}, @var{line})
+%% Project of a point orthogonally onto a line
+%%
+%% Computes the (orthogonal) projection of point @var{pt1} onto the line @var{line}.
+%%
+%% Function works also for multiple points and lines. In this case, it
+%% returns multiple points.
+%% Point @var{pt1} is a [N*2] array, and @var{line} is a [N*4] array (see createLine
+%% for details). Result @var{point} is a [N*2] array, containing coordinates of
+%% orthogonal projections of @var{pt1} onto lines @var{line}.
+%%
+%% @seealso{lines2d, points2d, isPointOnLine, linePosition}
+%% @end deftypefn
+
+function point = projPointOnLine(point, line)
+
+ % ensure input arguments have same size
+ if size(line, 1)==1 && size(point, 1)>1
+ line = repmat(line, [size(point, 1) 1]);
+ end
+ if size(point, 1)==1 && size(line, 1)>1
+ point = repmat(point, [size(line, 1) 1]);
+ end
+
+ % slope of line
+ dx = line(:, 3);
+ dy = line(:, 4);
+
+ % first find relative position of projection on the line,
+ tp = ((point(:, 2) - line(:, 2)).*dy + (point(:, 1) - line(:, 1)).*dx) ./ (dx.*dx+dy.*dy);
+
+ % convert position on line to cartesian coordinate
+ point = line(:,1:2) + [tp tp].*[dx dy];
+
+endfunction
diff --git a/inst/geom2d/rad2deg.m b/inst/geom2d/rad2deg.m
new file mode 100644
index 0000000..5274d74
--- /dev/null
+++ b/inst/geom2d/rad2deg.m
@@ -0,0 +1,58 @@
+%% Copyright (c) 2011, INRA
+%% 2004-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} {@var{deg} =} rad2deg(@var{rad})
+% Convert angle from radians to degrees
+%
+% Usage:
+% R = rad2deg(D)
+% convert an angle in radians to angle in degrees
+%
+% Example:
+% rad2deg(pi)
+% ans =
+% 180
+% rad2deg(pi/3)
+% ans =
+% 60
+%%
+%% @seealso{angles2d, deg2rad}
+%% @end deftypefn
+
+function deg = rad2deg(rad)
+
+ deg = rad*180/pi;
+
+endfunction
+
diff --git a/inst/geom2d/radicalAxis.m b/inst/geom2d/radicalAxis.m
new file mode 100644
index 0000000..25c076d
--- /dev/null
+++ b/inst/geom2d/radicalAxis.m
@@ -0,0 +1,88 @@
+%% Copyright (c) 2011, INRA
+%% 2004-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} {@var{line} = } radicalAxis (@var{circle1}, @var{circle2})
+%% Compute the radical axis (or radical line) of 2 circles
+%%
+%% L = radicalAxis(C1, C2)
+%% Computes the radical axis of 2 circles.
+%%
+%% Example
+%% C1 = [10 10 5];
+%% C2 = [60 50 30];
+%% L = radicalAxis(C1, C2);
+%% hold on; axis equal;axis([0 100 0 100]);
+%% drawCircle(C1);drawCircle(C2);drawLine(L);
+%%
+%% Ref:
+%% http://mathworld.wolfram.com/RadicalLine.html
+%% http://en.wikipedia.org/wiki/Radical_axis
+%%
+%% @seealso{lines2d, circles2d, createCircle}
+%%
+%% @end deftypefn
+
+function line = radicalAxis(circle1, circle2)
+
+ % extract circles parameters
+ x1 = circle1(:,1);
+ x2 = circle2(:,1);
+ y1 = circle1(:,2);
+ y2 = circle2(:,2);
+ r1 = circle1(:,3);
+ r2 = circle2(:,3);
+
+ % distance between each couple of centers
+ dist = sqrt((x2-x1).^2 + (y2-y1).^2);
+
+ % relative position of intersection point of
+ % the radical line with the line joining circle centers
+ d = (dist.^2 + r1.^2 - r2.^2) * .5 ./ dist;
+
+ % compute angle of radical axis
+ angle = lineAngle(createLine([x1 y1], [x2 y2]));
+ cot = cos(angle);
+ sit = sin(angle);
+
+ % parameters of the line
+ x0 = x1 + d*cot;
+ y0 = y1 + d*sit;
+ dx = -sit;
+ dy = cot;
+
+ % concatenate into one structure
+ line = [x0 y0 dx dy];
+
+endfunction
+
diff --git a/inst/geom2d/randomPointInBox.m b/inst/geom2d/randomPointInBox.m
new file mode 100644
index 0000000..06d57e6
--- /dev/null
+++ b/inst/geom2d/randomPointInBox.m
@@ -0,0 +1,85 @@
+%% 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} {@var{points} =} randomPointInBox (@var{box})
+%% @deftypefnx {Function File} {@var{points} =} randomPointInBox (@var{box}, @var{n})
+%% Generate random points within a box.
+%%
+%% Generate a random point within the box @var{box}. The result is a 1-by-2 row
+%% vector. If @var{n} is given, generates @var{n} points. The result is a
+%% @var{n}-by-2 array.
+%%
+%% Example
+%%
+%% @example
+%% % draw points within a box
+%% box = [10 80 20 60];
+%% pts = randomPointInBox(box, 500);
+%% figure(1); clf; hold on;
+%% drawBox(box);
+%% drawPoint(pts, '.');
+%% axis('equal');
+%% axis([0 100 0 100]);
+%% @end example
+%%
+%% @seealso{edges2d, boxes2d, clipLine}
+%% @end deftypefn
+
+function points = randomPointInBox(box, N=1, varargin)
+
+ % extract box bounds
+ xmin = box(1);
+ xmax = box(2);
+ ymin = box(3);
+ ymax = box(4);
+
+ % compute size of box
+ dx = xmax - xmin;
+ dy = ymax - ymin;
+
+ % compute point coordinates
+ points = [rand(N, 1)*dx+xmin , rand(N, 1)*dy+ymin];
+
+endfunction
+
+%!demo
+%! % draw points within a box
+%! bb = [10 80 20 60];
+%! pts = randomPointInBox(bb, 500);
+%! figure(1); clf; hold on;
+%! drawBox(bb);
+%! drawPoint(pts, '.');
+%! axis equal
+%! axis([0 100 0 100]);
+
diff --git a/inst/geom2d/rays2d.m b/inst/geom2d/rays2d.m
new file mode 100644
index 0000000..034bbb4
--- /dev/null
+++ b/inst/geom2d/rays2d.m
@@ -0,0 +1,60 @@
+%% Copyright (c) 2011, INRA
+%% 2008-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} rays2d ()
+%% Description of functions operating on planar rays
+%%
+%% A ray is defined by a point (its origin), and a vector (its
+%% direction). The different parameters are bundled into a row vector:
+%% @code{RAY = [x0 y0 dx dy];}
+%%
+%% The ray contains all the points (x,y) such that:
+%% x = x0 + t*dx
+%% y = y0 + t*dy;
+%% for all t>0
+%%
+%% Contrary to a (straight) line, the points located before the origin do
+%% not belong to the ray.
+%% However, as rays and lines have the same representation, some functions
+%% working on lines are also working on rays (like @code{transformLine}).
+%%
+%% @seealso{points2d, vectors2d, lines2d, createRay, bisector, isPointOnRay,
+%% clipRay, drawRay}
+%% @end deftypefn
+
+function rays2d(varargin)
+
+ help('rays2d');
+
+endfunction
diff --git a/inst/geom2d/readme.txt b/inst/geom2d/readme.txt
new file mode 100644
index 0000000..ef5fe00
--- /dev/null
+++ b/inst/geom2d/readme.txt
@@ -0,0 +1,68 @@
+%% 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.
+
+
+Description of the geom2d library.
+
+The aim of geom2d library is to handle and visualize geometric primitives such
+as points, lines, circles and ellipses, polylines and polygons... It provides
+low-level functions for manipulating geometrical primitives, making easier the
+development of more complex geometric algorithms.
+
+Some features of the library are:
+
+- creation of various shapes (points, circles, lines, ellipses, polylines,
+ polygons...) through an intuitive syntax.
+ Ex: createCircle(p1, p2, p3) to create a circle through 3 points.
+
+- derivation of new shapes: intersection between 2 lines, between line and
+ circle, between polylines... or point on a curve from its parametrisation
+
+- functions for polylines and polygons: compute centroid and area, expand,
+ self-intersections, clipping with half-plane...
+
+- manipulation of planar transformation. Ex.:
+ ROT = createRotation(CENTER, THETA);
+ P2 = transformPoint(P1, ROT);
+
+- direct drawing of shapes with specialized functions. Clipping is performed
+ automatically for infinite shapes such as lines or rays. Ex:
+ drawCircle([50 50 25]); % draw circle with radius 25 and center [50 50]
+ drawLine([X0 Y0 DX DY]); % clip and draw straight line
+
+- measure distances (between points, a point and a line, a point and a group
+ of points), angle (of a line, between 3 points), or test geometry (point
+ on a line, on a circle).
+
+Additional help is provided in geom/Contents.m file, as well as summary files
+ like 'points2d.m' or 'lines2d.m'.
diff --git a/inst/geom2d/reverseEdge.m b/inst/geom2d/reverseEdge.m
new file mode 100644
index 0000000..cf32ec3
--- /dev/null
+++ b/inst/geom2d/reverseEdge.m
@@ -0,0 +1,50 @@
+%% Copyright (c) 2011, INRA
+%% 2010-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} {@var{res} = } reverseEdge (@var{edge})
+%% Intervert the source and target vertices of edge
+%%
+%% REV = reverseEdge(EDGE);
+%% Returns the opposite edge of EDGE.
+%% EDGE has the format [X1 Y1 X2 Y2]. The resulting edge REV has value
+%% [X2 Y2 X1 Y1];
+%%
+%% @seealso{edges2d, createEdge, reverseLine}
+%% @end deftypefn
+
+function res = reverseEdge(edge)
+
+ res = [edge(:,3:4) edge(:,1:2)];
+
+endfunction
diff --git a/inst/geom2d/reverseLine.m b/inst/geom2d/reverseLine.m
new file mode 100644
index 0000000..2844c6d
--- /dev/null
+++ b/inst/geom2d/reverseLine.m
@@ -0,0 +1,52 @@
+%% Copyright (c) 2011, INRA
+%% 2004-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} {@var{line} = } reverseLine (@var{line})
+%% Return same line but with opposite orientation
+%%
+%% INVLINE = reverseLine(LINE);
+%% Returns the opposite line of LINE.
+%% LINE has the format [x0 y0 dx dy], then INVLINE will have following
+%% parameters: [x0 y0 -dx -dy].
+%%
+%% @seealso{lines2d, createLine}
+%% @end deftypefn
+
+function line = reverseLine(line)
+
+ line(:, 3:4) = -line(:, 3:4);
+
+endfunction
+
+
diff --git a/inst/geom2d/rotateVector.m b/inst/geom2d/rotateVector.m
new file mode 100644
index 0000000..9bcf79d
--- /dev/null
+++ b/inst/geom2d/rotateVector.m
@@ -0,0 +1,64 @@
+%% 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} {@var{vr} = } rotateVector (@var{v}, @var{theta})
+%% Rotate a vector by a given angle
+%%
+%% Rotate the vector @var{v} by an angle @var{theta}, given in radians.
+%%
+%% Example
+%%
+%% @example
+%% rotateVector([1 0], pi/2)
+%% ans =
+%% 0 1
+%% @end example
+%%
+%% @seealso{vectors2d, transformVector, createRotation}
+%% @end deftypefn
+
+function vr = rotateVector(v, angle)
+
+ % precomputes angles
+ cot = cos(angle);
+ sit = sin(angle);
+
+ % compute rotated coordinates
+ vr = [cot * v(:,1) - sit * v(:,2) , sit * v(:,1) + cot * v(:,2)];
+
+endfunction
+
+%!assert ([0 1],rotateVector([1 0],pi/2), 1e-6)
+%!assert (sqrt([0.5 0.5]),rotateVector([1 0],pi/4), 1e-6)
+
diff --git a/inst/geom2d/squareGrid.m b/inst/geom2d/squareGrid.m
new file mode 100644
index 0000000..353615e
--- /dev/null
+++ b/inst/geom2d/squareGrid.m
@@ -0,0 +1,82 @@
+%% Copyright (c) 2011, INRA
+%% 2005-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} {@var{pts} = } squaregrid (@var{bounds}, @var{origin}, @var{size})
+%% Generate equally spaces points in plane.
+%%
+%% usage
+%% PTS = squareGrid(BOUNDS, ORIGIN, SIZE)
+%% generate points, lying in the window defined by BOUNDS (=[xmin ymin
+%% xmax ymax]), starting from origin with a constant step equal to size.
+%%
+%% Example
+%% PTS = squareGrid([0 0 10 10], [3 3], [4 2])
+%% will return points :
+%% [3 1;7 1;3 3;7 3;3 5;7 5;3 7;7 7;3 9;7 9];
+%%
+%% TODO: add possibility to use rotated grid
+%%
+%% @end deftypefn
+
+function varargout = squareGrid(bounds, origin, size)
+
+ % find all x coordinate
+ x1 = bounds(1) + mod(origin(1)-bounds(1), size(1));
+ x2 = bounds(3) - mod(bounds(3)-origin(1), size(1));
+ lx = (x1:size(1):x2)';
+
+ % find all y coordinate
+ y1 = bounds(2) + mod(origin(2)-bounds(2), size(2));
+ y2 = bounds(4) - mod(bounds(4)-origin(2), size(2));
+ ly = (y1:size(2):y2)';
+
+ % number of points in each coord, and total number of points
+ ny = length(ly);
+ nx = length(lx);
+ np = nx*ny;
+
+ % create points
+ pts = zeros(np, 2);
+ for i=1:ny
+ pts( (1:nx)'+(i-1)*nx, 1) = lx;
+ pts( (1:nx)'+(i-1)*nx, 2) = ly(i);
+ end
+
+ % process output
+ if nargout>0
+ varargout{1} = pts;
+ end
+
+endfunction
+
diff --git a/inst/geom2d/transformEdge.m b/inst/geom2d/transformEdge.m
new file mode 100644
index 0000000..cbfceff
--- /dev/null
+++ b/inst/geom2d/transformEdge.m
@@ -0,0 +1,71 @@
+%% Copyright (c) 2011, INRA
+%% 2004-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} {@var{edge2} = } transformEdge (@var{edge1}, @var{T})
+%% Transform an edge with an affine transform.
+%%
+%% Where @var{edge1} has the form [x1 y1 x2 y1], and @var{T} is a transformation
+%% matrix, return the edge transformed with affine transform @var{T}.
+%%
+%% Format of TRANS can be one of :
+%% [a b] , [a b c] , or [a b c]
+%% [d e] [d e f] [d e f]
+%% [0 0 1]
+%%
+%% Also works when @var{edge1} is a [Nx4] array of double. In this case, @var{edge2}
+%% has the same size as @var{edge1}.
+%%
+%% @seealso{edges2d, transforms2d, transformPoint, translation, rotation}
+%% @end deftypefn
+
+function dest = transformEdge(edge, trans)
+
+ dest = zeros(size(edge));
+
+ % compute position
+ dest(:,1) = edge(:,1)*trans(1,1) + edge(:,2)*trans(1,2);
+ dest(:,2) = edge(:,1)*trans(2,1) + edge(:,2)*trans(2,2);
+ dest(:,3) = edge(:,3)*trans(1,1) + edge(:,3)*trans(1,2);
+ dest(:,4) = edge(:,4)*trans(2,1) + edge(:,4)*trans(2,2);
+
+ % add translation vector, if exist
+ if size(trans, 2)>2
+ dest(:,1) = dest(:,1)+trans(1,3);
+ dest(:,2) = dest(:,2)+trans(2,3);
+ dest(:,3) = dest(:,3)+trans(1,3);
+ dest(:,4) = dest(:,4)+trans(2,3);
+ end
+
+endfunction
+
diff --git a/inst/geom2d/transformLine.m b/inst/geom2d/transformLine.m
new file mode 100644
index 0000000..9e63354
--- /dev/null
+++ b/inst/geom2d/transformLine.m
@@ -0,0 +1,66 @@
+%% Copyright (c) 2011, INRA
+%% 2004-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} {@var{line2} = } transformLine (@var{line1}, @var{T})
+%% Transform a line with an affine transform.
+%%
+%% Returns the line @var{line1} transformed with affine transform @var{T}.
+%% @var{line1} has the form [x0 y0 dx dy], and @var{T} is a transformation
+%% matrix.
+%%
+%% Format of @var{T} can be one of :
+%% [a b] , [a b c] , or [a b c]
+%% [d e] [d e f] [d e f]
+%% [0 0 1]
+%%
+%% Also works when @var{line1} is a [Nx4] array of double. In this case, @var{line2}
+%% has the same size as @var{line1}.
+%%
+%% @seealso{lines2d, transforms2d, transformPoint}
+%% @end deftypefn
+
+function dest = transformLine(line, trans)
+
+ % isolate points
+ points1 = line(:, 1:2);
+ points2 = line(:, 1:2) + line(:, 3:4);
+
+ % transform points
+ points1 = transformPoint(points1, trans);
+ points2 = transformPoint(points2, trans);
+
+ dest = createLine(points1, points2);
+
+endfunction
+
diff --git a/inst/geom2d/transformPoint.m b/inst/geom2d/transformPoint.m
new file mode 100644
index 0000000..0eb0281
--- /dev/null
+++ b/inst/geom2d/transformPoint.m
@@ -0,0 +1,92 @@
+%% Copyright (c) 2011, INRA
+%% 2005-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} {@var{pt2} = } transformPoint (@var{pt1}, @var{Trans})
+%% @deftypefnx {Function File} {[@var{px2} @var{py2}]= } transformPoint (@var{px1}, @var{py1}, @var{Trans})
+%% Transform a point with an affine transform.
+%%
+%% where @var{pt1} has the form [xp yp], and @var{Trans} is a [2x2], [2x3] or [3x3]
+%% matrix, returns the point transformed with affine transform @var{Trans}.
+%%
+%% Format of @var{Trans} can be one of :
+%% [a b] , [a b c] , or [a b c]
+%% [d e] [d e f] [d e f]
+%% [0 0 1]
+%%
+%% Also works when @var{pt1} is a [Nx2] array of double. In this case, @var{pt2} has
+%% the same size as @var{pt1}.
+%%
+%% Also works when @var{px1} and @var{py1} are arrays the same size. The function
+%% transform each couple of (@var{px1}, @var{py1}), and return the result in
+%% (@var{px2}, @var{py2}), which is the same size as (@var{px1} @var{py1}).
+%%
+%% @seealso{points2d, transforms2d, createTranslation, createRotation}
+%% @end deftypefn
+
+function varargout = transformPoint(varargin)
+
+ if length(varargin)==2
+ var = varargin{1};
+ px = var(:,1);
+ py = var(:,2);
+ trans = varargin{2};
+ elseif length(varargin)==3
+ px = varargin{1};
+ py = varargin{2};
+ trans = varargin{3};
+ else
+ error('wrong number of arguments in "transformPoint"');
+ end
+
+
+ % compute position
+ px2 = px*trans(1,1) + py*trans(1,2);
+ py2 = px*trans(2,1) + py*trans(2,2);
+
+ % add translation vector, if exist
+ if size(trans, 2)>2
+ px2 = px2 + trans(1,3);
+ py2 = py2 + trans(2,3);
+ end
+
+
+ if nargout==0 || nargout==1
+ varargout{1} = [px2 py2];
+ elseif nargout==2
+ varargout{1} = px2;
+ varargout{2} = py2;
+ end
+
+endfunction
+
diff --git a/inst/geom2d/transformVector.m b/inst/geom2d/transformVector.m
new file mode 100644
index 0000000..5416343
--- /dev/null
+++ b/inst/geom2d/transformVector.m
@@ -0,0 +1,108 @@
+%% 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} {@var{v2} = } transformVector (@var{v}, @var{T})
+%% @deftypefnx {Function File} {[@var{x2} @var{y2}] = } transformVector (@var{x},@var{y}, @var{T})
+%% Transform a vector with an affine transform
+%%
+%% @var{v} has the form [xv yv], and @var{T} is a [2x2], [2x3] or [3x3]
+%% matrix, returns the vector transformed with affine transform @var{T}.
+%%
+%% Format of @var{T} can be one of :
+%% @group
+%% [a b] , [a b c] , or [a b c]
+%% [d e] [d e f] [d e f]
+%% [0 0 1]
+%% @end group
+%%
+%% Also works when @var{v} is a [Nx2] array of double. In this case, @var{v2} has
+%% the same size as @var{v}.
+%%
+%% Also works when @var{x} and @var{y} are arrays the same size. The function
+%% transform each couple of (@var{x}, @var{y}), and return the result in
+%% (@var{x2}, @var{y2}), which is the same size as (@var{x}, @var{y}).
+%%
+%% @seealso{vectors2d, transforms2d, rotateVector, transformPoint}
+%% @end deftypefn
+
+function varargout = transformVector(varargin)
+
+ if length(varargin)==2
+ var = varargin{1};
+ vx = var(:,1);
+ vy = var(:,2);
+ trans = varargin{2};
+ elseif length(varargin)==3
+ vx = varargin{1};
+ vy = varargin{2};
+ trans = varargin{3};
+ else
+ error('wrong number of arguments in "transformVector"');
+ end
+
+
+ % compute new position of vector
+ vx2 = vx*trans(1,1) + vy*trans(1,2);
+ vy2 = vx*trans(2,1) + vy*trans(2,2);
+
+ if size(trans, 2) == 3
+ vx2 = vx2 + trans(1,3);
+ vy2 = vy2 + trans(2,3);
+ end
+
+ % format output
+ if nargout==0 || nargout==1
+ varargout{1} = [vx2 vy2];
+ elseif nargout==2
+ varargout{1} = vx2;
+ varargout{2} = vy2;
+ end
+
+endfunction
+
+%!demo
+%! t1 = [2 0 0; 0 2 0];
+%! t2 = [1 0 1; 0 1 1];
+%! t3 = [0.5 0 1; 0 0.5 1; 0 0 1];
+%!
+%! triangle = [-0.5 -1/3; 0.5 -1/3; 0 2/3; -0.5 -1/3];
+%! tr1 = transformVector(triangle,t1);
+%! tr2 = transformVector(triangle,t2);
+%! tr3 = transformVector(triangle,t3);
+%!
+%! plot(triangle(:,1),triangle(:,2),'k-', ...
+%! tr1(:,1),tr1(:,2),'g-;scaled up;', ...
+%! tr2(:,1),tr2(:,2),'m-;translated;', ...
+%! tr3(:,1),tr3(:,2),'b-;scaled down and translated;')
+
diff --git a/inst/geom2d/transforms2d.m b/inst/geom2d/transforms2d.m
new file mode 100644
index 0000000..fb27bd0
--- /dev/null
+++ b/inst/geom2d/transforms2d.m
@@ -0,0 +1,63 @@
+%% Copyright (c) 2011, INRA
+%% 2008-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} transforms2d ()
+%% Description of functions operating on transforms
+%%
+%% By 'transform' we mean an affine transform. A planar affine transform
+%% can be represented by a 3x3 matrix.
+%%
+%% Example
+%%
+%% @example
+%% % create a translation by the vector [10 20]:
+%% T = createTranslation([10 20])
+%% T =
+%% 1 0 10
+%% 0 1 20
+%% 0 0 1
+%%@end example
+%%
+%% @seealso{createTranslation, createRotation, createScaling, createBasisTransform,
+%% createHomothecy, createLineReflection, fitAffineTransform2d,
+%% transformPoint, transformVector, transformLine, transformEdge,
+%% rotateVector}
+%% @end deftypefn
+
+function transforms2d(varargin)
+
+ help('transforms2d');
+
+endfunction
+
diff --git a/inst/geom2d/triangleGrid.m b/inst/geom2d/triangleGrid.m
new file mode 100644
index 0000000..ba14010
--- /dev/null
+++ b/inst/geom2d/triangleGrid.m
@@ -0,0 +1,69 @@
+%% Copyright (c) 2011, INRA
+%% 2005-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} {@var{pts} = } triangleGrid (@var{bounds}, @var{origin}, @var{size})
+%% Generate triangular grid of points in the plane.
+%%
+%% usage
+%% PTS = triangleGrid(BOUNDS, ORIGIN, SIZE)
+%% generate points, lying in the window defined by BOUNDS, given in form
+%% [xmin ymin xmax ymax], starting from origin with a constant step equal
+%% to size.
+%% SIZE is constant and is equals to the length of the sides of each
+%% triangles.
+%%
+%% TODO: add possibility to use rotated grid
+%%
+%% @end deftypefn
+
+function varargout = triangleGrid(bounds, origin, size, varargin)
+
+ dx = size(1);
+ dy = size(1)*sqrt(3);
+
+ % consider two square grids with different centers
+ pts1 = squareGrid(bounds, origin, [dx dy], varargin{:});
+ pts2 = squareGrid(bounds, origin + [dx dy]/2, [dx dy], varargin{:});
+
+ % gather points
+ pts = [pts1;pts2];
+
+
+ % process output
+ if nargout>0
+ varargout{1} = pts;
+ end
+
+endfunction
+
diff --git a/inst/geom2d/vectorAngle.m b/inst/geom2d/vectorAngle.m
new file mode 100644
index 0000000..80cd612
--- /dev/null
+++ b/inst/geom2d/vectorAngle.m
@@ -0,0 +1,221 @@
+%% 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} {@var{alpha} =} vectorAngle (@var{v1})
+%% Angle of a vector, or between 2 vectors
+%%
+%% A = vectorAngle(V);
+%% Returns angle between Ox axis and vector direction, in Counter
+%% clockwise orientation.
+%% The result is normalised between 0 and 2*PI.
+%%
+%% A = vectorAngle(V1, V2);
+%% Returns the angle from vector V1 to vector V2, in counter-clockwise
+%% order, and in radians.
+%%
+%% A = vectorAngle(..., 'cutAngle', CUTANGLE);
+%% A = vectorAngle(..., CUTANGLE); % (deprecated syntax)
+%% Specifies convention for angle interval. CUTANGLE is the center of the
+%% 2*PI interval containing the result. See <a href="matlab:doc
+%% ('normalizeAngle')">normalizeAngle</a> for details.
+%%
+%% Example:
+%% rad2deg(vectorAngle([2 2]))
+%% ans =
+%% 45
+%% rad2deg(vectorAngle([1 sqrt(3)]))
+%% ans =
+%% 60
+%% rad2deg(vectorAngle([0 -1]))
+%% ans =
+%% 270
+%%
+%% @seealso{vectors2d, angles2d, normalizeAngle}
+%% @end deftypefn
+
+function alpha = vectorAngle(v1, varargin)
+
+ %% Initializations
+
+ % default values
+ v2 = [];
+ cutAngle = pi;
+
+ % process input arguments
+ while ~isempty(varargin)
+ var = varargin{1};
+ if isnumeric(var) && isscalar(var)
+ % argument is normalization constant
+ cutAngle = varargin{1};
+ varargin(1) = [];
+
+ elseif isnumeric(var) && size(var, 2) == 2
+ % argument is second vector
+ v2 = varargin{1};
+ varargin(1) = [];
+
+ elseif ischar(var) && length(varargin) >= 2
+ % argument is option given as string + value
+ if strcmpi(var, 'cutAngle')
+ cutAngle = varargin{2};
+ varargin(1:2) = [];
+
+ else
+ error(['Unknown option: ' var]);
+ end
+
+ else
+ error('Unable to parse inputs');
+ end
+ end
+
+
+ %% Case of one vector
+
+ % If only one vector is provided, computes its angle
+ if isempty(v2)
+ % compute angle and format result in a 2*pi interval
+ alpha = atan2(v1(:,2), v1(:,1));
+
+ % normalize within a 2*pi interval
+ alpha = normalizeAngle(alpha + 2*pi, cutAngle);
+
+ return;
+ end
+
+
+ %% Case of two vectors
+
+ % compute angle of each vector
+ alpha1 = atan2(v1(:,2), v1(:,1));
+ alpha2 = atan2(v2(:,2), v2(:,1));
+
+ % difference
+ alpha = bsxfun(@minus, alpha2, alpha1);
+
+ % normalize within a 2*pi interval
+ alpha = normalizeAngle(alpha + 2*pi, cutAngle);
+
+endfunction
+
+%!test
+%! ang = vectorAngle([1 0]);
+%! assert(0, ang, 1e-6);
+
+%!test
+%! ang = vectorAngle([0 1]);
+%! assert(pi/2, ang, 1e-6);
+
+%!test
+%! ang = vectorAngle([-1 0]);
+%! assert(pi, ang, 1e-6);
+
+%!test
+%! ang = vectorAngle([0 -1]);
+%! assert(3*pi/2, ang, 1e-6);
+
+%!test
+%! ang = vectorAngle([-1 1]);
+%! assert(3*pi/4, ang, 1e-6);
+
+%!test
+%! ang = vectorAngle([1 0], pi);
+%! assert(0, ang, 1e-6);
+
+%!test
+%! ang = vectorAngle([0 1], pi);
+%! assert(pi/2, ang, 1e-6);
+
+%!test
+%! ang = vectorAngle([-1 0], pi);
+%! assert(pi, ang, 1e-6);
+
+%!test
+%! ang = vectorAngle([0 -1], pi);
+%! assert(3*pi/2, ang, 1e-6);
+
+%!test
+%! ang = vectorAngle([-1 1], pi);
+%! assert(3*pi/4, ang, 1e-6);
+
+%!test
+%! vecs = [1 0;0 1;-1 0;0 -1;1 1];
+%! angs = [0;pi/2;pi;3*pi/2;pi/4];
+%! assert(angs, vectorAngle(vecs));
+%! assert(angs, vectorAngle(vecs, pi));
+
+%!test
+%! ang = vectorAngle([1 0], 0);
+%! assert(0, ang, 1e-6);
+
+%!test
+%! ang = vectorAngle([0 1], 0);
+%! assert(pi/2, ang, 1e-6);
+
+%!test
+%! ang = vectorAngle([0 -1], 0);
+%! assert(-pi/2, ang, 1e-6);
+
+%!test
+%! ang = vectorAngle([-1 1], 0);
+%! assert(3*pi/4, ang, 1e-6);
+
+%!test
+%! vecs = [1 0;0 1;0 -1;1 1;1 -1];
+%! angs = [0;pi/2;-pi/2;pi/4;-pi/4];
+%! assert(angs, vectorAngle(vecs, 0), 1e-6);
+
+%!test
+%! v1 = [1 0];
+%! v2 = [0 1];
+%! ang = pi /2 ;
+%! assert(ang, vectorAngle(v1, v2), 1e-6);
+
+%!test
+%! v1 = [1 0];
+%! v2 = [0 1; 0 1; 1 1; -1 1];
+%! ang = [pi / 2 ;pi / 2 ;pi / 4 ; 3 * pi / 4];
+%! assert(ang, vectorAngle(v1, v2), 1e-6);
+
+%!test
+%! v1 = [0 1; 0 1; 1 1; -1 1];
+%! v2 = [-1 0];
+%! ang = [pi / 2 ;pi / 2 ; 3 * pi / 4 ; pi / 4];
+%! assert(ang, vectorAngle(v1, v2), 1e-6);
+
+%!test
+%! v1 = [1 0; 0 1; 1 1; -1 1];
+%! v2 = [0 1; 1 0; -1 1; -1 0];
+%! ang = [pi / 2 ;3 * pi / 2 ;pi / 2 ; pi / 4];
+%! assert(ang, vectorAngle(v1, v2), 1e-6);
diff --git a/inst/geom2d/vectorNorm.m b/inst/geom2d/vectorNorm.m
new file mode 100644
index 0000000..3cb072c
--- /dev/null
+++ b/inst/geom2d/vectorNorm.m
@@ -0,0 +1,114 @@
+%% 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} {@var{nm} = } vectorNorm (@var{v})
+%% @deftypefnx {Function File} {@var{nm} = } vectorNorm (@var{v},@var{n})
+%% Compute norm of a vector, or of a set of vectors
+%%
+%% Without extra arguments, returns the euclidean norm of vector V.
+%% Optional argument @var{n} specifies the norm to use. N can be any value
+%% greater than 0.
+%% @table @samp
+%% @item N=1
+%% City lock norm.
+%% @item N=2
+%% Euclidean norm.
+%% @item N=inf
+%% Compute max coord.
+%% @end table
+%%
+%% When @var{v} is a MxN array, compute norm for each vector of the array.
+%% Vector are given as rows. Result is then a Mx1 array.
+%%
+%% Example
+%%
+%% @example
+%% n1 = vectorNorm([3 4])
+%% n1 =
+%% 5
+%%
+%% n2 = vectorNorm([1, 10], inf)
+%% n2 =
+%% 10
+%% @end example
+%%
+%% @seealso{vectors2d, vectorAngle}
+%% @end deftypefn
+
+function n = vectorNorm(v, varargin)
+
+ % size of vector
+ dim = size(v);
+
+ % extract the type of norm to compute
+ d = 2;
+ if ~isempty(varargin)
+ d = varargin{1};
+ end
+
+ if d==2
+ % euclidean norm: sum of squared coordinates, and take square root
+ if dim(1)==1 || dim(2)==1
+ n = sqrt(sum(v.*v));
+ else
+ n = sqrt(sum(v.*v, 2));
+ end
+ elseif d==1
+ % absolute norm: sum of absolute coordinates
+ if dim(1)==1 || dim(2)==1
+ n = sum(abs(v));
+ else
+ n = sum(abs(v), 2);
+ end
+ elseif d==inf
+ % infinite norm: uses the maximal corodinate
+ if dim(1)==1 || dim(2)==1
+ n = max(v);
+ else
+ n = max(v, [], 2);
+ end
+ else
+ % Other norms, use explicit but slower expression
+ if dim(1)==1 || dim(2)==1
+ n = power(sum(power(v, d)), 1/d);
+ else
+ n = power(sum(power(v, d), 2), 1/d);
+ end
+ end
+
+endfunction
+
+%!assert (5, vectorNorm ([3 4]))
+%!assert(10, vectorNorm ([1, 10], inf))
+
diff --git a/inst/geom2d/vectors2d.m b/inst/geom2d/vectors2d.m
new file mode 100644
index 0000000..2f2bb88
--- /dev/null
+++ b/inst/geom2d/vectors2d.m
@@ -0,0 +1,54 @@
+%% Copyright (c) 2011, INRA
+%% 2008-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} vectors2d ()
+%% Description of functions operating on plane vectors
+%%
+%% A vector is defined by its two cartesian coordinates, put into a row
+%% vector of 2 elements:
+%% @code{V = [vx vy];}
+%%
+%% Several vectors are stored in a matrix with two columns, one for the
+%% x-coordinate, one for the y-coordinate.
+%% @code{VS = [vx1 vy1 ; vx2 vy2 ; vx3 vy3];}
+%%
+%% @seealso{vectorNorm, vectorAngle, isPerpendicular, isParallel,
+%% normalizeVector, transformVector, rotateVector}
+%% @end deftypefn
+
+function vectors2d
+
+ help('vectors2d');
+
+endfunction