1 // File: Extrema_GExtCC2d.gxx
2 // Created: Wed Jul 6 15:08:36 1994
3 // Author: Laurent PAINNOT
7 #include Extrema_ECC2d_hxx
8 #include <Extrema_ExtElC2d.hxx>
9 #include <StdFail_NotDone.hxx>
10 #include <Extrema_ExtElC.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>
27 Extrema_GExtCC2d::Extrema_GExtCC2d() {}
30 Extrema_GExtCC2d::Extrema_GExtCC2d(const Curve1& C1,
32 const Standard_Real TolC1,
33 const Standard_Real TolC2)
35 Initialize(C2, Tool2::FirstParameter(C2), Tool2::LastParameter(C2), TolC1, TolC2);
36 Perform(C1, Tool1::FirstParameter(C1), Tool1::LastParameter(C1));
39 Extrema_GExtCC2d::Extrema_GExtCC2d(const Curve1& C1,
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)
48 Initialize(C2, V1, V2, TolC1, TolC2);
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)
60 myC = (Standard_Address)&C2;
69 void Extrema_GExtCC2d::Perform (const Curve1& C1,
70 const Standard_Real U1,
71 const Standard_Real U2)
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;
80 inverse = Standard_False;
81 myIsPar = Standard_False;
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);
95 // La premiere courbe est un cercle:
97 case GeomAbs_Circle: {
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);
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 );
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.);
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. );
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);
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.);
141 // La premiere courbe est une ellipse:
143 case GeomAbs_Ellipse: {
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);
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);
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.);
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.);
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);
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.);
194 // La premiere courbe est une parabole:
196 case GeomAbs_Parabola: {
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);
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);
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.);
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.);
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);
239 inverse = Standard_True;
240 Extrema_ExtElC2d Xtrem(Tool2::Line(*((Curve2*)myC)), Tool1::Parabola(C1));
241 Results(Xtrem, U11, U12, U21, U22, 0., 0.);
249 // La premiere courbe est une hyperbole:
251 case GeomAbs_Hyperbola: {
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);
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 );
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.);
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.);
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);
293 inverse = Standard_True;
294 Extrema_ExtElC2d Xtrem(Tool2::Line(*((Curve2*)myC)), Tool1::Hyperbola(C1));
295 Results(Xtrem, U11, U12, U21, U22, 0., 0.);
303 // La premiere courbe est une BezierCurve ou une BSplineCurve:
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);
319 // La premiere courbe est une Line:
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);
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);
334 case GeomAbs_Parabola: {
335 Extrema_ExtElC2d Xtrem(Tool1::Line(C1), Tool2::Parabola(*((Curve2*)myC)));
336 Results(Xtrem, U11, U12, U21, U22, 0., 0.);
339 case GeomAbs_Hyperbola: {
340 Extrema_ExtElC2d Xtrem(Tool1::Line(C1), Tool2::Hyperbola(*((Curve2*)myC)));
341 Results(Xtrem, U11, U12, U21, U22, 0., 0.);
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);
355 Extrema_ExtElC2d Xtrem(Tool1::Line(C1), Tool2::Line(*((Curve2*)myC)), Tol);
356 Results(Xtrem, U11, U12, U21, U22, 0., 0.);
368 Standard_Boolean Extrema_GExtCC2d::IsDone() const
374 Standard_Real Extrema_GExtCC2d::SquareDistance(const Standard_Integer N) const
376 if(!myDone) StdFail_NotDone::Raise();
377 if ((N <= 0) || (N > mynbext)) Standard_OutOfRange::Raise();
378 return mySqDist.Value(N);
382 Standard_Integer Extrema_GExtCC2d::NbExt() const
384 if(!myDone) StdFail_NotDone::Raise();
389 void Extrema_GExtCC2d::Points(const Standard_Integer N,
390 Extrema_POnCurv2d& P1,
391 Extrema_POnCurv2d& P2) const
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);
401 void Extrema_GExtCC2d::TrimmedSquareDistances(Standard_Real& dist11,
402 Standard_Real& dist12,
403 Standard_Real& dist21,
404 Standard_Real& dist22,
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)
430 Standard_Integer i, NbExt;
431 Standard_Real Val, U, U2;
432 Extrema_POnCurv2d P1, P2;
434 myDone = AlgExt.IsDone();
435 myIsPar = AlgExt.IsParallel();
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);
444 if (Period1 != 0.0) U = ElCLib::InPeriod(U,Ut11,Ut11+Period1);
446 if (Period2 != 0.0) U2 = ElCLib::InPeriod(U2,Ut21,Ut21+Period2);
450 if (Period2 != 0.0) U2 = ElCLib::InPeriod(U2,Ut21,Ut21+Period2);
452 if (Period1 != 0.0) U = ElCLib::InPeriod(U,Ut11,Ut11+Period1);
454 if ((U >= Ut11 - Precision::PConfusion()) &&
455 (U <= Ut12 + Precision::PConfusion()) &&
456 (U2 >= Ut21 - Precision::PConfusion()) &&
457 (U2 <= Ut22 + Precision::PConfusion())) {
459 Val = AlgExt.SquareDistance(i);
460 mySqDist.Append(Val);
462 P1.SetValues(U, P1.Value());
463 P2.SetValues(U2, P2.Value());
468 P1.SetValues(U2, P1.Value());
469 P2.SetValues(U, P2.Value());
477 mydist11 = P1f.SquareDistance(P2f);
478 mydist12 = P1f.SquareDistance(P2l);
479 mydist21 = P1l.SquareDistance(P2f);
480 mydist22 = P1l.SquareDistance(P2l);
485 void Extrema_GExtCC2d::Results(const Extrema_ECC2d& AlgExt,
486 // modified by NIZHNY-EAP Wed Feb 23 14:51:24 2000 ___BEGIN___
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)
496 Standard_Integer i, NbExt;
497 Standard_Real Val, U, U2;
498 Extrema_POnCurv2d P1, P2;
500 myDone = AlgExt.IsDone();
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);
508 if (Period1 != 0.0) U = ElCLib::InPeriod(U,Ut11,Ut11+Period1);
510 if (Period2 != 0.0) U2 = ElCLib::InPeriod(U2,Ut21,Ut21+Period2);
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
520 Tool1::D1(C1,U,p, v1);
521 Tool2::D1(*((Curve2*)myC),U2,p, v2);
522 if (v1.IsParallel(v2, Precision::Angular())) {
524 Val = AlgExt.SquareDistance(i);
525 P1.SetValues(U, P1.Value());
526 P2.SetValues(U2, P2.Value());
527 mySqDist.Append(Val);
531 // modified by NIZHNY-EAP Thu Jan 27 16:41:00 2000 ___END___
536 mydist11 = P1f.SquareDistance(P2f);
537 mydist12 = P1f.SquareDistance(P2l);
538 mydist21 = P1l.SquareDistance(P2f);
539 mydist22 = P1l.SquareDistance(P2l);
544 Standard_Boolean Extrema_GExtCC2d::IsParallel() const
546 if (!myDone) StdFail_NotDone::Raise();