0022241: The bug is appendix to the Salome Bug 0021148
[occt.git] / src / Extrema / Extrema_GExtCC2d.gxx
CommitLineData
7fd59977 1// File: Extrema_GExtCC2d.gxx
2// Created: Wed Jul 6 15:08:36 1994
3// Author: Laurent PAINNOT
4// <lpa@metrox>
5
6
7#include Extrema_ECC2d_hxx
8#include <Extrema_ExtElC2d.hxx>
9#include <StdFail_NotDone.hxx>
10#include <Extrema_ExtElC.hxx>
11#include <ElCLib.hxx>
12#include <Standard_Failure.hxx>
13#include <GeomAbs_CurveType.hxx>
14#include <Geom2d_Curve.hxx>
15#include <Geom2d_TrimmedCurve.hxx>
16#include <Geom2d_Ellipse.hxx>
17#include <Geom2d_Circle.hxx>
18#include <Geom2d_Line.hxx>
19#include <Geom2d_Parabola.hxx>
20#include <Geom2d_Hyperbola.hxx>
21#include <Extrema_POnCurv2d.hxx>
22#include <Extrema_SequenceOfPOnCurv2d.hxx>
23#include <Standard_NotImplemented.hxx>
24#include <Precision.hxx>
25
26
27Extrema_GExtCC2d::Extrema_GExtCC2d() {}
28
29
30Extrema_GExtCC2d::Extrema_GExtCC2d(const Curve1& C1,
31 const Curve2& C2,
32 const Standard_Real TolC1,
33 const Standard_Real TolC2)
34{
35 Initialize(C2, Tool2::FirstParameter(C2), Tool2::LastParameter(C2), TolC1, TolC2);
36 Perform(C1, Tool1::FirstParameter(C1), Tool1::LastParameter(C1));
37}
38
39Extrema_GExtCC2d::Extrema_GExtCC2d(const Curve1& C1,
40 const Curve2& C2,
41 const Standard_Real U1,
42 const Standard_Real U2,
43 const Standard_Real V1,
44 const Standard_Real V2,
45 const Standard_Real TolC1,
46 const Standard_Real TolC2)
47{
48 Initialize(C2, V1, V2, TolC1, TolC2);
49 Perform(C1, U1, U2);
50}
51
52
53
54void Extrema_GExtCC2d::Initialize(const Curve2& C2,
55 const Standard_Real V1,
56 const Standard_Real V2,
57 const Standard_Real TolC1,
58 const Standard_Real TolC2)
59{
60 myC = (Standard_Address)&C2;
61 myv1 = V1;
62 myv2 = V2;
63 mytolc1 = TolC1;
64 mytolc2 = TolC2;
65}
66
67
68
69void Extrema_GExtCC2d::Perform (const Curve1& C1,
70 const Standard_Real U1,
71 const Standard_Real U2)
72{
73 mypoints.Clear();
74 mySqDist.Clear();
75 Standard_Integer NbU = 32, NbV = 32;
76 GeomAbs_CurveType type1 = Tool1::GetType(C1), type2 = Tool2::GetType(*((Curve2*)myC));
77 Standard_Real U11, U12, U21, U22, Tol = Min(mytolc1, mytolc2);
78// Extrema_POnCurv2d P1, P2;
79 mynbext = 0;
80 inverse = Standard_False;
81 myIsPar = Standard_False;
82
83 U11 = U1;
84 U12 = U2;
85 U21 = myv1;
86 U22 = myv2;
87 P1f = Tool1::Value(C1, U11);
88 P1l = Tool1::Value(C1, U12);
89 P2f = Tool2::Value(*((Curve2*)myC), U21);
90 P2l = Tool2::Value(*((Curve2*)myC), U22);
91
92
93 switch(type1) {
94 //
95 // La premiere courbe est un cercle:
96 //
97 case GeomAbs_Circle: {
98
99 switch(type2) {
100 case GeomAbs_Circle: {
101 Extrema_ExtElC2d Xtrem(Tool1::Circle(C1), Tool2::Circle(*((Curve2*)myC)));
102 Results(Xtrem, U11, U12, U21, U22, 2*PI, 2*PI);
103 }
104 break;
105 case GeomAbs_Ellipse: {
106 Extrema_ExtElC2d Xtrem(Tool1::Circle(C1), Tool2::Ellipse(*((Curve2*)myC)));
107 Results(Xtrem, U11, U12, U21, U22, 2*PI, 2*PI );
108 }
109 break;
110 case GeomAbs_Parabola: {
111 Extrema_ExtElC2d Xtrem(Tool1::Circle(C1), Tool2::Parabola(*((Curve2*)myC)));
112 Results(Xtrem, U11, U12, U21, U22, 2*PI, 0.);
113 }
114 break;
115 case GeomAbs_Hyperbola: {
116 Extrema_ExtElC2d Xtrem(Tool1::Circle(C1), Tool2::Hyperbola(*((Curve2*)myC)));
117 Results(Xtrem, U11, U12, U21, U22, 2*PI, 0. );
118 }
119 break;
120 case GeomAbs_BezierCurve:
121 case GeomAbs_OtherCurve:
122 case GeomAbs_BSplineCurve: {
123 Extrema_ECC2d Xtrem(C1, *((Curve2*)myC),
124 NbU, NbV, mytolc1, mytolc2);
125 Standard_Real Period2 = 0.;
126 if (Tool2::IsPeriodic(*((Curve2*)myC))) Period2 = Tool2::Period(*((Curve2*)myC));
127 Results(Xtrem, C1, U11, U12, U21, U22, 2*PI,Period2);
128 }
129 break;
130 case GeomAbs_Line: {
131 inverse = Standard_True;
132 Extrema_ExtElC2d Xtrem(Tool2::Line(*((Curve2*)myC)), Tool1::Circle(C1), Tol);
133 Results(Xtrem, U11, U12, U21, U22, 2*PI, 0.);
134 }
135 break;
136 }; // switch(type2)
137 }
138 break;
139
140 //
141 // La premiere courbe est une ellipse:
142 //
143 case GeomAbs_Ellipse: {
144
145 switch(type2) {
146 case GeomAbs_Circle: {
147 inverse = Standard_True;
148 Extrema_ExtElC2d Xtrem(Tool2::Circle(*((Curve2*)myC)), Tool1::Ellipse(C1));
149 Results(Xtrem, U11, U12, U21, U22, 2*PI, 2*PI);
150 }
151 break;
152 case GeomAbs_Ellipse: {
153 //Extrema_ExtElC2d Xtrem(Tool1::Ellipse(C1), Tool2::Ellipse(*((Curve2*)myC)));
154 Extrema_ECC2d Xtrem(C1, *((Curve2*)myC),
155 NbU, NbV, mytolc1, mytolc2);
156 Results(Xtrem, C1, U11, U12, U21, U22,2*PI, 2*PI);
157 }
158 break;
159 case GeomAbs_Parabola: {
160 //Extrema_ExtElC2d Xtrem(Tool1::Ellipse(C1), Tool2::Parabola(*((Curve2*)myC)));
161 Extrema_ECC2d Xtrem(C1, *((Curve2*)myC),
162 NbU, NbV, mytolc1, mytolc2);
163 Results(Xtrem, C1, U11, U12, U21, U22, 2*PI, 0.);
164 }
165 break;
166 case GeomAbs_Hyperbola: {
167 //Extrema_ExtElC2d Xtrem(Tool1::Ellipse(C1), Tool2::Hyperbola(*((Curve2*)myC)));
168 Extrema_ECC2d Xtrem(C1, *((Curve2*)myC),
169 NbU, NbV, mytolc1, mytolc2);
170 Results(Xtrem, C1, U11, U12, U21, U22, 2*PI, 0.);
171 }
172 break;
173 case GeomAbs_BezierCurve:
174 case GeomAbs_OtherCurve:
175 case GeomAbs_BSplineCurve: {
176 Extrema_ECC2d Xtrem(C1, *((Curve2*)myC),
177 NbU, NbV, mytolc1, mytolc2);
178 Standard_Real Period2 = 0.;
179 if (Tool2::IsPeriodic(*((Curve2*)myC))) Period2 = Tool2::Period(*((Curve2*)myC));
180 Results(Xtrem, C1, U11, U12, U21, U22, 2*PI,Period2);
181 }
182 break;
183 case GeomAbs_Line: {
184 inverse = Standard_True;
185 Extrema_ExtElC2d Xtrem(Tool2::Line(*((Curve2*)myC)), Tool1::Ellipse(C1));
186 Results(Xtrem, U11, U12, U21, U22, 2*PI, 0.);
187 }
188 break;
189 }; // switch(type2)
190 }
191 break;
192
193 //
194 // La premiere courbe est une parabole:
195 //
196 case GeomAbs_Parabola: {
197
198 switch(type2) {
199 case GeomAbs_Circle: {
200 inverse = Standard_True;
201 Extrema_ExtElC2d Xtrem(Tool2::Circle(*((Curve2*)myC)), Tool1::Parabola(C1));
202 Results(Xtrem, U11, U12, U21, U22, 0., 2*PI);
203 }
204 break;
205 case GeomAbs_Ellipse: {
206 //inverse = Standard_True;
207 //Extrema_ExtElC2d Xtrem(Tool2::Ellipse(*((Curve2*)myC)), Tool1::Parabola(C1));
208 Extrema_ECC2d Xtrem(C1, *((Curve2*)myC),
209 NbU, NbV, mytolc1, mytolc2);
210 Results(Xtrem, C1, U11, U12, U21, U22, 0., 2*PI);
211 }
212 break;
213 case GeomAbs_Parabola: {
214 //Extrema_ExtElC2d Xtrem(Tool1::Parabola(C1), Tool2::Parabola(*((Curve2*)myC)));
215 Extrema_ECC2d Xtrem(C1, *((Curve2*)myC),
216 NbU, NbV, mytolc1, mytolc2);
217 Results(Xtrem, C1, U11, U12, U21, U22, 0., 0.);
218 }
219 break;
220 case GeomAbs_Hyperbola: {
221 //inverse = Standard_True;
222 //Extrema_ExtElC2d Xtrem(Tool2::Hyperbola(*((Curve2*)myC)), Tool1::Parabola(C1));
223 Extrema_ECC2d Xtrem(C1, *((Curve2*)myC),
224 NbU, NbV, mytolc1, mytolc2);
225 Results(Xtrem, C1, U11, U12, U21, U22, 0., 0.);
226 }
227 break;
228 case GeomAbs_BezierCurve:
229 case GeomAbs_OtherCurve:
230 case GeomAbs_BSplineCurve: {
231 Extrema_ECC2d Xtrem(C1, *((Curve2*)myC),
232 NbU, NbV, mytolc1, mytolc2);
233 Standard_Real Period2 = 0.;
234 if (Tool2::IsPeriodic(*((Curve2*)myC))) Period2 = Tool2::Period(*((Curve2*)myC));
235 Results(Xtrem, C1, U11, U12, U21, U22, 0., Period2);
236 }
237 break;
238 case GeomAbs_Line: {
239 inverse = Standard_True;
240 Extrema_ExtElC2d Xtrem(Tool2::Line(*((Curve2*)myC)), Tool1::Parabola(C1));
241 Results(Xtrem, U11, U12, U21, U22, 0., 0.);
242 }
243 break;
244 }; // switch(type2)
245 }
246 break;
247
248 //
249 // La premiere courbe est une hyperbole:
250 //
251 case GeomAbs_Hyperbola: {
252
253 switch(type2) {
254 case GeomAbs_Circle: {
255 inverse = Standard_True;
256 Extrema_ExtElC2d Xtrem(Tool2::Circle(*((Curve2*)myC)), Tool1::Hyperbola(C1));
257 Results(Xtrem, U11, U12, U21, U22, 0., 2*PI);
258 }
259 break;
260 case GeomAbs_Ellipse: {
261 //inverse = Standard_True;
262 //Extrema_ExtElC2d Xtrem(Tool2::Ellipse(*((Curve2*)myC)), Tool1::Hyperbola(C1));
263 Extrema_ECC2d Xtrem(C1, *((Curve2*)myC),
264 NbU, NbV, mytolc1, mytolc2);
265 Results(Xtrem, C1, U11, U12, U21, U22, 0., 2*PI );
266 }
267 break;
268 case GeomAbs_Parabola: {
269 //Extrema_ExtElC2d Xtrem(Tool1::Hyperbola(C1), Tool2::Parabola(*((Curve2*)myC)));
270 Extrema_ECC2d Xtrem(C1, *((Curve2*)myC),
271 NbU, NbV, mytolc1, mytolc2);
272 Results(Xtrem, C1, U11, U12, U21, U22, 0., 0.);
273 }
274 break;
275 case GeomAbs_Hyperbola: {
276 //Extrema_ExtElC2d Xtrem(Tool1::Hyperbola(C1), Tool2::Hyperbola(*((Curve2*)myC)));
277 Extrema_ECC2d Xtrem(C1, *((Curve2*)myC),
278 NbU, NbV, mytolc1, mytolc2);
279 Results(Xtrem, C1, U11, U12, U21, U22, 0., 0.);
280 }
281 break;
282 case GeomAbs_OtherCurve:
283 case GeomAbs_BezierCurve:
284 case GeomAbs_BSplineCurve: {
285 Extrema_ECC2d Xtrem(C1, *((Curve2*)myC)
286 , NbU, NbV, mytolc1, mytolc2);
287 Standard_Real Period2 = 0.;
288 if (Tool2::IsPeriodic(*((Curve2*)myC))) Period2 = Tool2::Period(*((Curve2*)myC));
289 Results(Xtrem, C1, U11, U12, U21, U22, 0., Period2);
290 }
291 break;
292 case GeomAbs_Line: {
293 inverse = Standard_True;
294 Extrema_ExtElC2d Xtrem(Tool2::Line(*((Curve2*)myC)), Tool1::Hyperbola(C1));
295 Results(Xtrem, U11, U12, U21, U22, 0., 0.);
296 }
297 break;
298 }; // switch(type2)
299 }
300 break;
301
302 //
303 // La premiere courbe est une BezierCurve ou une BSplineCurve:
304 //
305 case GeomAbs_BezierCurve:
306 case GeomAbs_OtherCurve:
307 case GeomAbs_BSplineCurve: {
308 Extrema_ECC2d Xtrem(C1, *((Curve2*)myC),
309 NbU, NbV, mytolc1, mytolc2);
310 Standard_Real Period1 = 0.;
311 if (Tool1::IsPeriodic(C1)) Period1 = Tool1::Period(C1);
312 Standard_Real Period2 = 0.;
313 if (Tool2::IsPeriodic(*((Curve2*)myC))) Period2 = Tool2::Period(*((Curve2*)myC));
314 Results(Xtrem, C1, U11, U12, U21, U22, Period1, Period2);
315 }
316 break;
317
318 //
319 // La premiere courbe est une Line:
320 //
321 case GeomAbs_Line: {
322
323 switch(type2) {
324 case GeomAbs_Circle: {
325 Extrema_ExtElC2d Xtrem(Tool1::Line(C1), Tool2::Circle(*((Curve2*)myC)), Tol);
326 Results(Xtrem, U11, U12, U21, U22, 0., 2*PI);
327 }
328 break;
329 case GeomAbs_Ellipse: {
330 Extrema_ExtElC2d Xtrem(Tool1::Line(C1), Tool2::Ellipse(*((Curve2*)myC)));
331 Results(Xtrem, U11, U12, U21, U22, 0., 2*PI);
332 }
333 break;
334 case GeomAbs_Parabola: {
335 Extrema_ExtElC2d Xtrem(Tool1::Line(C1), Tool2::Parabola(*((Curve2*)myC)));
336 Results(Xtrem, U11, U12, U21, U22, 0., 0.);
337 }
338 break;
339 case GeomAbs_Hyperbola: {
340 Extrema_ExtElC2d Xtrem(Tool1::Line(C1), Tool2::Hyperbola(*((Curve2*)myC)));
341 Results(Xtrem, U11, U12, U21, U22, 0., 0.);
342 }
343 break;
344 case GeomAbs_BezierCurve:
345 case GeomAbs_OtherCurve:
346 case GeomAbs_BSplineCurve: {
347 Extrema_ECC2d Xtrem(C1, *((Curve2*)myC),
348 NbU, NbV, mytolc1, mytolc2);
349 Standard_Real Period2 = 0.;
350 if (Tool2::IsPeriodic(*((Curve2*)myC))) Period2 = Tool2::Period(*((Curve2*)myC));
351 Results(Xtrem, C1, U11, U12, U21, U22, 0., Period2);
352 }
353 break;
354 case GeomAbs_Line: {
355 Extrema_ExtElC2d Xtrem(Tool1::Line(C1), Tool2::Line(*((Curve2*)myC)), Tol);
356 Results(Xtrem, U11, U12, U21, U22, 0., 0.);
357 }
358 break;
359 }; // switch(type2)
360 }
361 break;
362
363 };
364
365}
366
367
368Standard_Boolean Extrema_GExtCC2d::IsDone() const
369{
370 return myDone;
371}
372
373
374Standard_Real Extrema_GExtCC2d::SquareDistance(const Standard_Integer N) const
375{
376 if(!myDone) StdFail_NotDone::Raise();
377 if ((N <= 0) || (N > mynbext)) Standard_OutOfRange::Raise();
378 return mySqDist.Value(N);
379}
380
381
382Standard_Integer Extrema_GExtCC2d::NbExt() const
383{
384 if(!myDone) StdFail_NotDone::Raise();
385 return mynbext;
386}
387
388
389void Extrema_GExtCC2d::Points(const Standard_Integer N,
390 Extrema_POnCurv2d& P1,
391 Extrema_POnCurv2d& P2) const
392{
393 if(!myDone) StdFail_NotDone::Raise();
394 if ((N <= 0) || (N > mynbext)) Standard_OutOfRange::Raise();
395 P1 = mypoints.Value(2*N-1);
396 P2 = mypoints.Value(2*N);
397}
398
399
400
401void Extrema_GExtCC2d::TrimmedSquareDistances(Standard_Real& dist11,
402 Standard_Real& dist12,
403 Standard_Real& dist21,
404 Standard_Real& dist22,
405 gp_Pnt2d& P11,
406 gp_Pnt2d& P12,
407 gp_Pnt2d& P21,
408 gp_Pnt2d& P22) const
409{
410 dist11 = mydist11;
411 dist12 = mydist12;
412 dist21 = mydist21;
413 dist22 = mydist22;
414 P11 = P1f;
415 P12 = P1l;
416 P21 = P2f;
417 P22 = P2l;
418}
419
420
421
422void Extrema_GExtCC2d::Results(const Extrema_ExtElC2d& AlgExt,
423 const Standard_Real Ut11,
424 const Standard_Real Ut12,
425 const Standard_Real Ut21,
426 const Standard_Real Ut22,
427 const Standard_Real Period1,
428 const Standard_Real Period2)
429{
430 Standard_Integer i, NbExt;
431 Standard_Real Val, U, U2;
432 Extrema_POnCurv2d P1, P2;
433
434 myDone = AlgExt.IsDone();
435 myIsPar = AlgExt.IsParallel();
436 if (myDone) {
437 if (!myIsPar) {
438 NbExt = AlgExt.NbExt();
439 for (i = 1; i <= NbExt; i++) {
440 // Verification de la validite des parametres pour le cas trimme:
441 AlgExt.Points(i, P1, P2);
442 if (!inverse) {
443 U = P1.Parameter();
444 if (Period1 != 0.0) U = ElCLib::InPeriod(U,Ut11,Ut11+Period1);
445 U2 = P2.Parameter();
446 if (Period2 != 0.0) U2 = ElCLib::InPeriod(U2,Ut21,Ut21+Period2);
447 }
448 else {
449 U2 = P1.Parameter();
450 if (Period2 != 0.0) U2 = ElCLib::InPeriod(U2,Ut21,Ut21+Period2);
451 U = P2.Parameter();
452 if (Period1 != 0.0) U = ElCLib::InPeriod(U,Ut11,Ut11+Period1);
453 }
454 if ((U >= Ut11 - Precision::PConfusion()) &&
455 (U <= Ut12 + Precision::PConfusion()) &&
456 (U2 >= Ut21 - Precision::PConfusion()) &&
457 (U2 <= Ut22 + Precision::PConfusion())) {
458 mynbext++;
459 Val = AlgExt.SquareDistance(i);
460 mySqDist.Append(Val);
461 if (!inverse) {
462 P1.SetValues(U, P1.Value());
463 P2.SetValues(U2, P2.Value());
464 mypoints.Append(P1);
465 mypoints.Append(P2);
466 }
467 else {
468 P1.SetValues(U2, P1.Value());
469 P2.SetValues(U, P2.Value());
470 mypoints.Append(P2);
471 mypoints.Append(P1);
472 }
473 }
474 }
475 }
476
477 mydist11 = P1f.SquareDistance(P2f);
478 mydist12 = P1f.SquareDistance(P2l);
479 mydist21 = P1l.SquareDistance(P2f);
480 mydist22 = P1l.SquareDistance(P2l);
481 }
482}
483
484
485void Extrema_GExtCC2d::Results(const Extrema_ECC2d& AlgExt,
486// modified by NIZHNY-EAP Wed Feb 23 14:51:24 2000 ___BEGIN___
487 const Curve1& C1,
488// modified by NIZHNY-EAP Wed Feb 23 14:51:26 2000 ___END___
489 const Standard_Real Ut11,
490 const Standard_Real Ut12,
491 const Standard_Real Ut21,
492 const Standard_Real Ut22,
493 const Standard_Real Period1,
494 const Standard_Real Period2)
495{
496 Standard_Integer i, NbExt;
497 Standard_Real Val, U, U2;
498 Extrema_POnCurv2d P1, P2;
499
500 myDone = AlgExt.IsDone();
501 if (myDone) {
502 if (!myIsPar) {
503 NbExt = AlgExt.NbExt();
504 for (i = 1; i <= NbExt; i++) {
505 // Verification de la validite des parametres pour le cas trimme:
506 AlgExt.Points(i, P1, P2);
507 U = P1.Parameter();
508 if (Period1 != 0.0) U = ElCLib::InPeriod(U,Ut11,Ut11+Period1);
509 U2 = P2.Parameter();
510 if (Period2 != 0.0) U2 = ElCLib::InPeriod(U2,Ut21,Ut21+Period2);
511
512 if ((U >= Ut11 - Precision::PConfusion()) &&
513 (U <= Ut12 + Precision::PConfusion()) &&
514 (U2 >= Ut21 - Precision::PConfusion()) &&
515 (U2 <= Ut22 + Precision::PConfusion())) {
516// modified by NIZHNY-EAP Thu Jan 27 16:40:55 2000 ___BEGIN___
517 // to be sure that it's a real extrema
518 gp_Pnt2d p;
519 gp_Vec2d v1, v2;
520 Tool1::D1(C1,U,p, v1);
521 Tool2::D1(*((Curve2*)myC),U2,p, v2);
522 if (v1.IsParallel(v2, Precision::Angular())) {
523 mynbext++;
524 Val = AlgExt.SquareDistance(i);
525 P1.SetValues(U, P1.Value());
526 P2.SetValues(U2, P2.Value());
527 mySqDist.Append(Val);
528 mypoints.Append(P1);
529 mypoints.Append(P2);
530 }
531// modified by NIZHNY-EAP Thu Jan 27 16:41:00 2000 ___END___
532 }
533 }
534 }
535
536 mydist11 = P1f.SquareDistance(P2f);
537 mydist12 = P1f.SquareDistance(P2l);
538 mydist21 = P1l.SquareDistance(P2f);
539 mydist22 = P1l.SquareDistance(P2l);
540 }
541}
542
543
544Standard_Boolean Extrema_GExtCC2d::IsParallel() const
545{
546 if (!myDone) StdFail_NotDone::Raise();
547 return myIsPar;
548}