// fois la meme solution
#include <Adaptor3d_Curve.hxx>
+#include <Bnd_Range.hxx>
#include <ElCLib.hxx>
#include <Extrema_CurveTool.hxx>
#include <Extrema_ECC.hxx>
myDone (Standard_False)
{
myC[0] = 0; myC[1] = 0;
+ myInf[0] = myInf[1] = -Precision::Infinite();
+ mySup[0] = mySup[1] = Precision::Infinite();
myTol[0] = TolC1; myTol[1] = TolC2;
+ mydist11 = mydist12 = mydist21 = mydist22 = RealFirst();
}
//=======================================================================
SetCurve (2, C2, V1, V2);
SetTolerance (1, TolC1);
SetTolerance (2, TolC2);
+ mydist11 = mydist12 = mydist21 = mydist22 = RealFirst();
Perform();
}
SetCurve (2, C2, C2.FirstParameter(), C2.LastParameter());
SetTolerance (1, TolC1);
SetTolerance (2, TolC2);
+ mydist11 = mydist12 = mydist21 = mydist22 = RealFirst();
Perform();
}
GeomAbs_CurveType type1 = (*((Adaptor3d_Curve*)myC[0])).GetType();
GeomAbs_CurveType type2 = (*((Adaptor3d_Curve*)myC[1])).GetType();
Standard_Real U11, U12, U21, U22, Tol = Min(myTol[0], myTol[1]);
- mynbext = 0;
- inverse = Standard_False;
U11 = myInf[0];
U12 = mySup[0];
//analytical case - one curve is always a line
Standard_Integer anInd1 = 0, anInd2 = 1;
GeomAbs_CurveType aType2 = type2;
- inverse = (type1 > type2);
- if (inverse) {
+ Standard_Boolean isInverse = (type1 > type2);
+ if (isInverse)
+ {
//algorithm uses inverse order of arguments
anInd1 = 1;
anInd2 = 0;
switch (aType2) {
case GeomAbs_Line: {
Extrema_ExtElC Xtrem((*((Adaptor3d_Curve*)myC[anInd1])).Line(), (*((Adaptor3d_Curve*)myC[anInd2])).Line(), Tol);
- Results(Xtrem, U11, U12, U21, U22);
+ PrepareResults(Xtrem, isInverse, U11, U12, U21, U22);
break;
}
case GeomAbs_Circle: {
Extrema_ExtElC Xtrem((*((Adaptor3d_Curve*)myC[anInd1])).Line(), (*((Adaptor3d_Curve*)myC[anInd2])).Circle(), Tol);
- Results(Xtrem, U11, U12, U21, U22);
+ PrepareResults(Xtrem, isInverse, U11, U12, U21, U22);
break;
}
case GeomAbs_Ellipse: {
Extrema_ExtElC Xtrem((*((Adaptor3d_Curve*)myC[anInd1])).Line(), (*((Adaptor3d_Curve*)myC[anInd2])).Ellipse());
- Results(Xtrem, U11, U12, U21, U22);
+ PrepareResults(Xtrem, isInverse, U11, U12, U21, U22);
break;
}
case GeomAbs_Hyperbola: {
Extrema_ExtElC Xtrem((*((Adaptor3d_Curve*)myC[anInd1])).Line(), (*((Adaptor3d_Curve*)myC[anInd2])).Hyperbola());
- Results(Xtrem, U11, U12, U21, U22);
+ PrepareResults(Xtrem, isInverse, U11, U12, U21, U22);
break;
}
case GeomAbs_Parabola: {
Extrema_ExtElC Xtrem((*((Adaptor3d_Curve*)myC[anInd1])).Line(), (*((Adaptor3d_Curve*)myC[anInd2])).Parabola());
- Results(Xtrem, U11, U12, U21, U22);
+ PrepareResults(Xtrem, isInverse, U11, U12, U21, U22);
break;
}
default: break;
Extrema_ExtElC CCXtrem ((*((Adaptor3d_Curve*)myC[0])).Circle(), (*((Adaptor3d_Curve*)myC[1])).Circle());
bIsDone = CCXtrem.IsDone();
if(bIsDone) {
- Results(CCXtrem, U11, U12, U21, U22);
+ PrepareResults(CCXtrem, Standard_False, U11, U12, U21, U22);
}
else {
myECC.Perform();
- Results(myECC, U11, U12, U21, U22);
+ PrepareResults(myECC, U11, U12, U21, U22);
}
} else {
myECC.Perform();
- Results(myECC, U11, U12, U21, U22);
+ PrepareResults(myECC, U11, U12, U21, U22);
}
}
Standard_Boolean Extrema_ExtCC::IsParallel() const
{
+ if (!IsDone())
+ {
+ throw StdFail_NotDone();
+ }
+
return myIsPar;
}
Standard_Real Extrema_ExtCC::SquareDistance(const Standard_Integer N) const
{
- if(!myDone) throw StdFail_NotDone();
- if ((N <= 0) || (N > mynbext)) throw Standard_OutOfRange();
+ if ((N < 1) || (N > NbExt())) throw Standard_OutOfRange();
return mySqDist.Value(N);
}
Standard_Integer Extrema_ExtCC::NbExt() const
{
if(!myDone) throw StdFail_NotDone();
- return mynbext;
+ return mySqDist.Length();
}
Extrema_POnCurv& P1,
Extrema_POnCurv& P2) const
{
- if(!myDone) throw StdFail_NotDone();
- if ((N <= 0) || (N > mynbext)) throw Standard_OutOfRange();
- P1 = mypoints.Value(2*N-1);
- P2 = mypoints.Value(2*N);
+ if (IsParallel())
+ {
+ throw StdFail_InfiniteSolutions();
+ }
+
+ if (N < 1 || N > NbExt())
+ {
+ throw Standard_OutOfRange();
+ }
+
+ P1 = mypoints.Value(2 * N - 1);
+ P2 = mypoints.Value(2 * N);
}
P22 = P2l;
}
+//=======================================================================
+//function : ParallelResult
+//purpose :
+//=======================================================================
+void Extrema_ExtCC::PrepareParallelResult(const Standard_Real theUt11,
+ const Standard_Real theUt12,
+ const Standard_Real theUt21,
+ const Standard_Real theUt22,
+ const Standard_Real theSqDist)
+{
+ if (!myIsPar)
+ return;
+ const GeomAbs_CurveType aType1 = Extrema_CurveTool::GetType(*((Adaptor3d_Curve*) myC[0]));
+ const GeomAbs_CurveType aType2 = Extrema_CurveTool::GetType(*((Adaptor3d_Curve*) myC[1]));
+
+ if (((aType1 != GeomAbs_Line) && (aType1 != GeomAbs_Circle)) ||
+ ((aType2 != GeomAbs_Line) && (aType2 != GeomAbs_Circle)))
+ {
+ mySqDist.Append(theSqDist);
+ myDone = Standard_True;
+ myIsPar = Standard_True;
+ return;
+ }
+
+ // Parallel case is only for line-line, circle-circle and circle-line!!!
+ // But really for trimmed curves extremas can not exist!
+ if (aType1 != aType2)
+ {
+ //The projection of the circle's location to the trimmed line must exist.
+ const Standard_Boolean isReversed = (aType1 != GeomAbs_Circle);
+ const gp_Pnt aPonC = !isReversed ?
+ Extrema_CurveTool::Value(*((Adaptor3d_Curve*) myC[0]), theUt11) :
+ Extrema_CurveTool::Value(*((Adaptor3d_Curve*) myC[1]), theUt21);
+
+ const gp_Lin aL = !isReversed ? ((Adaptor3d_Curve*) myC[1])->Line() :
+ ((Adaptor3d_Curve*) myC[0])->Line();
+ const Extrema_ExtPElC ExtPLin(aPonC, aL, Precision::Confusion(),
+ !isReversed ? theUt21 : theUt11,
+ !isReversed ? theUt22 : theUt12);
+
+ if (ExtPLin.IsDone())
+ {
+ mySqDist.Append(theSqDist);
+ }
+ else
+ {
+ myIsPar = Standard_False;
+ }
+
+ return;
+ }
+
+ if (aType1 == GeomAbs_Line)
+ {
+ // Line - Line
+
+ const Standard_Real isFirstInfinite = (Precision::IsInfinite(theUt11) &&
+ Precision::IsInfinite(theUt12));
+ const Standard_Real isLastInfinite = (Precision::IsInfinite(theUt21) &&
+ Precision::IsInfinite(theUt22));
+
+ if (isFirstInfinite || isLastInfinite)
+ {
+ // Infinite number of solution
+
+ mySqDist.Append(theSqDist);
+ }
+ else
+ {
+ // The range created by projection of both ends of the 1st line
+ // to the 2nd one must intersect the (native) trimmed range of
+ // the 2nd line.
+
+ myIsPar = Standard_False;
+
+ const gp_Lin aLin1 = ((Adaptor3d_Curve*) myC[0])->Line();
+ const gp_Lin aLin2 = ((Adaptor3d_Curve*) myC[1])->Line();
+ const Standard_Boolean isOpposite(aLin1.Direction().Dot(aLin2.Direction()) < 0.0);
+
+ Bnd_Range aRange2(theUt21, theUt22);
+ Bnd_Range aProjRng12;
+
+ if (Precision::IsInfinite(theUt11))
+ {
+ if (isOpposite)
+ aProjRng12.Add(Precision::Infinite());
+ else
+ aProjRng12.Add(-Precision::Infinite());
+ }
+ else
+ {
+ const gp_Pnt aPonC1 = ElCLib::Value(theUt11, aLin1);
+ const Standard_Real aPar = ElCLib::Parameter(aLin2, aPonC1);
+ aProjRng12.Add(aPar);
+ }
+
+ if (Precision::IsInfinite(theUt12))
+ {
+ if (isOpposite)
+ aProjRng12.Add(-Precision::Infinite());
+ else
+ aProjRng12.Add(Precision::Infinite());
+ }
+ else
+ {
+ const gp_Pnt aPonC1 = ElCLib::Value(theUt12, aLin1);
+ const Standard_Real aPar = ElCLib::Parameter(aLin2, aPonC1);
+ aProjRng12.Add(aPar);
+ }
+
+ aRange2.Common(aProjRng12);
+ if (aRange2.Delta() > Precision::Confusion())
+ {
+ ClearSolutions();
+ mySqDist.Append(theSqDist);
+ myIsPar = Standard_True;
+ }
+ else if (!aRange2.IsVoid())
+ {
+ //Case like this:
+
+ // ************** aLin1
+ // o
+ // o
+ // *************** aLin2
+
+ ClearSolutions();
+ Standard_Real aPar1 = 0.0, aPar2 = 0.0;
+ aRange2.GetBounds(aPar1, aPar2);
+ aPar2 = 0.5*(aPar1 + aPar2);
+ gp_Pnt aP = ElCLib::Value(aPar2, aLin2);
+ const Extrema_POnCurv aP2(aPar2, aP);
+ aPar1 = ElCLib::Parameter(aLin1, aP);
+ aP = ElCLib::Value(aPar1, aLin1);
+ const Extrema_POnCurv aP1(aPar1, aP);
+ mypoints.Append(aP1);
+ mypoints.Append(aP2);
+ mySqDist.Append(theSqDist);
+ }
+ }
+ }
+ else
+ {
+ // Circle - Circle
+ myIsPar = Standard_False;
+
+ //Two arcs with ranges [U1, U2] and [V1, V2] correspondingly are
+ //considered to be parallel in the following case:
+ // The range created by projection both points U1 and U2 of the
+ // 1st circle to the 2nd one intersects either the range [V1, V2] or
+ // the range [V1-PI, V2-PI]. All ranges must be adjusted to correspond
+ // periodic range before checking of intersection.
+
+ const gp_Circ aWorkCirc = ((Adaptor3d_Curve*) myC[1])->Circle();
+ const Standard_Real aPeriod = M_PI + M_PI;
+ gp_Vec aVTg1;
+ gp_Pnt aP11;
+ const gp_Pnt aP12 = Extrema_CurveTool::Value(*((Adaptor3d_Curve*) myC[0]), theUt12);
+ Extrema_CurveTool::D1(*((Adaptor3d_Curve*) myC[0]), theUt11, aP11, aVTg1);
+
+ const Bnd_Range aRange(theUt21, theUt22);
+ Bnd_Range aProjRng1;
+
+ // Project arc of the 1st circle between points theUt11 and theUt12 to the
+ // 2nd circle. It is necessary to chose correct arc from two possible ones.
+
+ Standard_Real aPar1 = ElCLib::InPeriod(ElCLib::Parameter(aWorkCirc, aP11),
+ theUt21, theUt21 + aPeriod);
+ const gp_Vec aVTg2 = Extrema_CurveTool::DN(*((Adaptor3d_Curve*) myC[1]), aPar1, 1);
+
+ // Check if circles have same/opposite directions
+ const Standard_Boolean isOpposite(aVTg1.Dot(aVTg2) < 0.0);
+
+ Standard_Real aPar2 = ElCLib::InPeriod(ElCLib::Parameter(aWorkCirc, aP12),
+ theUt21, theUt21 + aPeriod);
+
+ if (isOpposite)
+ {
+ // Must be aPar2 < aPar1
+ if ((aRange.Delta() > Precision::Angular()) &&
+ ((aPar1 - aPar2) < Precision::Angular()))
+ {
+ aPar2 -= aPeriod;
+ }
+ }
+ else
+ {
+ // Must be aPar2 > aPar1
+ if ((aRange.Delta() > Precision::Angular()) &&
+ ((aPar2 - aPar1) < Precision::Angular()))
+ {
+ aPar1 -= aPeriod;
+ }
+ }
+
+ // Now the projection result is the range [aPar1, aPar2]
+ // if aPar1 < aPar2 or the range [aPar2, aPar1], otherwise.
+
+ Standard_Real aMinSquareDist = RealLast();
+
+ aProjRng1.Add(aPar1 - M_PI);
+ aProjRng1.Add(aPar2 - M_PI);
+ for (Standard_Integer i = 0; i < 2; i++)
+ {
+ // Repeat computation twice
+
+ Bnd_Range aRng = aProjRng1;
+ aRng.Common(aRange);
+
+ //Cases are possible and processed below:
+ //1. Extrema does not exist. In this case all common ranges are VOID.
+ //2. Arcs are parallel and distance between them is equal to sqrt(theSqDist).
+ // In this case myIsPar = TRUE definitely.
+ //3. Arcs are parallel and distance between them is equal to (sqrt(theSqDist) + R),
+ // where R is the least radius of the both circles. In this case myIsPar flag
+ // will temporary be set to TRUE but check will be continued until less
+ // distance will be found. At that, region with the least distance can be
+ // either a local point or continuous range. In 1st case myIsPar = FALSE and
+ // several (or single) extremas will be returned. In the 2nd one
+ // myIsPar = TRUE and only the least distance will be returned.
+ //4. Arcs are not parallel. Then several (or single) extremas will be returned.
+
+ if (aRng.Delta() > Precision::Angular())
+ {
+ Standard_Real aPar = 0.0;
+ aRng.GetIntermediatePoint(0.5, aPar);
+ const gp_Pnt aPCirc2 = ElCLib::Value(aPar, aWorkCirc);
+ Extrema_ExtPElC ExtPCir(aPCirc2,
+ Extrema_CurveTool::Circle(*((Adaptor3d_Curve*) myC[0])),
+ Precision::Confusion(), theUt11, theUt12);
+
+ Standard_Real aMinSqD = ExtPCir.SquareDistance(1);
+ for (Standard_Integer anExtID = 2; anExtID <= ExtPCir.NbExt(); anExtID++)
+ {
+ aMinSqD = Min(aMinSqD, ExtPCir.SquareDistance(anExtID));
+ }
+
+ if (aMinSqD <= aMinSquareDist)
+ {
+ ClearSolutions();
+ mySqDist.Append(aMinSqD);
+ myIsPar = Standard_True;
+
+ const Standard_Real aDeltaSqDist = aMinSqD - theSqDist;
+ const Standard_Real aSqD = Max(aMinSqD, theSqDist);
+
+ // 0 <= Dist1-Dist2 <= Eps
+ // 0 <= Dist1^2 - Dist2^2 < Eps*(Dist1+Dist2)
+
+ //If Dist1 ~= Dist2 ==> Dist1+Dist2 ~= 2*Dist2.
+ //Consequently,
+ // 0 <= Dist1^2 - Dist2^2 <= 2*Dist2*Eps
+
+ //Or
+ // (Dist1^2 - Dist2^2)^2 <= 4*Dist2^2*Eps^2
+
+ if (aDeltaSqDist*aDeltaSqDist < 4.0*aSqD*Precision::SquareConfusion())
+ {
+ // New solution is found
+ break;
+ }
+ }
+
+ //Nearer solution can be found
+ }
+ else if (!aRng.IsVoid())
+ {
+ //Check cases like this:
+
+ // ************** aCirc1
+ // o
+ // o
+ // *************** aCirc2
+
+ Standard_Real aPar = 0.0;
+ aRng.GetIntermediatePoint(0.5, aPar);
+ const gp_Pnt aPCirc2 = ElCLib::Value(aPar, aWorkCirc);
+ const Extrema_POnCurv aP2(aPar, aPCirc2);
+
+ Extrema_ExtPElC ExtPCir(aPCirc2,
+ Extrema_CurveTool::Circle(*((Adaptor3d_Curve*) myC[0])),
+ Precision::Confusion(), theUt11, theUt12);
+
+ Standard_Boolean isFound = !myIsPar;
+
+ if (!isFound)
+ {
+ //If the flag myIsPar was set earlier then it does not mean that
+ //we have found the minimal distance. Here we check it. If there is
+ //a pair of points, which are in less distance then myIsPar flag
+ //was unset and the algorithm will return these nearest points.
+
+ for (Standard_Integer anExtID = 1; anExtID <= ExtPCir.NbExt(); anExtID++)
+ {
+ if (ExtPCir.SquareDistance(anExtID) < aMinSquareDist)
+ {
+ isFound = Standard_True;
+ break;
+ }
+ }
+ }
+
+ if (isFound)
+ {
+ ClearSolutions();
+ myIsPar = Standard_False;
+ for (Standard_Integer anExtID = 1; anExtID <= ExtPCir.NbExt(); anExtID++)
+ {
+ mypoints.Append(ExtPCir.Point(anExtID));
+ mypoints.Append(aP2);
+ mySqDist.Append(ExtPCir.SquareDistance(anExtID));
+ aMinSquareDist = Min(aMinSquareDist, ExtPCir.SquareDistance(anExtID));
+ }
+ }
+ }
+
+ aProjRng1.Shift(M_PI);
+ }
+ }
+}
//=======================================================================
//function : Results
//purpose :
//=======================================================================
-void Extrema_ExtCC::Results(const Extrema_ExtElC& AlgExt,
- const Standard_Real Ut11,
- const Standard_Real Ut12,
- const Standard_Real Ut21,
- const Standard_Real Ut22)
+void Extrema_ExtCC::PrepareResults(const Extrema_ExtElC& AlgExt,
+ const Standard_Boolean theIsInverse,
+ const Standard_Real Ut11,
+ const Standard_Real Ut12,
+ const Standard_Real Ut21,
+ const Standard_Real Ut22)
{
Standard_Integer i, NbExt;
Standard_Real Val, U, U2;
if (myDone) {
myIsPar = AlgExt.IsParallel();
if (myIsPar) {
- GeomAbs_CurveType type = Extrema_CurveTool::GetType(*((Adaptor3d_Curve*)myC[0]));
- GeomAbs_CurveType type2 = Extrema_CurveTool::GetType(*((Adaptor3d_Curve*)myC[1]));
- // Parallel case is only for line-line, circle-circle and circle-line!!!
- // But really for trimmed curves extremas can not exist!
- Extrema_POnCurv dummypoint(0., gp_Pnt(0.,0.,0.));
- if(type != type2) {
- mySqDist.Append(AlgExt.SquareDistance(1));
- if(type == GeomAbs_Circle) {
- gp_Pnt PonC1 = Extrema_CurveTool::Value(*((Adaptor3d_Curve*)myC[0]), Ut11);
- P1.SetValues(Ut11, PonC1);
- Extrema_ExtPElC ExtPLin(PonC1, Extrema_CurveTool::Line(*((Adaptor3d_Curve*)myC[1])), Precision::Confusion(), Ut21, Ut22);
- if(ExtPLin.IsDone()) {
- mynbext = 1;
- P2 = ExtPLin.Point(1);
- mypoints.Append(P1);
- mypoints.Append(P2);
- }
- else {
- myIsPar = Standard_False;
- mynbext = 0;
- mypoints.Append(dummypoint);
- mypoints.Append(dummypoint);
- }
- }
- else {
- gp_Pnt PonC2 = Extrema_CurveTool::Value(*((Adaptor3d_Curve*)myC[1]), Ut21);
- P2.SetValues(Ut21, PonC2);
- Extrema_ExtPElC ExtPLin(PonC2, Extrema_CurveTool::Line(*((Adaptor3d_Curve*)myC[0])), Precision::Confusion(), Ut11, Ut12);
- if(ExtPLin.IsDone()) {
- mynbext = 1;
- P1 = ExtPLin.Point(1);
- mypoints.Append(P1);
- mypoints.Append(P2);
- }
- else {
- myIsPar = Standard_False;
- mynbext = 0;
- mypoints.Append(dummypoint);
- mypoints.Append(dummypoint);
- }
- }
- return;
- }
-
- if(type == GeomAbs_Line) {
- Standard_Boolean infinite = Precision::IsInfinite(Ut11) &&
- Precision::IsInfinite(Ut12) &&
- Precision::IsInfinite(Ut21) &&
- Precision::IsInfinite(Ut22);
-
- if(infinite) {
- mynbext = 1;
- mySqDist.Append(AlgExt.SquareDistance(1));
- gp_Pnt PonC1 = Extrema_CurveTool::Value(*((Adaptor3d_Curve*)myC[0]), 0.);
- P1.SetValues(0., PonC1);
- Extrema_ExtPElC ExtPLin(PonC1, Extrema_CurveTool::Line(*((Adaptor3d_Curve*)myC[1])), Precision::Confusion(), Ut21, Ut22);
- if(ExtPLin.IsDone()) {
- P2 = ExtPLin.Point(1);
- mypoints.Append(P1);
- mypoints.Append(P2);
- }
- else {
- myIsPar = Standard_False;
- mypoints.Append(dummypoint);
- mypoints.Append(dummypoint);
- }
- }
- else {
- Standard_Boolean finish = Standard_False;
- if(!Precision::IsInfinite(Ut11)) {
- gp_Pnt PonC1 = Extrema_CurveTool::Value(*((Adaptor3d_Curve*)myC[0]), Ut11);
- Extrema_ExtPElC ExtPLin(PonC1, Extrema_CurveTool::Line(*((Adaptor3d_Curve*)myC[1])), Precision::Confusion(), Ut21, Ut22);
- if(ExtPLin.IsDone() && ExtPLin.NbExt() > 0) {
- mynbext = 1;
- mySqDist.Append(AlgExt.SquareDistance(1));
- P1.SetValues(Ut11, PonC1);
- P2 = ExtPLin.Point(1);
- mypoints.Append(P1);
- mypoints.Append(P2);
- finish = Standard_True;
- }
- }
- if(!finish) {
- if(!Precision::IsInfinite(Ut12)) {
- gp_Pnt PonC1 = Extrema_CurveTool::Value(*((Adaptor3d_Curve*)myC[0]), Ut12);
- Extrema_ExtPElC ExtPLin(PonC1, Extrema_CurveTool::Line(*((Adaptor3d_Curve*)myC[1])), Precision::Confusion(), Ut21, Ut22);
- if(ExtPLin.IsDone() && ExtPLin.NbExt() > 0) {
- mynbext = 1;
- mySqDist.Append(AlgExt.SquareDistance(1));
- P1.SetValues(Ut12, PonC1);
- P2 = ExtPLin.Point(1);
- mypoints.Append(P1);
- mypoints.Append(P2);
- finish = Standard_True;
- }
- }
- }
- if(!finish) {
- if(!Precision::IsInfinite(Ut21)) {
- gp_Pnt PonC2 = Extrema_CurveTool::Value(*((Adaptor3d_Curve*)myC[1]), Ut21);
- Extrema_ExtPElC ExtPLin(PonC2, Extrema_CurveTool::Line(*((Adaptor3d_Curve*)myC[0])), Precision::Confusion(), Ut11, Ut12);
- if(ExtPLin.IsDone() && ExtPLin.NbExt() > 0) {
- mynbext = 1;
- mySqDist.Append(AlgExt.SquareDistance(1));
- P2.SetValues(Ut21, PonC2);
- P1 = ExtPLin.Point(1);
- mypoints.Append(P1);
- mypoints.Append(P2);
- finish = Standard_True;
- }
- }
- }
- if(!finish) {
- if(!Precision::IsInfinite(Ut22)) {
- gp_Pnt PonC2 = Extrema_CurveTool::Value(*((Adaptor3d_Curve*)myC[1]), Ut22);
- Extrema_ExtPElC ExtPLin(PonC2, Extrema_CurveTool::Line(*((Adaptor3d_Curve*)myC[0])), Precision::Confusion(), Ut11, Ut12);
- if(ExtPLin.IsDone() && ExtPLin.NbExt() > 0) {
- mynbext = 1;
- mySqDist.Append(AlgExt.SquareDistance(1));
- P2.SetValues(Ut22, PonC2);
- P1 = ExtPLin.Point(1);
- mypoints.Append(P1);
- mypoints.Append(P2);
- finish = Standard_True;
- }
- }
- }
- if(!finish) {
- mynbext = 0;
- myIsPar = Standard_False;
- mySqDist.Append(AlgExt.SquareDistance(1));
- mypoints.Append(dummypoint);
- mypoints.Append(dummypoint);
- }
- }
-
- }
- else {
- Standard_Boolean finish = Standard_False;
- gp_Pnt PonC1 = Extrema_CurveTool::Value(*((Adaptor3d_Curve*)myC[0]), Ut11);
- P1.SetValues(Ut11, PonC1);
- Extrema_ExtPElC ExtPCir(PonC1, Extrema_CurveTool::Circle(*((Adaptor3d_Curve*)myC[1])), Precision::Confusion(), Ut21, Ut22);
- if(ExtPCir.IsDone() && ExtPCir.NbExt() > 0) {
- for(i = 1; i <= ExtPCir.NbExt(); i++) {
- mynbext++;
- P2 = ExtPCir.Point(i);
- mySqDist.Append(ExtPCir.SquareDistance(i));
- mypoints.Append(P1);
- mypoints.Append(P2);
- }
- if(mynbext == 2) finish = Standard_True;
- }
- if(!finish) {
- PonC1 = Extrema_CurveTool::Value(*((Adaptor3d_Curve*)myC[0]), Ut12);
- ExtPCir.Perform(PonC1, Extrema_CurveTool::Circle(*((Adaptor3d_Curve*)myC[1])), Precision::Confusion(), Ut21, Ut22);
- P1.SetValues(Ut12, PonC1);
- if(ExtPCir.IsDone() && ExtPCir.NbExt() > 0) {
- if(mynbext == 0) {
- for(i = 1; i <= ExtPCir.NbExt(); i++) {
- mynbext++;
- P2 = ExtPCir.Point(i);
- mySqDist.Append(ExtPCir.SquareDistance(i));
- mypoints.Append(P1);
- mypoints.Append(P2);
- }
- }
- else {
- for(i = 1; i <= ExtPCir.NbExt(); i++) {
- Standard_Real dist = mySqDist(1);
- if(Abs(dist - ExtPCir.SquareDistance(i)) > Precision::Confusion()) {
- mynbext++;
- P2 = ExtPCir.Point(i);
- mySqDist.Append(ExtPCir.SquareDistance(i));
- mypoints.Append(P1);
- mypoints.Append(P2);
- }
- }
- }
-
- if(mynbext == 2) finish = Standard_True;
- }
- }
- if(!finish) {
- gp_Pnt PonC2 = Extrema_CurveTool::Value(*((Adaptor3d_Curve*)myC[1]), Ut21);
- ExtPCir.Perform(PonC2, Extrema_CurveTool::Circle(*((Adaptor3d_Curve*)myC[0])), Precision::Confusion(), Ut11, Ut12);
- P2.SetValues(Ut21, PonC2);
- if(ExtPCir.IsDone() && ExtPCir.NbExt() > 0) {
- if(mynbext == 0) {
- for(i = 1; i <= ExtPCir.NbExt(); i++) {
- mynbext++;
- P1 = ExtPCir.Point(i);
- mySqDist.Append(ExtPCir.SquareDistance(i));
- mypoints.Append(P1);
- mypoints.Append(P2);
- }
- }
- else {
- for(i = 1; i <= ExtPCir.NbExt(); i++) {
- Standard_Real dist = mySqDist(1);
- if(Abs(dist - ExtPCir.SquareDistance(i)) > Precision::Confusion()) {
- mynbext++;
- P1 = ExtPCir.Point(i);
- mySqDist.Append(ExtPCir.SquareDistance(i));
- mypoints.Append(P1);
- mypoints.Append(P2);
- }
- }
- }
-
- if(mynbext == 2) finish = Standard_True;
- }
- }
- if(!finish) {
- gp_Pnt PonC2 = Extrema_CurveTool::Value(*((Adaptor3d_Curve*)myC[1]), Ut22);
- ExtPCir.Perform(PonC2, Extrema_CurveTool::Circle(*((Adaptor3d_Curve*)myC[0])), Precision::Confusion(), Ut11, Ut12);
- P2.SetValues(Ut22, PonC2);
- if(ExtPCir.IsDone() && ExtPCir.NbExt() > 0) {
- if(mynbext == 0) {
- for(i = 1; i <= ExtPCir.NbExt(); i++) {
- mynbext++;
- P1 = ExtPCir.Point(i);
- mySqDist.Append(ExtPCir.SquareDistance(i));
- mypoints.Append(P1);
- mypoints.Append(P2);
- }
- }
- else {
- for(i = 1; i <= ExtPCir.NbExt(); i++) {
- Standard_Real dist = mySqDist(1);
- if(Abs(dist - ExtPCir.SquareDistance(i)) > Precision::Confusion()) {
- mynbext++;
- P1 = ExtPCir.Point(i);
- mySqDist.Append(ExtPCir.SquareDistance(i));
- mypoints.Append(P1);
- mypoints.Append(P2);
- }
- }
- }
-
- if(mynbext == 2) finish = Standard_True;
- }
- }
- if(mynbext == 0) {
- myIsPar = Standard_False;
- mySqDist.Append(AlgExt.SquareDistance(1));
- mypoints.Append(dummypoint);
- mypoints.Append(dummypoint);
- mySqDist.Append(AlgExt.SquareDistance(2));
- mypoints.Append(dummypoint);
- mypoints.Append(dummypoint);
- }
- }
+ PrepareParallelResult(Ut11, Ut12, Ut21, Ut22, AlgExt.SquareDistance());
}
else {
NbExt = AlgExt.NbExt();
for (i = 1; i <= NbExt; i++) {
// Verification de la validite des parametres
AlgExt.Points(i, P1, P2);
- if (!inverse) {
+ if (!theIsInverse)
+ {
U = P1.Parameter();
U2 = P2.Parameter();
}
(U <= Ut12 + RealEpsilon()) &&
(U2 >= Ut21 - RealEpsilon()) &&
(U2 <= Ut22 + RealEpsilon())) {
- mynbext++;
Val = AlgExt.SquareDistance(i);
mySqDist.Append(Val);
- if (!inverse) {
+ if (!theIsInverse)
+ {
P1.SetValues(U, P1.Value());
P2.SetValues(U2, P2.Value());
mypoints.Append(P1);
//purpose :
//=======================================================================
-void Extrema_ExtCC::Results(const Extrema_ECC& AlgExt,
- const Standard_Real Ut11,
- const Standard_Real Ut12,
- const Standard_Real Ut21,
- const Standard_Real Ut22)
+void Extrema_ExtCC::PrepareResults(const Extrema_ECC& AlgExt,
+ const Standard_Real Ut11,
+ const Standard_Real Ut12,
+ const Standard_Real Ut21,
+ const Standard_Real Ut22)
{
Standard_Integer i, NbExt;
Standard_Real Val, U, U2;
if (myDone)
{
myIsPar = AlgExt.IsParallel();
- NbExt = AlgExt.NbExt();
- for (i = 1; i <= NbExt; i++)
+ if (myIsPar)
{
- AlgExt.Points(i, P1, P2);
- U = P1.Parameter();
- U2 = P2.Parameter();
-
- // Check points to be into param space.
- if (Extrema_CurveTool::IsPeriodic(*((Adaptor3d_Curve*)myC[0])))
- {
- U = ElCLib::InPeriod(U, Ut11, Ut11+Extrema_CurveTool::Period(*((Adaptor3d_Curve*)myC[0])));
- }
- if (Extrema_CurveTool::IsPeriodic(*((Adaptor3d_Curve*)myC[1])))
- {
- U2 = ElCLib::InPeriod(U2, Ut21, Ut21+Extrema_CurveTool::Period(*((Adaptor3d_Curve*)myC[1])));
- }
-
- if ((U >= Ut11 - RealEpsilon()) &&
- (U <= Ut12 + RealEpsilon()) &&
- (U2 >= Ut21 - RealEpsilon()) &&
- (U2 <= Ut22 + RealEpsilon()) )
+ PrepareParallelResult(Ut11, Ut12, Ut21, Ut22, AlgExt.SquareDistance());
+ }
+ else
+ {
+ NbExt = AlgExt.NbExt();
+ for (i = 1; i <= NbExt; i++)
{
- mynbext++;
- Val = AlgExt.SquareDistance(i);
- mySqDist.Append(Val);
- P1.SetValues(U, P1.Value());
- P2.SetValues(U2, P2.Value());
- mypoints.Append(P1);
- mypoints.Append(P2);
+ AlgExt.Points(i, P1, P2);
+ U = P1.Parameter();
+ U2 = P2.Parameter();
+
+ // Check points to be into param space.
+ if (Extrema_CurveTool::IsPeriodic(*((Adaptor3d_Curve*) myC[0])))
+ {
+ U = ElCLib::InPeriod(U, Ut11, Ut11 + Extrema_CurveTool::Period(*((Adaptor3d_Curve*) myC[0])));
+ }
+ if (Extrema_CurveTool::IsPeriodic(*((Adaptor3d_Curve*) myC[1])))
+ {
+ U2 = ElCLib::InPeriod(U2, Ut21, Ut21 + Extrema_CurveTool::Period(*((Adaptor3d_Curve*) myC[1])));
+ }
+
+ if ((U >= Ut11 - RealEpsilon()) &&
+ (U <= Ut12 + RealEpsilon()) &&
+ (U2 >= Ut21 - RealEpsilon()) &&
+ (U2 <= Ut22 + RealEpsilon()))
+ {
+ Val = AlgExt.SquareDistance(i);
+ mySqDist.Append(Val);
+ P1.SetValues(U, P1.Value());
+ P2.SetValues(U2, P2.Value());
+ mypoints.Append(P1);
+ mypoints.Append(P2);
+ }
}
}
}