0022312: Translation of french commentaries in OCCT files
[occt.git] / src / Extrema / Extrema_GExtCC2d.gxx
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
27 Extrema_GExtCC2d::Extrema_GExtCC2d() {}
28
29
30 Extrema_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
39 Extrema_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
54 void 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
69 void 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
368 Standard_Boolean Extrema_GExtCC2d::IsDone() const
369 {
370   return myDone;
371 }
372
373
374 Standard_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
382 Standard_Integer Extrema_GExtCC2d::NbExt() const
383 {
384   if(!myDone) StdFail_NotDone::Raise();
385   return mynbext;
386 }
387
388
389 void 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
401 void 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
422 void 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
485 void 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
544 Standard_Boolean Extrema_GExtCC2d::IsParallel() const
545 {
546   if (!myDone) StdFail_NotDone::Raise();
547   return myIsPar;
548 }