{
if (theA.X() == theB.X())
{
- if (theA.Y() <= theB.Y())
+ if (theA.Y() < theB.Y())
return Standard_True;
}
}
//purpose :
//=======================================================================
Extrema_GenExtCC::Extrema_GenExtCC()
-: myParallel(Standard_False),
+: myIsFindSingleSolution(Standard_False),
+ myParallel(Standard_False),
myCurveMinTol(Precision::PConfusion()),
myLowBorder(1,2),
myUppBorder(1,2),
//=======================================================================
Extrema_GenExtCC::Extrema_GenExtCC(const Curve1& C1,
const Curve2& C2)
-: myParallel(Standard_False),
+: myIsFindSingleSolution(Standard_False),
+ myParallel(Standard_False),
myCurveMinTol(Precision::PConfusion()),
myLowBorder(1,2),
myUppBorder(1,2),
const Standard_Real Usup,
const Standard_Real Vinf,
const Standard_Real Vsup)
-: myParallel(Standard_False),
+: myIsFindSingleSolution(Standard_False),
+ myParallel(Standard_False),
myCurveMinTol(Precision::PConfusion()),
myLowBorder(1,2),
myUppBorder(1,2),
Curve2 &C2 = *(Curve2*)myC[1];
Standard_Integer aNbInter[2];
- aNbInter[0] = C1.NbIntervals(GeomAbs_C2);
- aNbInter[1] = C2.NbIntervals(GeomAbs_C2);
+ GeomAbs_Shape aContinuity = GeomAbs_C2;
+ aNbInter[0] = C1.NbIntervals(aContinuity);
+ aNbInter[1] = C2.NbIntervals(aContinuity);
+
+ if (aNbInter[0] * aNbInter[1] > 100)
+ {
+ aContinuity = GeomAbs_C1;
+ aNbInter[0] = C1.NbIntervals(aContinuity);
+ aNbInter[1] = C2.NbIntervals(aContinuity);
+ }
+
TColStd_Array1OfReal anIntervals1(1, aNbInter[0] + 1);
TColStd_Array1OfReal anIntervals2(1, aNbInter[1] + 1);
- C1.Intervals(anIntervals1, GeomAbs_C2);
- C2.Intervals(anIntervals2, GeomAbs_C2);
+ C1.Intervals(anIntervals1, aContinuity);
+ C2.Intervals(anIntervals2, aContinuity);
+
+ // Lipchitz constant computation.
+ Standard_Real aLC = 9.0; // Default value.
+ const Standard_Real aMaxDer1 = 1.0 / C1.Resolution(1.0);
+ const Standard_Real aMaxDer2 = 1.0 / C2.Resolution(1.0);
+ const Standard_Real aMaxDer = Max(aMaxDer1, aMaxDer2) * Sqrt(2.0);
+ if (aLC > aMaxDer)
+ aLC = aMaxDer;
+
+ // Change constant value according to the concrete curve types.
+ Standard_Boolean isConstLockedFlag = Standard_False;
+ if (C1.GetType() == GeomAbs_Line)
+ {
+ Standard_Real aMaxDer = 1.0 / C2.Resolution(1.0);
+ if (aLC > aMaxDer)
+ {
+ isConstLockedFlag = Standard_True;
+ aLC = aMaxDer;
+ }
+ }
+ if (C2.GetType() == GeomAbs_Line)
+ {
+ Standard_Real aMaxDer = 1.0 / C1.Resolution(1.0);
+ if (aLC > aMaxDer)
+ {
+ isConstLockedFlag = Standard_True;
+ aLC = aMaxDer;
+ }
+ }
Extrema_GlobOptFuncCCC2 aFunc (C1, C2);
- math_GlobOptMin aFinder(&aFunc, myLowBorder, myUppBorder);
+ math_GlobOptMin aFinder(&aFunc, myLowBorder, myUppBorder, aLC);
+ aFinder.SetLipConstState(isConstLockedFlag);
+ aFinder.SetContinuity(aContinuity == GeomAbs_C2 ? 2 : 1);
Standard_Real aDiscTol = 1.0e-2;
Standard_Real aValueTol = 1.0e-2;
Standard_Real aSameTol = myCurveMinTol / (aDiscTol);
aFinder.SetTol(aDiscTol, aSameTol);
+ aFinder.SetFunctionalMinimalValue(0.0); // Best distance cannot be lower than 0.0.
// Size computed to have cell index inside of int32 value.
const Standard_Real aCellSize = Max(anIntervals1.Upper() - anIntervals1.Lower(),
aSecondBorderInterval(2) = anIntervals2(j + 1);
aFinder.SetLocalParams(aFirstBorderInterval, aSecondBorderInterval);
- aFinder.Perform();
+ aFinder.Perform(GetSingleSolutionFlag());
// Check that solution found on current interval is not worse than previous.
aCurrF = aFinder.GetF();
// Check for infinity solutions case, for this:
// Sort points lexicographically and check midpoint between each two neighboring points.
// If all midpoints functional value is acceptable
- // then set myParallel flag to true and return one soulution.
+ // then set myParallel flag to true and return one solution.
std::sort(aPnts.begin(), aPnts.end(), comp);
Standard_Boolean isParallel = Standard_False;
Standard_Real aVal = 0.0;
P1.SetValues(myPoints1(N), Tool1::Value(*((Curve1*)myC[0]), myPoints1(N)));
P2.SetValues(myPoints2(N), Tool2::Value(*((Curve2*)myC[1]), myPoints2(N)));
}
+
+//=======================================================================
+//function : SetSingleSolutionFlag
+//purpose :
+//=======================================================================
+void Extrema_GenExtCC::SetSingleSolutionFlag(const Standard_Boolean theFlag)
+{
+ myIsFindSingleSolution = theFlag;
+}
+
+//=======================================================================
+//function : GetSingleSolutionFlag
+//purpose :
+//=======================================================================
+Standard_Boolean Extrema_GenExtCC::GetSingleSolutionFlag() const
+{
+ return myIsFindSingleSolution;
+}