]> Creatis software - CreaPhase.git/blob - octave_packages/geometry-1.5.0/polygons2d/polylineSelfIntersections.m
Add a useful package (from Source forge) for octave
[CreaPhase.git] / octave_packages / geometry-1.5.0 / polygons2d / polylineSelfIntersections.m
1 ## Copyright (C) 2003-2011 David Legland <david.legland@grignon.inra.fr>
2 ## Copyright (C) 2012 Adapted to Octave by Juan Pablo Carbajal <carbajal@ifi.uzh.ch>
3 ## All rights reserved.
4 ##
5 ## Redistribution and use in source and binary forms, with or without
6 ## modification, are permitted provided that the following conditions are met:
7 ##
8 ##     1 Redistributions of source code must retain the above copyright notice,
9 ##       this list of conditions and the following disclaimer.
10 ##     2 Redistributions in binary form must reproduce the above copyright
11 ##       notice, this list of conditions and the following disclaimer in the
12 ##       documentation and/or other materials provided with the distribution.
13 ##
14 ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ''AS IS''
15 ## AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 ## ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
18 ## ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 ## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
20 ## SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
21 ## CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
22 ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 ##
25 ## The views and conclusions contained in the software and documentation are
26 ## those of the authors and should not be interpreted as representing official
27 ## policies, either expressed or implied, of the copyright holders.
28
29 ## -*- texinfo -*-
30 ## @deftypefn {Function File} {@var{pts} = } polylineSelfIntersections (@var{poly})
31 ##   Find self-intersections points of a polyline
32 ##
33 ##   Return the position of self intersection points
34 ##
35 ##   Also return the 2 positions of each intersection point (the position
36 ##   when meeting point for first time, then position when meeting point
37 ##   for the second time).
38 ##
39 ##   Example
40 ## @example
41 ##       # use a gamma-shaped polyline
42 ##       poly = [0 0;0 10;20 10;20 20;10 20;10 0];
43 ##       polylineSelfIntersections(poly)
44 ##       ans = 
45 ##           10 10
46 ##
47 ##       # use a 'S'-shaped polyline
48 ##       poly = [10 0;0 0;0 10;20 10;20 20;10 20];
49 ##       polylineSelfIntersections(poly)
50 ##       ans = 
51 ##           10 10
52 ## @end example
53 ##   
54 ##  @seealso{polygons2d, intersectPolylines, polygonSelfIntersections}
55 ## @end deftypefn
56
57 function varargout = polylineSelfIntersections(poly, varargin)
58
59   ## Initialisations
60
61   # determine whether the polyline is closed
62   closed = false;
63   if ~isempty(varargin)
64       closed = varargin{1};
65       if ischar(closed)
66           if strcmp(closed, 'closed')
67               closed = true;
68           elseif strcmp(closed, 'open')
69               closed = false;
70           end
71       end
72   end
73
74   # if polyline is closed, ensure the last point equals the first one
75   if closed
76       if sum(abs(poly(end, :)-poly(1,:))<1e-14)~=2
77           poly = [poly; poly(1,:)];
78       end
79   end
80
81   # arrays for storing results
82   points  = zeros(0, 2);
83   pos1    = zeros(0, 1);
84   pos2    = zeros(0, 1);
85
86   # number of vertices
87   Nv = size(poly, 1);
88
89
90   ## Main processing
91
92   # index of current intersection
93   ip = 0;
94
95   # iterate over each couple of edge ( (N-1)*(N-2)/2 iterations)
96   for i=1:Nv-2
97       # create first edge
98       edge1 = [poly(i, :) poly(i+1, :)];
99       for j=i+2:Nv-1
100           # create second edge
101           edge2 = [poly(j, :) poly(j+1, :)];
102
103           # check conditions on bounding boxes
104           if min(edge1([1 3]))>max(edge2([1 3]))
105               continue;
106           end
107           if max(edge1([1 3]))<min(edge2([1 3]))
108               continue;
109           end
110           if min(edge1([2 4]))>max(edge2([2 4]))
111               continue;
112           end
113           if max(edge1([2 4]))<min(edge2([2 4]))
114               continue;
115           end
116           
117           # compute intersection point
118           inter = intersectEdges(edge1, edge2);
119           
120           if sum(isfinite(inter))==2
121               # add point to the list
122               ip = ip + 1;
123               points(ip, :) = inter;
124               
125               # also compute positions on the polyline
126               pos1(ip, 1) = i+edgePosition(inter, edge1)-1;
127               pos2(ip, 1) = j+edgePosition(inter, edge2)-1;
128           end
129       end
130   end
131
132   # if polyline is closed, the first vertex was found as an intersection, so
133   # we need to remove it
134   if closed
135       dist = distancePoints(points, poly(1,:));
136       [minDist ind] = min(dist); ##ok<ASGLU>
137       points(ind,:) = [];
138       pos1(ind)   = [];
139       pos2(ind)   = [];
140   end
141
142   ## Post-processing
143
144   # process output arguments
145   if nargout<=1
146       varargout{1} = points;
147   elseif nargout==3
148       varargout{1} = points;
149       varargout{2} = pos1;
150       varargout{3} = pos2;
151   end
152
153 endfunction