1 // Created on: 1994-07-06
2 // Created by: Laurent PAINNOT
3 // Copyright (c) 1994-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 // Modified by MPS (june 96) : correction du trap dans le cas droite/Bezier
18 // Modified by MPS (mai 97) : PRO 7598
19 // tri des solutions pour eviter de rendre plusieurs
20 // fois la meme solution
22 #include <Adaptor3d_Curve.hxx>
23 #include <Bnd_Range.hxx>
25 #include <Extrema_CurveTool.hxx>
26 #include <Extrema_ECC.hxx>
27 #include <Extrema_ExtCC.hxx>
28 #include <Extrema_ExtElC.hxx>
29 #include <Extrema_ExtPElC.hxx>
30 #include <Extrema_POnCurv.hxx>
31 #include <Extrema_SequenceOfPOnCurv.hxx>
32 #include <Geom_Circle.hxx>
33 #include <Geom_Curve.hxx>
34 #include <Geom_Ellipse.hxx>
35 #include <Geom_Hyperbola.hxx>
36 #include <Geom_Line.hxx>
37 #include <Geom_Parabola.hxx>
38 #include <Geom_TrimmedCurve.hxx>
39 #include <GeomAbs_CurveType.hxx>
41 #include <Precision.hxx>
42 #include <Standard_Failure.hxx>
43 #include <Standard_NotImplemented.hxx>
44 #include <Standard_NullObject.hxx>
45 #include <Standard_OutOfRange.hxx>
46 #include <StdFail_InfiniteSolutions.hxx>
47 #include <StdFail_NotDone.hxx>
48 #include <TColStd_Array1OfReal.hxx>
49 #include <TColStd_ListIteratorOfListOfTransient.hxx>
50 #include <TColStd_SequenceOfReal.hxx>
52 //=======================================================================
53 //function : Extrema_ExtCC
55 //=======================================================================
56 Extrema_ExtCC::Extrema_ExtCC (const Standard_Real TolC1,
57 const Standard_Real TolC2)
58 : myIsFindSingleSolution(Standard_False),
59 myDone (Standard_False)
61 myC[0] = 0; myC[1] = 0;
62 myInf[0] = myInf[1] = -Precision::Infinite();
63 mySup[0] = mySup[1] = Precision::Infinite();
64 myTol[0] = TolC1; myTol[1] = TolC2;
65 mydist11 = mydist12 = mydist21 = mydist22 = RealFirst();
68 //=======================================================================
69 //function : Extrema_ExtCC
71 //=======================================================================
73 Extrema_ExtCC::Extrema_ExtCC(const Adaptor3d_Curve& C1,
74 const Adaptor3d_Curve& C2,
75 const Standard_Real U1,
76 const Standard_Real U2,
77 const Standard_Real V1,
78 const Standard_Real V2,
79 const Standard_Real TolC1,
80 const Standard_Real TolC2)
81 : myIsFindSingleSolution(Standard_False),
82 myECC(C1, C2, U1, U2, V1, V2),
83 myDone (Standard_False)
85 SetCurve (1, C1, U1, U2);
86 SetCurve (2, C2, V1, V2);
87 SetTolerance (1, TolC1);
88 SetTolerance (2, TolC2);
89 mydist11 = mydist12 = mydist21 = mydist22 = RealFirst();
94 //=======================================================================
95 //function : Extrema_ExtCC
97 //=======================================================================
99 Extrema_ExtCC::Extrema_ExtCC(const Adaptor3d_Curve& C1,
100 const Adaptor3d_Curve& C2,
101 const Standard_Real TolC1,
102 const Standard_Real TolC2)
103 : myIsFindSingleSolution(Standard_False),
105 myDone (Standard_False)
107 SetCurve (1, C1, C1.FirstParameter(), C1.LastParameter());
108 SetCurve (2, C2, C2.FirstParameter(), C2.LastParameter());
109 SetTolerance (1, TolC1);
110 SetTolerance (2, TolC2);
111 mydist11 = mydist12 = mydist21 = mydist22 = RealFirst();
115 //=======================================================================
116 //function : SetCurve
118 //=======================================================================
120 void Extrema_ExtCC::SetCurve (const Standard_Integer theRank, const Adaptor3d_Curve& C)
122 Standard_OutOfRange_Raise_if (theRank < 1 || theRank > 2, "Extrema_ExtCC::SetCurve()")
123 Standard_Integer anInd = theRank - 1;
124 myC[anInd] = (Standard_Address)&C;
127 //=======================================================================
128 //function : SetCurve
130 //=======================================================================
132 void Extrema_ExtCC::SetCurve (const Standard_Integer theRank, const Adaptor3d_Curve& C,
133 const Standard_Real Uinf, const Standard_Real Usup)
135 SetCurve (theRank, C);
136 SetRange (theRank, Uinf, Usup);
139 //=======================================================================
140 //function : SetRange
142 //=======================================================================
144 void Extrema_ExtCC::SetRange (const Standard_Integer theRank,
145 const Standard_Real Uinf, const Standard_Real Usup)
147 Standard_OutOfRange_Raise_if (theRank < 1 || theRank > 2, "Extrema_ExtCC::SetRange()")
148 Standard_Integer anInd = theRank - 1;
153 //=======================================================================
154 //function : SetTolerance
156 //=======================================================================
158 void Extrema_ExtCC::SetTolerance (const Standard_Integer theRank, const Standard_Real theTol)
160 Standard_OutOfRange_Raise_if (theRank < 1 || theRank > 2, "Extrema_ExtCC::SetTolerance()")
161 Standard_Integer anInd = theRank - 1;
162 myTol[anInd] = theTol;
166 //=======================================================================
169 //=======================================================================
171 void Extrema_ExtCC::Perform()
173 Standard_NullObject_Raise_if (!myC[0] || !myC[1], "Extrema_ExtCC::Perform()")
174 myECC.SetParams(*((Adaptor3d_Curve*)myC[0]),
175 *((Adaptor3d_Curve*)myC[1]), myInf[0], mySup[0], myInf[1], mySup[1]);
176 myECC.SetTolerance(Min(myTol[0], myTol[1]));
177 myECC.SetSingleSolutionFlag(GetSingleSolutionFlag());
178 myDone = Standard_False;
181 myIsPar = Standard_False;
183 GeomAbs_CurveType type1 = (*((Adaptor3d_Curve*)myC[0])).GetType();
184 GeomAbs_CurveType type2 = (*((Adaptor3d_Curve*)myC[1])).GetType();
185 Standard_Real U11, U12, U21, U22, Tol = Min(myTol[0], myTol[1]);
192 if (!Precision::IsInfinite(U11)) P1f = Extrema_CurveTool::Value(*((Adaptor3d_Curve*)myC[0]), U11);
193 if (!Precision::IsInfinite(U12)) P1l = Extrema_CurveTool::Value(*((Adaptor3d_Curve*)myC[0]), U12);
194 if (!Precision::IsInfinite(U21)) P2f = Extrema_CurveTool::Value(*((Adaptor3d_Curve*)myC[1]), U21);
195 if (!Precision::IsInfinite(U22)) P2l = Extrema_CurveTool::Value(*((Adaptor3d_Curve*)myC[1]), U22);
198 if (Precision::IsInfinite(U11) || Precision::IsInfinite(U21)) mydist11 = RealLast();
199 else mydist11 = P1f.SquareDistance(P2f);
200 if (Precision::IsInfinite(U11) || Precision::IsInfinite(U22)) mydist12 = RealLast();
201 else mydist12 = P1f.SquareDistance(P2l);
202 if (Precision::IsInfinite(U12) || Precision::IsInfinite(U21)) mydist21 = RealLast();
203 else mydist21 = P1l.SquareDistance(P2f);
204 if (Precision::IsInfinite(U12) || Precision::IsInfinite(U22)) mydist22 = RealLast();
205 else mydist22 = P1l.SquareDistance(P2l);
207 //Depending on the types of curves, the algorithm is chosen:
208 //- _ExtElC, when one of the curves is a line and the other is elementary,
209 // or there are two circles;
210 //- _GenExtCC, in all other cases
211 if ( (type1 == GeomAbs_Line && type2 <= GeomAbs_Parabola) ||
212 (type2 == GeomAbs_Line && type1 <= GeomAbs_Parabola) ) {
213 //analytical case - one curve is always a line
214 Standard_Integer anInd1 = 0, anInd2 = 1;
215 GeomAbs_CurveType aType2 = type2;
216 Standard_Boolean isInverse = (type1 > type2);
219 //algorithm uses inverse order of arguments
226 Extrema_ExtElC Xtrem((*((Adaptor3d_Curve*)myC[anInd1])).Line(), (*((Adaptor3d_Curve*)myC[anInd2])).Line(), Tol);
227 PrepareResults(Xtrem, isInverse, U11, U12, U21, U22);
230 case GeomAbs_Circle: {
231 Extrema_ExtElC Xtrem((*((Adaptor3d_Curve*)myC[anInd1])).Line(), (*((Adaptor3d_Curve*)myC[anInd2])).Circle(), Tol);
232 PrepareResults(Xtrem, isInverse, U11, U12, U21, U22);
235 case GeomAbs_Ellipse: {
236 Extrema_ExtElC Xtrem((*((Adaptor3d_Curve*)myC[anInd1])).Line(), (*((Adaptor3d_Curve*)myC[anInd2])).Ellipse());
237 PrepareResults(Xtrem, isInverse, U11, U12, U21, U22);
240 case GeomAbs_Hyperbola: {
241 Extrema_ExtElC Xtrem((*((Adaptor3d_Curve*)myC[anInd1])).Line(), (*((Adaptor3d_Curve*)myC[anInd2])).Hyperbola());
242 PrepareResults(Xtrem, isInverse, U11, U12, U21, U22);
245 case GeomAbs_Parabola: {
246 Extrema_ExtElC Xtrem((*((Adaptor3d_Curve*)myC[anInd1])).Line(), (*((Adaptor3d_Curve*)myC[anInd2])).Parabola());
247 PrepareResults(Xtrem, isInverse, U11, U12, U21, U22);
252 } else if (type1 == GeomAbs_Circle && type2 == GeomAbs_Circle) {
253 //analytical case - two circles
254 Standard_Boolean bIsDone;
255 Extrema_ExtElC CCXtrem ((*((Adaptor3d_Curve*)myC[0])).Circle(), (*((Adaptor3d_Curve*)myC[1])).Circle());
256 bIsDone = CCXtrem.IsDone();
258 PrepareResults(CCXtrem, Standard_False, U11, U12, U21, U22);
262 PrepareResults(myECC, U11, U12, U21, U22);
266 PrepareResults(myECC, U11, U12, U21, U22);
271 //=======================================================================
274 //=======================================================================
276 Standard_Boolean Extrema_ExtCC::IsDone() const
281 //=======================================================================
282 //function : IsParallel
284 //=======================================================================
286 Standard_Boolean Extrema_ExtCC::IsParallel() const
290 throw StdFail_NotDone();
297 //=======================================================================
300 //=======================================================================
302 Standard_Real Extrema_ExtCC::SquareDistance(const Standard_Integer N) const
304 if ((N < 1) || (N > NbExt())) throw Standard_OutOfRange();
305 return mySqDist.Value(N);
309 //=======================================================================
312 //=======================================================================
314 Standard_Integer Extrema_ExtCC::NbExt() const
316 if(!myDone) throw StdFail_NotDone();
317 return mySqDist.Length();
321 //=======================================================================
324 //=======================================================================
326 void Extrema_ExtCC::Points(const Standard_Integer N,
328 Extrema_POnCurv& P2) const
332 throw StdFail_InfiniteSolutions();
335 if (N < 1 || N > NbExt())
337 throw Standard_OutOfRange();
340 P1 = mypoints.Value(2 * N - 1);
341 P2 = mypoints.Value(2 * N);
346 //=======================================================================
347 //function : TrimmedDistances
349 //=======================================================================
351 void Extrema_ExtCC::TrimmedSquareDistances(Standard_Real& dist11,
352 Standard_Real& dist12,
353 Standard_Real& dist21,
354 Standard_Real& dist22,
358 gp_Pnt& P22 ) const {
370 //=======================================================================
371 //function : ParallelResult
373 //=======================================================================
374 void Extrema_ExtCC::PrepareParallelResult(const Standard_Real theUt11,
375 const Standard_Real theUt12,
376 const Standard_Real theUt21,
377 const Standard_Real theUt22,
378 const Standard_Real theSqDist)
383 const GeomAbs_CurveType aType1 = Extrema_CurveTool::GetType(*((Adaptor3d_Curve*) myC[0]));
384 const GeomAbs_CurveType aType2 = Extrema_CurveTool::GetType(*((Adaptor3d_Curve*) myC[1]));
386 if (((aType1 != GeomAbs_Line) && (aType1 != GeomAbs_Circle)) ||
387 ((aType2 != GeomAbs_Line) && (aType2 != GeomAbs_Circle)))
389 mySqDist.Append(theSqDist);
390 myDone = Standard_True;
391 myIsPar = Standard_True;
395 // Parallel case is only for line-line, circle-circle and circle-line!!!
396 // But really for trimmed curves extremas can not exist!
397 if (aType1 != aType2)
399 //The projection of the circle's location to the trimmed line must exist.
400 const Standard_Boolean isReversed = (aType1 != GeomAbs_Circle);
401 const gp_Pnt aPonC = !isReversed ?
402 Extrema_CurveTool::Value(*((Adaptor3d_Curve*) myC[0]), theUt11) :
403 Extrema_CurveTool::Value(*((Adaptor3d_Curve*) myC[1]), theUt21);
405 const gp_Lin aL = !isReversed ? ((Adaptor3d_Curve*) myC[1])->Line() :
406 ((Adaptor3d_Curve*) myC[0])->Line();
407 const Extrema_ExtPElC ExtPLin(aPonC, aL, Precision::Confusion(),
408 !isReversed ? theUt21 : theUt11,
409 !isReversed ? theUt22 : theUt12);
411 if (ExtPLin.IsDone())
413 mySqDist.Append(theSqDist);
417 myIsPar = Standard_False;
423 if (aType1 == GeomAbs_Line)
427 const Standard_Real isFirstInfinite = (Precision::IsInfinite(theUt11) &&
428 Precision::IsInfinite(theUt12));
429 const Standard_Real isLastInfinite = (Precision::IsInfinite(theUt21) &&
430 Precision::IsInfinite(theUt22));
432 if (isFirstInfinite || isLastInfinite)
434 // Infinite number of solution
436 mySqDist.Append(theSqDist);
440 // The range created by projection of both ends of the 1st line
441 // to the 2nd one must intersect the (native) trimmed range of
444 myIsPar = Standard_False;
446 const gp_Lin aLin1 = ((Adaptor3d_Curve*) myC[0])->Line();
447 const gp_Lin aLin2 = ((Adaptor3d_Curve*) myC[1])->Line();
448 const Standard_Boolean isOpposite(aLin1.Direction().Dot(aLin2.Direction()) < 0.0);
450 Bnd_Range aRange2(theUt21, theUt22);
451 Bnd_Range aProjRng12;
453 if (Precision::IsInfinite(theUt11))
456 aProjRng12.Add(Precision::Infinite());
458 aProjRng12.Add(-Precision::Infinite());
462 const gp_Pnt aPonC1 = ElCLib::Value(theUt11, aLin1);
463 const Standard_Real aPar = ElCLib::Parameter(aLin2, aPonC1);
464 aProjRng12.Add(aPar);
467 if (Precision::IsInfinite(theUt12))
470 aProjRng12.Add(-Precision::Infinite());
472 aProjRng12.Add(Precision::Infinite());
476 const gp_Pnt aPonC1 = ElCLib::Value(theUt12, aLin1);
477 const Standard_Real aPar = ElCLib::Parameter(aLin2, aPonC1);
478 aProjRng12.Add(aPar);
481 aRange2.Common(aProjRng12);
482 if (aRange2.Delta() > Precision::Confusion())
485 mySqDist.Append(theSqDist);
486 myIsPar = Standard_True;
488 else if (!aRange2.IsVoid())
492 // ************** aLin1
495 // *************** aLin2
498 Standard_Real aPar1 = 0.0, aPar2 = 0.0;
499 aRange2.GetBounds(aPar1, aPar2);
500 aPar2 = 0.5*(aPar1 + aPar2);
501 gp_Pnt aP = ElCLib::Value(aPar2, aLin2);
502 const Extrema_POnCurv aP2(aPar2, aP);
503 aPar1 = ElCLib::Parameter(aLin1, aP);
504 aP = ElCLib::Value(aPar1, aLin1);
505 const Extrema_POnCurv aP1(aPar1, aP);
506 mypoints.Append(aP1);
507 mypoints.Append(aP2);
508 mySqDist.Append(theSqDist);
515 myIsPar = Standard_False;
517 //Two arcs with ranges [U1, U2] and [V1, V2] correspondingly are
518 //considered to be parallel in the following case:
519 // The range created by projection both points U1 and U2 of the
520 // 1st circle to the 2nd one intersects either the range [V1, V2] or
521 // the range [V1-PI, V2-PI]. All ranges must be adjusted to correspond
522 // periodic range before checking of intersection.
524 const gp_Circ aWorkCirc = ((Adaptor3d_Curve*) myC[1])->Circle();
525 const Standard_Real aPeriod = M_PI + M_PI;
528 const gp_Pnt aP12 = Extrema_CurveTool::Value(*((Adaptor3d_Curve*) myC[0]), theUt12);
529 Extrema_CurveTool::D1(*((Adaptor3d_Curve*) myC[0]), theUt11, aP11, aVTg1);
531 const Bnd_Range aRange(theUt21, theUt22);
534 // Project arc of the 1st circle between points theUt11 and theUt12 to the
535 // 2nd circle. It is necessary to chose correct arc from two possible ones.
537 Standard_Real aPar1 = ElCLib::InPeriod(ElCLib::Parameter(aWorkCirc, aP11),
538 theUt21, theUt21 + aPeriod);
539 const gp_Vec aVTg2 = Extrema_CurveTool::DN(*((Adaptor3d_Curve*) myC[1]), aPar1, 1);
541 // Check if circles have same/opposite directions
542 const Standard_Boolean isOpposite(aVTg1.Dot(aVTg2) < 0.0);
544 Standard_Real aPar2 = ElCLib::InPeriod(ElCLib::Parameter(aWorkCirc, aP12),
545 theUt21, theUt21 + aPeriod);
549 // Must be aPar2 < aPar1
550 if ((aRange.Delta() > Precision::Angular()) &&
551 ((aPar1 - aPar2) < Precision::Angular()))
558 // Must be aPar2 > aPar1
559 if ((aRange.Delta() > Precision::Angular()) &&
560 ((aPar2 - aPar1) < Precision::Angular()))
566 // Now the projection result is the range [aPar1, aPar2]
567 // if aPar1 < aPar2 or the range [aPar2, aPar1], otherwise.
569 Standard_Real aMinSquareDist = RealLast();
571 aProjRng1.Add(aPar1 - M_PI);
572 aProjRng1.Add(aPar2 - M_PI);
573 for (Standard_Integer i = 0; i < 2; i++)
575 // Repeat computation twice
577 Bnd_Range aRng = aProjRng1;
580 //Cases are possible and processed below:
581 //1. Extrema does not exist. In this case all common ranges are VOID.
582 //2. Arcs are parallel and distance between them is equal to sqrt(theSqDist).
583 // In this case myIsPar = TRUE definitely.
584 //3. Arcs are parallel and distance between them is equal to (sqrt(theSqDist) + R),
585 // where R is the least radius of the both circles. In this case myIsPar flag
586 // will temporary be set to TRUE but check will be continued until less
587 // distance will be found. At that, region with the least distance can be
588 // either a local point or continuous range. In 1st case myIsPar = FALSE and
589 // several (or single) extremas will be returned. In the 2nd one
590 // myIsPar = TRUE and only the least distance will be returned.
591 //4. Arcs are not parallel. Then several (or single) extremas will be returned.
593 if (aRng.Delta() > Precision::Angular())
595 Standard_Real aPar = 0.0;
596 aRng.GetIntermediatePoint(0.5, aPar);
597 const gp_Pnt aPCirc2 = ElCLib::Value(aPar, aWorkCirc);
598 Extrema_ExtPElC ExtPCir(aPCirc2,
599 Extrema_CurveTool::Circle(*((Adaptor3d_Curve*) myC[0])),
600 Precision::Confusion(), theUt11, theUt12);
602 Standard_Real aMinSqD = ExtPCir.SquareDistance(1);
603 for (Standard_Integer anExtID = 2; anExtID <= ExtPCir.NbExt(); anExtID++)
605 aMinSqD = Min(aMinSqD, ExtPCir.SquareDistance(anExtID));
608 if (aMinSqD <= aMinSquareDist)
611 mySqDist.Append(aMinSqD);
612 myIsPar = Standard_True;
614 const Standard_Real aDeltaSqDist = aMinSqD - theSqDist;
615 const Standard_Real aSqD = Max(aMinSqD, theSqDist);
617 // 0 <= Dist1-Dist2 <= Eps
618 // 0 <= Dist1^2 - Dist2^2 < Eps*(Dist1+Dist2)
620 //If Dist1 ~= Dist2 ==> Dist1+Dist2 ~= 2*Dist2.
622 // 0 <= Dist1^2 - Dist2^2 <= 2*Dist2*Eps
625 // (Dist1^2 - Dist2^2)^2 <= 4*Dist2^2*Eps^2
627 if (aDeltaSqDist*aDeltaSqDist < 4.0*aSqD*Precision::SquareConfusion())
629 // New solution is found
634 //Nearer solution can be found
636 else if (!aRng.IsVoid())
638 //Check cases like this:
640 // ************** aCirc1
643 // *************** aCirc2
645 Standard_Real aPar = 0.0;
646 aRng.GetIntermediatePoint(0.5, aPar);
647 const gp_Pnt aPCirc2 = ElCLib::Value(aPar, aWorkCirc);
648 const Extrema_POnCurv aP2(aPar, aPCirc2);
650 Extrema_ExtPElC ExtPCir(aPCirc2,
651 Extrema_CurveTool::Circle(*((Adaptor3d_Curve*) myC[0])),
652 Precision::Confusion(), theUt11, theUt12);
654 Standard_Boolean isFound = !myIsPar;
658 //If the flag myIsPar was set earlier then it does not mean that
659 //we have found the minimal distance. Here we check it. If there is
660 //a pair of points, which are in less distance then myIsPar flag
661 //was unset and the algorithm will return these nearest points.
663 for (Standard_Integer anExtID = 1; anExtID <= ExtPCir.NbExt(); anExtID++)
665 if (ExtPCir.SquareDistance(anExtID) < aMinSquareDist)
667 isFound = Standard_True;
676 myIsPar = Standard_False;
677 for (Standard_Integer anExtID = 1; anExtID <= ExtPCir.NbExt(); anExtID++)
679 mypoints.Append(ExtPCir.Point(anExtID));
680 mypoints.Append(aP2);
681 mySqDist.Append(ExtPCir.SquareDistance(anExtID));
682 aMinSquareDist = Min(aMinSquareDist, ExtPCir.SquareDistance(anExtID));
687 aProjRng1.Shift(M_PI);
692 //=======================================================================
695 //=======================================================================
697 void Extrema_ExtCC::PrepareResults(const Extrema_ExtElC& AlgExt,
698 const Standard_Boolean theIsInverse,
699 const Standard_Real Ut11,
700 const Standard_Real Ut12,
701 const Standard_Real Ut21,
702 const Standard_Real Ut22)
704 Standard_Integer i, NbExt;
705 Standard_Real Val, U, U2;
706 Extrema_POnCurv P1, P2;
708 myDone = AlgExt.IsDone();
710 myIsPar = AlgExt.IsParallel();
712 PrepareParallelResult(Ut11, Ut12, Ut21, Ut22, AlgExt.SquareDistance());
715 NbExt = AlgExt.NbExt();
716 for (i = 1; i <= NbExt; i++) {
717 // Verification de la validite des parametres
718 AlgExt.Points(i, P1, P2);
729 if (Extrema_CurveTool::IsPeriodic(*((Adaptor3d_Curve*)myC[0]))) {
730 U = ElCLib::InPeriod(U, Ut11, Ut11+Extrema_CurveTool::Period(*((Adaptor3d_Curve*)myC[0])));
732 if (Extrema_CurveTool::IsPeriodic(*((Adaptor3d_Curve*)myC[1]))) {
733 U2 = ElCLib::InPeriod(U2, Ut21, Ut21+Extrema_CurveTool::Period(*((Adaptor3d_Curve*)myC[1])));
736 if ((U >= Ut11 - RealEpsilon()) &&
737 (U <= Ut12 + RealEpsilon()) &&
738 (U2 >= Ut21 - RealEpsilon()) &&
739 (U2 <= Ut22 + RealEpsilon())) {
740 Val = AlgExt.SquareDistance(i);
741 mySqDist.Append(Val);
744 P1.SetValues(U, P1.Value());
745 P2.SetValues(U2, P2.Value());
750 P1.SetValues(U2, P1.Value());
751 P2.SetValues(U, P2.Value());
763 //=======================================================================
766 //=======================================================================
768 void Extrema_ExtCC::PrepareResults(const Extrema_ECC& AlgExt,
769 const Standard_Real Ut11,
770 const Standard_Real Ut12,
771 const Standard_Real Ut21,
772 const Standard_Real Ut22)
774 Standard_Integer i, NbExt;
775 Standard_Real Val, U, U2;
776 Extrema_POnCurv P1, P2;
778 myDone = AlgExt.IsDone();
781 myIsPar = AlgExt.IsParallel();
784 PrepareParallelResult(Ut11, Ut12, Ut21, Ut22, AlgExt.SquareDistance());
788 NbExt = AlgExt.NbExt();
789 for (i = 1; i <= NbExt; i++)
791 AlgExt.Points(i, P1, P2);
795 // Check points to be into param space.
796 if (Extrema_CurveTool::IsPeriodic(*((Adaptor3d_Curve*) myC[0])))
798 U = ElCLib::InPeriod(U, Ut11, Ut11 + Extrema_CurveTool::Period(*((Adaptor3d_Curve*) myC[0])));
800 if (Extrema_CurveTool::IsPeriodic(*((Adaptor3d_Curve*) myC[1])))
802 U2 = ElCLib::InPeriod(U2, Ut21, Ut21 + Extrema_CurveTool::Period(*((Adaptor3d_Curve*) myC[1])));
805 if ((U >= Ut11 - RealEpsilon()) &&
806 (U <= Ut12 + RealEpsilon()) &&
807 (U2 >= Ut21 - RealEpsilon()) &&
808 (U2 <= Ut22 + RealEpsilon()))
810 Val = AlgExt.SquareDistance(i);
811 mySqDist.Append(Val);
812 P1.SetValues(U, P1.Value());
813 P2.SetValues(U2, P2.Value());
822 //=======================================================================
823 //function : SetSingleSolutionFlag
825 //=======================================================================
826 void Extrema_ExtCC::SetSingleSolutionFlag(const Standard_Boolean theFlag)
828 myIsFindSingleSolution = theFlag;
831 //=======================================================================
832 //function : GetSingleSolutionFlag
834 //=======================================================================
835 Standard_Boolean Extrema_ExtCC::GetSingleSolutionFlag() const
837 return myIsFindSingleSolution;