]> Creatis software - CreaPhase.git/blob - octave_packages/geometry-1.5.0/octclip/oc_polybool.m
Add a useful package (from Source forge) for octave
[CreaPhase.git] / octave_packages / geometry-1.5.0 / octclip / oc_polybool.m
1 ## Copyright (C) 2011, José Luis García Pallero, <jgpallero@gmail.com>
2 ##
3 ## This file is part of OctCLIP.
4 ##
5 ## OctCLIP is free software; you can redistribute it and/or modify it
6 ## under the terms of the GNU General Public License as published by
7 ## the Free Software Foundation; either version 3 of the License, or (at
8 ## your option) any later version.
9 ##
10 ## This program is distributed in the hope that it will be useful, but
11 ## WITHOUT ANY WARRANTY; without even the implied warranty of
12 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 ## General Public License for more details.
14 ##
15 ## You should have received a copy of the GNU General Public License
16 ## along with Octave; see the file COPYING.  If not, see
17 ## <http://www.gnu.org/licenses/>.
18
19 ## -*- texinfo -*-
20 ## @deftypefn{Function File}{[@var{X},@var{Y},@var{nPol},@var{nInt},@var{nPert}] =}_oc_polybool(@var{sub},@var{clip},@var{op})
21 ## @deftypefnx{Function File}{[@var{X},@var{Y},@var{nPol},@var{nInt},@var{nPert}] =}_oc_polybool(@var{sub},@var{clip})
22 ##
23 ## This function performs boolean operations between two polygons using the
24 ## Greiner-Hormann algorithm (http://davis.wpi.edu/~matt/courses/clipping/).
25 ##
26 ## @var{sub} is a two column matrix containing the X and Y coordinates of the
27 ## vertices for the subject polygon.
28 ##
29 ## @var{clip} is a two column matrix containing the X and Y coordinates of the
30 ## vertices for the clipper polygon.
31 ##
32 ## @var{op} is a text string containing the operation to perform between
33 ## @var{sub} and @var{clip}. Possible values are:
34 ##
35 ## @itemize @bullet
36 ## @item @var{'AND'}
37 ## Intersection of @var{sub} and @var{clip} (value by default).
38 ## @item @var{'OR'}
39 ## Union of @var{subt} and @var{clip}.
40 ## @item @var{'AB'}
41 ## Operation @var{sub} - @var{clip}.
42 ## @item @var{'BA'}
43 ## Operation of @var{clip} - @var{sub}.
44 ## @end itemize
45 ##
46 ## For the matrices @var{sub} and @var{clip}, the first point is not needed to
47 ## be repeated at the end (but is permitted). Pairs of (NaN,NaN) coordinates in
48 ## @var{sub} and/or @var{clip} are omitted.
49 ##
50 ## @var{X} is a column vector containing the X coordinates of the vertices for.
51 ## resultant polygon(s).
52 ##
53 ## @var{Y} is a column vector containing the Y coordinates of the vertices for.
54 ## resultant polygon(s).
55 ##
56 ## @var{nPol} is the number of output polygons.
57 ##
58 ## @var{nInt} is the number of intersections between @var{sub} and @var{clip}.
59 ##
60 ## @var{nPert} is the number of perturbed points of the @var{clip} polygon in
61 ## any particular case (points in the oborder of the other polygon) occurs see
62 ## http://davis.wpi.edu/~matt/courses/clipping/ for details.
63 ## @end deftypefn
64
65
66
67
68 function [X,Y,nPol,nInt,nPert] = oc_polybool(sub,clip,op)
69
70 try
71     functionName = 'oc_polybool';
72     minArg = 2;
73     maxArg = 3;
74
75 %*******************************************************************************
76 %NUMBER OF INPUT ARGUMENTS CHECKING
77 %*******************************************************************************
78
79     %number of input arguments checking
80     if (nargin<minArg)||(nargin>maxArg)
81         error(['Incorrect number of input arguments (%d)\n\t         ',...
82                'Correct number of input arguments = %d or %d'],...
83               nargin,minArg,maxArg);
84     end
85     %check if we omit the op argument
86     if nargin==minArg
87         %by default, use AND
88         op = 'AND';
89     end
90
91 %*******************************************************************************
92 %INPUT ARGUMENTS CHECKING
93 %*******************************************************************************
94
95     %checking input arguments
96     [op] = checkInputArguments(sub,clip,op);
97 catch
98     %error message
99     error('\n\tIn function %s:\n\t -%s ',functionName,lasterr);
100 end
101
102 %*******************************************************************************
103 %COMPUTATION
104 %*******************************************************************************
105
106 try
107     %calling oct function
108     [X,Y,nPol,nInt,nPert] = _oc_polybool(sub,clip,op);
109 catch
110     %error message
111     error('\n\tIn function %s:\n\tIn function %s ',functionName,lasterr);
112 end
113
114
115
116
117 %*******************************************************************************
118 %AUXILIARY FUNCTION
119 %*******************************************************************************
120
121
122
123
124 function [outOp] = checkInputArguments(sub,clip,inOp)
125
126 %sub must be matrix type
127 if ismatrix(sub)
128     %a dimensions
129     [rowSub,colSub] = size(sub);
130 else
131     error('The first input argument is not numeric');
132 end
133 %clip must be matrix type
134 if ismatrix(clip)
135     %b dimensions
136     [rowClip,colClip] = size(clip);
137 else
138     error('The second input argument is not numeric');
139 end
140 %checking dimensions
141 if (colSub~=2)||(colClip~=2)
142     error('The columns of input arguments must be 2');
143 end
144 %operation must be a text string
145 if ~ischar(inOp)
146     error('The third input argument is not a text string');
147 else
148     %upper case
149     outOp = toupper(inOp);
150     %check values
151     if (~strcmp(outOp,'AND'))&&(~strcmp(outOp,'OR'))&& ...
152         (~strcmp(outOp,'AB'))&&(~strcmp(outOp,'BA'))
153         error('The third input argument is not correct');
154     end
155 end
156
157
158
159
160 %*****END OF FUNCIONS*****
161
162
163
164
165 %*****FUNCTION TESTS*****
166
167
168
169
170 %tests for input arguments
171 %!error(oc_polybool)
172 %!error(oc_polybool(1,2,3,4))
173 %!error(oc_polybool('string',2,3))
174 %!error(oc_polybool(1,'string',3))
175 %!error(oc_polybool(1,2,3))
176 %demo program
177 %!demo
178 %!  %subject polygon
179 %!  clSub = [9.0 7.5
180 %!           9.0 3.0
181 %!           2.0 3.0
182 %!           2.0 4.0
183 %!           8.0 4.0
184 %!           8.0 5.0
185 %!           2.0 5.0
186 %!           2.0 6.0
187 %!           8.0 6.0
188 %!           8.0 7.0
189 %!           2.0 7.0
190 %!           2.0 7.5
191 %!           9.0 7.5];
192 %!  %clipper polygon
193 %!  clClip = [2.5 1.0
194 %!            7.0 1.0
195 %!            7.0 8.0
196 %!            6.0 8.0
197 %!            6.0 2.0
198 %!            5.0 2.0
199 %!            5.0 8.0
200 %!            4.0 8.0
201 %!            4.0 2.0
202 %!            3.0 2.0
203 %!            3.0 8.0
204 %!            2.5 8.0
205 %!            2.5 1.0];
206 %!  %limits for the plots
207 %!  clXLim = [1.5 11.75];
208 %!  clYLim = [0.5  8.50];
209 %!  %compute intersection
210 %!  [clXI,clYI] = oc_polybool(clSub,clClip,'and');
211 %!  %compute union
212 %!  [clXU,clYU] = oc_polybool(clSub,clClip,'or');
213 %!  %compute A-B
214 %!  [clXA,clYA] = oc_polybool(clSub,clClip,'ab');
215 %!  %compute B-A
216 %!  [clXB,clYB] = oc_polybool(clSub,clClip,'ba');
217 %!  %plot window for intersection
218 %!  subplot(2,2,1);
219 %!  plot(clXI,clYI,'r.-','markersize',10,'linewidth',3,clSub(:,1),clSub(:,2),...
220 %!       clClip(:,1),clClip(:,2));
221 %!  axis('equal');
222 %!  xlim(clXLim);
223 %!  ylim(clYLim);
224 %!  title('OctCLIP intersection');
225 %!  legend('Intersection','Subject polygon','Clipper polygon',...
226 %!         'location','southeast');
227 %!  %plot window for union
228 %!  subplot(2,2,2);
229 %!  plot(clXU,clYU,'r.-','markersize',10,'linewidth',3,clSub(:,1),clSub(:,2),...
230 %!       clClip(:,1),clClip(:,2));
231 %!  axis('equal');
232 %!  xlim(clXLim);
233 %!  ylim(clYLim);
234 %!  title('OctCLIP union');
235 %!  legend('Union','Subject polygon','Clipper polygon','location','southeast');
236 %!  %plot window for A-B
237 %!  subplot(2,2,3);
238 %!  plot(clXA,clYA,'r.-','markersize',10,'linewidth',3,clSub(:,1),clSub(:,2),...
239 %!       clClip(:,1),clClip(:,2));
240 %!  axis('equal');
241 %!  xlim(clXLim);
242 %!  ylim(clYLim);
243 %!  title('OctCLIP A-B');
244 %!  legend('A-B','Subject polygon','Clipper polygon','location','southeast');
245 %!  %plot window for B-A
246 %!  subplot(2,2,4);
247 %!  plot(clXB,clYB,'r.-','markersize',10,'linewidth',3,clSub(:,1),clSub(:,2),...
248 %!       clClip(:,1),clClip(:,2));
249 %!  axis('equal');
250 %!  xlim(clXLim);
251 %!  ylim(clYLim);
252 %!  title('OctCLIP B-A');
253 %!  legend('B-A','Subject polygon','Clipper polygon','location','southeast');
254 %!  %input message
255 %!  disp('Press ENTER to continue ...');
256 %!  pause();
257 %!  %kill and close the plot window
258 %!  clf();
259 %!  close();
260
261
262
263
264 %*****END OF TESTS*****