7fd59977 |
1 | // File: IntCurve_Polygon2dGen.gxx |
2 | // Created: Mon Oct 12 17:17:30 1992 |
3 | // Author: Laurent BUCHARD |
7fd59977 |
4 | |
5 | #define TEST 0 |
6 | |
7fd59977 |
7 | #include <Standard_ConstructionError.hxx> |
8 | #include <Bnd_Box2d.hxx> |
9 | #include <TColgp_Array1OfPnt2d.hxx> |
10 | #include <gp_Lin2d.hxx> |
11 | #include <gp_Vec2d.hxx> |
12 | #include <gp_Dir2d.hxx> |
13 | |
14 | |
7fd59977 |
15 | #define MAJORATION_DEFLECTION 1.5 |
16 | //====================================================================== |
17 | //== On echantillonne sur le Domain de la Curve NbPts Points |
18 | //== a parametres constants. |
19 | //== |
20 | //== On estime la fleche maximum en prenant la distance maxi entre la |
21 | //== droite Curve.Value(X(i))-->Curve.Value(X(i+1)) |
22 | //== et le point Curve.Value(X(i+1/2)) |
23 | //====================================================================== |
24 | // Modified by Sergey KHROMOV - Mon Mar 24 12:02:43 2003 Begin |
25 | IntCurve_Polygon2dGen::IntCurve_Polygon2dGen(const TheCurve& C, |
26 | const Standard_Integer tNbPts, |
27 | const IntRes2d_Domain& D, |
28 | const Standard_Real Tol): |
29 | // const Standard_Real ): |
30 | // Modified by Sergey KHROMOV - Mon Mar 24 12:02:45 2003 End |
31 | ThePnts(1,(tNbPts<3)? 6 : (tNbPts+tNbPts)), |
32 | TheParams(1,(tNbPts<3)? 6 : (tNbPts+tNbPts)), |
33 | TheIndex(1,(tNbPts<3)? 6 : (tNbPts+tNbPts)) |
34 | { |
35 | |
36 | Standard_Integer NbPts = (tNbPts<3)? 3 : tNbPts; |
37 | TheMaxNbPoints = NbPts+NbPts; |
38 | NbPntIn = NbPts; |
39 | //----------------------------------------------------- |
40 | //--- Initialisation du Brise a d_Parametre constant |
41 | //--- |
42 | Binf = D.FirstParameter(); |
43 | Bsup = D.LastParameter(); |
44 | //----------------------------------------------------- |
45 | //-- IntRes2d Raise si HasFirst retourne False |
46 | //-- et Acces a First Parameter |
47 | //-- |
48 | Standard_Real u=Binf; |
49 | Standard_Real u1=Bsup; |
50 | Standard_Real du=(u1-u)/(Standard_Real)(NbPts-1); |
51 | // Standard_Integer ip1,i=1; |
52 | Standard_Integer i=1; |
53 | |
54 | do { |
55 | gp_Pnt2d P=TheCurveTool::Value(C,u); |
9530af27 |
56 | myBox.Add(P); |
7fd59977 |
57 | TheIndex.SetValue(i,i); |
58 | ThePnts.SetValue(i,P); |
59 | TheParams.SetValue(i,u); |
60 | u+=du; |
61 | i++; |
62 | } |
63 | while(i<=NbPts); |
64 | |
65 | |
66 | //----------------------------------------------------- |
67 | //--- Calcul d un majorant de fleche approche |
68 | //--- |
69 | // Modified by Sergey KHROMOV - Mon Mar 24 12:03:05 2003 Begin |
70 | // TheDeflection = 0.000000001; |
71 | TheDeflection = Min(0.000000001, Tol/100.); |
72 | // Modified by Sergey KHROMOV - Mon Mar 24 12:03:05 2003 End |
73 | i=1; |
74 | u=D.FirstParameter(); |
75 | u+=du * 0.5; |
76 | |
77 | do { |
78 | gp_Pnt2d Pm = TheCurveTool::Value(C,u); |
79 | const gp_Pnt2d& P1 = ThePnts.Value(i); |
80 | const gp_Pnt2d& P2 = ThePnts.Value(i+1); |
81 | |
82 | u+=du; |
83 | i++; |
84 | |
85 | |
86 | Standard_Real dx,dy,t=0; |
87 | dx=P1.X()-P2.X(); if(dx<0) dx=-dx; |
88 | dy=P1.Y()-P2.Y(); if(dy<0) dy=-dy; |
89 | if(dx+dy>1e-12) { |
90 | gp_Lin2d L(P1,gp_Dir2d(gp_Vec2d(P1,P2))); |
91 | t = L.Distance(Pm); |
92 | if(t>TheDeflection) { |
93 | TheDeflection = t; |
94 | } |
95 | } |
96 | } |
97 | while(i<NbPts); |
98 | |
9530af27 |
99 | myBox.Enlarge(TheDeflection*MAJORATION_DEFLECTION); |
7fd59977 |
100 | ClosedPolygon = Standard_False; |
101 | } |
102 | //====================================================================== |
103 | // Modified by Sergey KHROMOV - Mon Mar 24 12:03:26 2003 Begin |
104 | IntCurve_Polygon2dGen::IntCurve_Polygon2dGen(const TheCurve& C, |
105 | const Standard_Integer tNbPts, |
106 | const IntRes2d_Domain& D, |
107 | const Standard_Real Tol, |
108 | const Bnd_Box2d& BoxOtherPolygon): |
109 | // Modified by Sergey KHROMOV - Mon Mar 24 12:03:28 2003 End |
110 | ThePnts(1,(tNbPts<3)? 6 : (tNbPts+tNbPts)), |
111 | TheParams(1,(tNbPts<3)? 6 : (tNbPts+tNbPts)), |
112 | TheIndex(1,(tNbPts<3)? 6 : (tNbPts+tNbPts)) |
113 | { |
114 | Standard_Integer NbPts = (tNbPts<3)? 3 : tNbPts; |
115 | TheMaxNbPoints = NbPts+NbPts; |
116 | NbPntIn = NbPts; |
117 | //----------------------------------------------------- |
118 | //--- Initialisation du Brise a d_Parametre constant |
119 | //--- |
120 | Binf = D.FirstParameter(); |
121 | Bsup = D.LastParameter(); |
122 | //----------------------------------------------------- |
123 | Standard_Real u=Binf; |
124 | Standard_Real u1=Bsup; |
125 | Standard_Real du=(u1-u)/(Standard_Real)(NbPts-1); |
126 | Standard_Integer i=1; |
127 | do { |
128 | gp_Pnt2d P=TheCurveTool::Value(C,u); |
9530af27 |
129 | myBox.Add(P); |
7fd59977 |
130 | ThePnts.SetValue(i,P); |
131 | TheParams.SetValue(i,u); |
132 | TheIndex.SetValue(i,i); |
133 | u+=du; |
134 | i++; |
135 | } |
136 | while(i<=NbPts); |
137 | |
138 | |
139 | //----------------------------------------------------- |
140 | //--- Calcul d un majorant de fleche approche |
141 | //--- |
142 | // Modified by Sergey KHROMOV - Mon Mar 24 12:03:55 2003 Begin |
143 | // TheDeflection = 0.0000001; |
144 | TheDeflection = Min(0.0000001, Tol/100.); |
145 | // Modified by Sergey KHROMOV - Mon Mar 24 12:03:56 2003 End |
146 | i=1; |
147 | u=D.FirstParameter(); |
148 | u+=du * 0.5; |
149 | |
150 | do { |
151 | gp_Pnt2d Pm = TheCurveTool::Value(C,u); |
152 | const gp_Pnt2d& P1 = ThePnts.Value(i); |
153 | const gp_Pnt2d& P2 = ThePnts.Value(i+1); |
154 | |
155 | Standard_Real dx,dy; |
156 | dx=P1.X()-P2.X(); if(dx<0) dx=-dx; |
157 | dy=P1.Y()-P2.Y(); if(dy<0) dy=-dy; |
158 | if(dx+dy>1e-12) { |
159 | gp_Lin2d L(P1,gp_Dir2d(gp_Vec2d(P1,P2))); |
160 | Standard_Real t = L.Distance(Pm); |
161 | if(t>TheDeflection) { |
162 | TheDeflection = t; |
163 | } |
164 | } |
165 | u+=du; |
166 | i++; |
167 | } |
168 | while(i<NbPts); |
169 | |
9530af27 |
170 | myBox.Enlarge(TheDeflection*MAJORATION_DEFLECTION); |
7fd59977 |
171 | ClosedPolygon = Standard_False; |
172 | //------------------------------------------------------- |
173 | //-- On supprime les points alignes |
174 | //-- (Permet de diminuer le nombre total de points) |
175 | //-- (Dans le cas ou la courbe est "droite" ) |
176 | Standard_Real DeflectionMaj = TheDeflection; |
177 | for(i=2;i<NbPntIn && NbPntIn>3;i++) { |
178 | Standard_Integer indexim1 = TheIndex.Value(i-1); |
179 | Standard_Integer indexi = TheIndex.Value(i); |
180 | Standard_Integer indexip1 = TheIndex.Value(i+1); |
181 | const gp_Pnt2d& Pim1 = ThePnts.Value(indexim1); |
182 | const gp_Pnt2d& Pi = ThePnts.Value(indexi); |
183 | const gp_Pnt2d& Pip1 = ThePnts.Value(indexip1); |
184 | |
185 | Standard_Real dx,dy; |
186 | dx=Pim1.X()-Pip1.X(); if(dx<0) dx=-dx; |
187 | dy=Pim1.Y()-Pip1.Y(); if(dy<0) dy=-dy; |
188 | Standard_Real t=0; |
189 | if(dx+dy>1e-12) { |
190 | gp_Lin2d L(Pim1,gp_Dir2d(gp_Vec2d(Pim1,Pip1))); |
191 | t = L.Distance(Pi); |
192 | } |
193 | if(t<=DeflectionMaj) { |
194 | //-- On supprime le point i |
195 | for(Standard_Integer j = i; j<NbPntIn; j++) { |
196 | TheIndex.SetValue(j,TheIndex.Value(j+1)); |
197 | } |
198 | NbPntIn--; |
199 | i--; |
200 | } |
201 | } |
202 | |
203 | ComputeWithBox(C,BoxOtherPolygon); |
204 | } |
205 | //====================================================================== |
206 | void IntCurve_Polygon2dGen::ComputeWithBox(const TheCurve& C, |
207 | const Bnd_Box2d& BoxOtherPolygon) { |
9530af27 |
208 | if(myBox.IsOut(BoxOtherPolygon)) { |
7fd59977 |
209 | NbPntIn=2; |
9530af27 |
210 | myBox.SetVoid(); |
7fd59977 |
211 | } |
212 | else { |
213 | Standard_Real bx0,bx1,by0,by1; |
214 | BoxOtherPolygon.Get(bx0,by0,bx1,by1); |
215 | |
216 | bx0-=TheDeflection; |
217 | by0-=TheDeflection; |
218 | bx1+=TheDeflection; |
219 | by1+=TheDeflection; |
220 | Standard_Integer MaxIndexUsed = 1; |
221 | Standard_Integer i,nbp; |
222 | Standard_Integer Rprec,Ri; |
223 | Standard_Real x,y; |
224 | |
225 | nbp = 0; |
226 | x = ThePnts.Value(TheIndex.Value(1)).X(); |
227 | y = ThePnts.Value(TheIndex.Value(1)).Y(); |
228 | |
229 | Rprec = CalculRegion(x,y,bx0,bx1,by0,by1); |
230 | for(i = 2; i<=NbPntIn; i++) { |
231 | const gp_Pnt2d& P2d = ThePnts.Value(TheIndex.Value(i)); |
232 | Ri = CalculRegion(P2d.X(),P2d.Y(),bx0,bx1,by0,by1); |
233 | if((Ri & Rprec)==0) { |
234 | if(nbp) { |
235 | if(TheIndex.Value(nbp) != TheIndex.Value(i-1)) { |
236 | nbp++; |
237 | TheIndex.SetValue(nbp,TheIndex.Value(i-1)); |
238 | } |
239 | } |
240 | else { |
241 | nbp++; |
242 | TheIndex.SetValue(nbp,TheIndex.Value(i-1)); |
243 | } |
244 | nbp++; |
245 | TheIndex.SetValue(nbp,TheIndex.Value(i)); |
246 | if(TheIndex.Value(i) > MaxIndexUsed) MaxIndexUsed = TheIndex.Value(i); |
247 | |
248 | Rprec = Ri; |
249 | } |
250 | else { |
251 | if((Ri & Rprec)==0) { |
252 | nbp++; |
253 | TheIndex.SetValue(nbp,TheIndex.Value(i)); |
254 | if(TheIndex.Value(i) > MaxIndexUsed) MaxIndexUsed = TheIndex.Value(i); |
255 | |
256 | Rprec = Ri; |
257 | } |
258 | } |
259 | Rprec = Ri; |
260 | } |
261 | if(nbp==1) { |
262 | NbPntIn=2; |
9530af27 |
263 | myBox.SetVoid(); |
7fd59977 |
264 | } |
265 | else { |
9530af27 |
266 | myBox.SetVoid(); |
7fd59977 |
267 | if(nbp) { |
9530af27 |
268 | myBox.Add(ThePnts.Value(TheIndex.Value(1))); |
7fd59977 |
269 | } |
270 | Standard_Real RatioDeflection; |
271 | Standard_Integer nbpassagedeflection = 0; |
272 | // Standard_Integer PointHasBeenAdded = 0; |
273 | do { |
274 | nbpassagedeflection++; |
275 | // Modified by Sergey KHROMOV - Mon Mar 24 12:05:28 2003 Begin |
276 | // Standard_Real NewDeflection = 0.0000001; |
277 | Standard_Real NewDeflection = TheDeflection; |
278 | // Modified by Sergey KHROMOV - Mon Mar 24 12:05:29 2003 End |
279 | for(i=2; i<=nbp; i++) { |
280 | Standard_Integer Ii = TheIndex.Value(i); |
281 | Standard_Integer Iim1= TheIndex.Value(i-1); |
282 | const gp_Pnt2d& Pi = ThePnts.Value(Ii); |
283 | const gp_Pnt2d& Pim1 = ThePnts.Value(Iim1); |
9530af27 |
284 | myBox.Add(Pi); |
7fd59977 |
285 | Standard_Integer Regi = CalculRegion(Pi.X(),Pi.Y(),bx0,bx1,by0,by1); |
286 | Standard_Integer Regim1 = CalculRegion(Pim1.X(),Pim1.Y(),bx0,bx1,by0,by1); |
287 | if((Regi & Regim1) == 0) { |
288 | Standard_Real u = 0.5*( TheParams.Value(Ii) |
289 | +TheParams.Value(Iim1)); |
290 | gp_Pnt2d Pm = TheCurveTool::Value(C,u); |
291 | Standard_Real dx,dy,t=0; |
292 | dx=Pim1.X()-Pi.X(); if(dx<0) dx=-dx; |
293 | dy=Pim1.Y()-Pi.Y(); if(dy<0) dy=-dy; |
294 | if(dx+dy>1e-12) { |
295 | gp_Lin2d L(Pim1,gp_Dir2d(gp_Vec2d(Pim1,Pi))); |
296 | t = L.Distance(Pm); |
297 | if((MaxIndexUsed<(TheMaxNbPoints-1)) && (t>(TheDeflection * 0.5))) { |
298 | const gp_Pnt2d& P1=Pim1; |
299 | nbp++; |
300 | for(Standard_Integer j=nbp; j>=i+1; j--) { |
301 | TheIndex.SetValue(j,TheIndex.Value(j-1)); |
302 | } |
303 | MaxIndexUsed++; |
304 | TheIndex.SetValue(i,MaxIndexUsed); |
305 | ThePnts.SetValue(MaxIndexUsed,Pm); |
306 | TheParams.SetValue(MaxIndexUsed,u); |
307 | |
308 | Standard_Real u1m = 0.5*(u+TheParams.Value(TheIndex.Value(i-1))); |
309 | Standard_Real um2 = 0.5*(u+TheParams.Value(TheIndex.Value(i+1))); |
310 | gp_Pnt2d P1m = TheCurveTool::Value(C,u1m); |
311 | #ifdef DEB |
312 | gp_Pnt2d Pm2 = TheCurveTool::Value(C,um2); |
313 | #else |
314 | TheCurveTool::Value(C,um2); |
315 | #endif |
316 | gp_Lin2d L1m(P1,gp_Dir2d(gp_Vec2d(P1,Pm))); |
317 | #ifdef DEB |
318 | gp_Lin2d Lm2(Pm,gp_Dir2d(gp_Vec2d(Pm,ThePnts.Value(TheIndex.Value(i+1))))); |
319 | #else |
320 | ThePnts.Value(TheIndex.Value(i+1)); |
321 | #endif |
322 | t = L1m.Distance(P1m); |
323 | i--; |
324 | } |
325 | } |
326 | else { |
327 | if(t>NewDeflection) { |
328 | NewDeflection = t; |
329 | } |
330 | } |
331 | } |
332 | } |
333 | if(NewDeflection) |
334 | RatioDeflection = TheDeflection / NewDeflection; |
335 | else RatioDeflection = 10.0; |
336 | TheDeflection = NewDeflection; |
337 | NbPntIn = nbp; |
338 | } |
339 | while((RatioDeflection<3.0) |
340 | && (nbpassagedeflection < 3) |
341 | && (MaxIndexUsed<(TheMaxNbPoints-2))); |
342 | } |
343 | |
344 | TheDeflection*=MAJORATION_DEFLECTION; |
9530af27 |
345 | myBox.Enlarge(TheDeflection); |
7fd59977 |
346 | } |
347 | ClosedPolygon = Standard_False; |
348 | Dump(); |
349 | } |
350 | |
351 | |
352 | Standard_Boolean IntCurve_Polygon2dGen::AutoIntersectionIsPossible() const { |
353 | |
354 | gp_Vec2d VRef(ThePnts.Value(TheIndex.Value(1)), |
355 | ThePnts.Value(TheIndex.Value(2))); |
356 | for(Standard_Integer i=3; i<=NbPntIn; i++) { |
357 | gp_Vec2d V(ThePnts.Value(TheIndex.Value(i-1)), |
358 | ThePnts.Value(TheIndex.Value(i))); |
359 | if(V.Dot(VRef)<0.0) { |
360 | return(Standard_True); |
361 | } |
362 | } |
363 | return(Standard_False); |
364 | } |
365 | |
366 | //====================================================================== |
367 | Standard_Real IntCurve_Polygon2dGen::ApproxParamOnCurve( const Standard_Integer Aindex |
368 | ,const Standard_Real TheParamOnLine) |
369 | const |
370 | { |
371 | Standard_Integer Indexp1,Index = Aindex; |
372 | Standard_Real ParamOnLine = TheParamOnLine; |
373 | if (Index > NbPntIn) { |
374 | cout << "OutOfRange Polygon2d::ApproxParamOnCurve " <<endl; |
375 | } |
376 | if((Index == NbPntIn) && (ParamOnLine == 0.0)) { |
377 | Index--; ParamOnLine=1.0; |
378 | } |
379 | if(Index==0) { |
380 | Index=1; |
381 | ParamOnLine = 0.0; |
382 | } |
383 | Indexp1 = TheIndex.Value(Index+1); |
384 | Index = TheIndex.Value(Index); |
385 | |
386 | Standard_Real du = TheParams.Value(Indexp1)-TheParams.Value(Index); |
387 | Standard_Real u = TheParams.Value(Index) + ParamOnLine * du; |
388 | return(u); |
389 | } |
390 | |
391 | |
392 | //====================================================================== |
393 | #if TEST |
394 | |
395 | extern Standard_Boolean DebugPolygon2d; |
396 | extern void DrawSegmentBlanc(const gp_Pnt2d& _P1,const gp_Pnt2d& _P2); |
397 | extern void DrawSegment(const gp_Pnt2d& _P1,const gp_Pnt2d& _P2); |
398 | |
399 | void IntCurve_Polygon2dGen::Dump(void) const { |
400 | if(!DebugPolygon2d) return; |
401 | Standard_Real bx0,bx1,by0,by1; |
9530af27 |
402 | if(myBox.IsVoid()) return; |
403 | myBox.Get(bx0,by0,bx1,by1); |
7fd59977 |
404 | DrawSegment(gp_Pnt2d(bx0,by0),gp_Pnt2d(bx1,by0)); |
405 | DrawSegment(gp_Pnt2d(bx1,by0),gp_Pnt2d(bx1,by1)); |
406 | DrawSegment(gp_Pnt2d(bx1,by1),gp_Pnt2d(bx0,by1)); |
407 | DrawSegment(gp_Pnt2d(bx0,by1),gp_Pnt2d(bx0,by0)); |
408 | Standard_Integer i; |
409 | if(NbPntIn<=1) return; |
410 | for(i=2;i<=NbPntIn; i++) { |
411 | DrawSegmentBlanc(ThePnts.Value(TheIndex.Value(i-1)),ThePnts.Value(TheIndex.Value(i))); |
412 | } |
413 | } |
414 | #else |
415 | void IntCurve_Polygon2dGen::Dump(void) const { |
416 | static int debug = 0; |
417 | if(debug) { |
418 | Standard_Real bx0,bx1,by0,by1; |
419 | |
420 | cout<<"\n ----- Dump de IntCurve_Polygon2dGen -----"<<endl; |
9530af27 |
421 | if(myBox.IsVoid()) { |
7fd59977 |
422 | cout<<" Polygone Vide "<<endl; |
423 | return; |
424 | } |
9530af27 |
425 | myBox.Get(bx0,by0,bx1,by1); |
7fd59977 |
426 | cout<<" bx0:"<<bx0 <<endl; |
427 | cout<<" by0:"<<by0<<endl; |
428 | cout<<" bx1:"<<bx1<<endl; |
429 | cout<<" by1:"<<by1<<endl; |
430 | |
431 | Standard_Integer i; |
432 | for(i=1;i<=NbPntIn; i++) { |
433 | const gp_Pnt2d& P = ThePnts(TheIndex(i)); |
434 | cout<<" ("<<i<<") u:"<<TheParams.Value(TheIndex(i))<<" X:"<<P.X()<<" Y:"<<P.Y()<<endl; |
435 | } |
436 | } |
437 | } |
438 | #endif |
439 | //====================================================================== |
9530af27 |
440 | void IntCurve_Polygon2dGen::Segment(const Standard_Integer theIndex, |
441 | gp_Pnt2d &theBegin, gp_Pnt2d &theEnd) const |
442 | { |
443 | Standard_Integer ind = theIndex; |
444 | theBegin = ThePnts(TheIndex(theIndex)); |
445 | if (theIndex >= NbPntIn) { |
446 | if (!ClosedPolygon) |
447 | Standard_OutOfRange::Raise("IntCurve_Polygon2dGen::Segment!"); |
448 | ind = 0; |
449 | } |
450 | theEnd = ThePnts(TheIndex(ind+1)); |
451 | } |
7fd59977 |
452 | //====================================================================== |