mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-14 13:30:48 +03:00
0025004: Extrema curve/curve incorrect result
Fixed bug in extrema clustering algorithm. Tolerances changing is available now. Testcase with Branin function added. Test cases for issue CR25004
This commit is contained in:
@@ -163,6 +163,7 @@ void Extrema_ExtCC::Perform()
|
||||
Standard_NullObject_Raise_if (!myC[0] || !myC[1], "Extrema_ExtCC::Perform()")
|
||||
myECC.SetParams(*((Adaptor3d_Curve*)myC[0]),
|
||||
*((Adaptor3d_Curve*)myC[1]), myInf[0], mySup[0], myInf[1], mySup[1]);
|
||||
myECC.SetTolerance(Min(myTol[0], myTol[1]));
|
||||
myDone = Standard_False;
|
||||
mypoints.Clear();
|
||||
mySqDist.Clear();
|
||||
|
@@ -44,18 +44,21 @@ is
|
||||
---Purpose: It calculates all the distances.
|
||||
-- The function F(u,v)=distance(C1(u),C2(v)) has an
|
||||
-- extremum when gradient(f)=0. The algorithm uses
|
||||
-- Evtushenko's global optimization solver..
|
||||
-- Evtushenko's global optimization solver.
|
||||
|
||||
Create (C1: Curve1; C2: Curve2; Uinf, Usup, Vinf, Vsup: Real) returns GenExtCC;
|
||||
---Purpose: Calculates all the distances as above
|
||||
-- between Uinf and Usup for C1 and between Vinf and Vsup
|
||||
-- for C2.
|
||||
|
||||
SetParams(me: in out; C1: Curve1; C2: Curve2; Uinf, Usup, Vinf, Vsup: Real)
|
||||
SetParams (me: in out; C1: Curve1; C2: Curve2; Uinf, Usup, Vinf, Vsup: Real)
|
||||
---Purpose: Set params in case of empty constructor is usage.
|
||||
is static;
|
||||
|
||||
Perform(me: in out) is static;
|
||||
SetTolerance (me: in out; Tol: Real);
|
||||
---Purpose:
|
||||
|
||||
Perform (me: in out) is static;
|
||||
---Purpose: Performs calculations.
|
||||
|
||||
|
||||
@@ -93,12 +96,13 @@ is
|
||||
is static;
|
||||
|
||||
fields
|
||||
myLowBorder : Vector from math;
|
||||
myUppBorder : Vector from math;
|
||||
mySolCount : Integer from Standard;
|
||||
myPoints1 : SequenceOfReal from TColStd;
|
||||
myPoints2 : SequenceOfReal from TColStd;
|
||||
myC : Address from Standard [2];
|
||||
myDone : Boolean;
|
||||
myCurveMinTol : Real from Standard;
|
||||
myLowBorder : Vector from math;
|
||||
myUppBorder : Vector from math;
|
||||
mySolCount : Integer from Standard;
|
||||
myPoints1 : SequenceOfReal from TColStd;
|
||||
myPoints2 : SequenceOfReal from TColStd;
|
||||
myC : Address from Standard [2];
|
||||
myDone : Boolean;
|
||||
|
||||
end GenExtCC;
|
||||
|
@@ -22,6 +22,10 @@
|
||||
#include <TColStd_Array1OfReal.hxx>
|
||||
#include <Precision.hxx>
|
||||
|
||||
//=======================================================================
|
||||
//function : Extrema_GenExtCC
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Extrema_GenExtCC::Extrema_GenExtCC()
|
||||
: myLowBorder(1,2),
|
||||
myUppBorder(1,2),
|
||||
@@ -29,8 +33,12 @@ Extrema_GenExtCC::Extrema_GenExtCC()
|
||||
{
|
||||
}
|
||||
|
||||
Extrema_GenExtCC::Extrema_GenExtCC (const Curve1& C1,
|
||||
const Curve2& C2)
|
||||
//=======================================================================
|
||||
//function : Extrema_GenExtCC
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Extrema_GenExtCC::Extrema_GenExtCC(const Curve1& C1,
|
||||
const Curve2& C2)
|
||||
: myLowBorder(1,2),
|
||||
myUppBorder(1,2),
|
||||
myDone(Standard_False)
|
||||
@@ -41,15 +49,19 @@ Extrema_GenExtCC::Extrema_GenExtCC (const Curve1& C1,
|
||||
myLowBorder(2) = C2.FirstParameter();
|
||||
myUppBorder(1) = C1.LastParameter();
|
||||
myUppBorder(2) = C2.LastParameter();
|
||||
myCurveMinTol = 1.0e-9;
|
||||
}
|
||||
|
||||
|
||||
Extrema_GenExtCC::Extrema_GenExtCC (const Curve1& C1,
|
||||
const Curve2& C2,
|
||||
const Standard_Real Uinf,
|
||||
const Standard_Real Usup,
|
||||
const Standard_Real Vinf,
|
||||
const Standard_Real Vsup)
|
||||
//=======================================================================
|
||||
//function : Extrema_GenExtCC
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Extrema_GenExtCC::Extrema_GenExtCC(const Curve1& C1,
|
||||
const Curve2& C2,
|
||||
const Standard_Real Uinf,
|
||||
const Standard_Real Usup,
|
||||
const Standard_Real Vinf,
|
||||
const Standard_Real Vsup)
|
||||
: myLowBorder(1,2),
|
||||
myUppBorder(1,2),
|
||||
myDone(Standard_False)
|
||||
@@ -60,14 +72,19 @@ Extrema_GenExtCC::Extrema_GenExtCC (const Curve1& C1,
|
||||
myLowBorder(2) = Vinf;
|
||||
myUppBorder(1) = Usup;
|
||||
myUppBorder(2) = Vsup;
|
||||
myCurveMinTol = 1.0e-9;
|
||||
}
|
||||
|
||||
void Extrema_GenExtCC::SetParams (const Curve1& C1,
|
||||
const Curve2& C2,
|
||||
const Standard_Real Uinf,
|
||||
const Standard_Real Usup,
|
||||
const Standard_Real Vinf,
|
||||
const Standard_Real Vsup)
|
||||
//=======================================================================
|
||||
//function : SetParams
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void Extrema_GenExtCC::SetParams(const Curve1& C1,
|
||||
const Curve2& C2,
|
||||
const Standard_Real Uinf,
|
||||
const Standard_Real Usup,
|
||||
const Standard_Real Vinf,
|
||||
const Standard_Real Vsup)
|
||||
{
|
||||
myC[0] = (Standard_Address)&C1;
|
||||
myC[1] = (Standard_Address)&C2;
|
||||
@@ -77,8 +94,20 @@ void Extrema_GenExtCC::SetParams (const Curve1& C1,
|
||||
myUppBorder(2) = Vsup;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
void Extrema_GenExtCC::Perform ()
|
||||
//=======================================================================
|
||||
//function : SetTolerance
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void Extrema_GenExtCC::SetTolerance(Standard_Real theTol)
|
||||
{
|
||||
myCurveMinTol = theTol;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Perform
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void Extrema_GenExtCC::Perform()
|
||||
{
|
||||
myDone = Standard_False;
|
||||
|
||||
@@ -95,6 +124,10 @@ void Extrema_GenExtCC::Perform ()
|
||||
|
||||
math_MultipleVarFunction *aFunc = new Extrema_GlobOptFuncCCC2(C1, C2);
|
||||
math_GlobOptMin aFinder(aFunc, myLowBorder, myUppBorder);
|
||||
Standard_Real aDiscTol = 1.0e-2;
|
||||
Standard_Real aValueTol = 1.0e-2;
|
||||
Standard_Real aSameTol = myCurveMinTol / (aDiscTol);
|
||||
aFinder.SetTol(aDiscTol, aSameTol);
|
||||
|
||||
Standard_Integer i,j,k;
|
||||
math_Vector aFirstBorderInterval(1,2);
|
||||
@@ -114,12 +147,15 @@ void Extrema_GenExtCC::Perform ()
|
||||
aFinder.Perform();
|
||||
|
||||
aCurrF = aFinder.GetF();
|
||||
if (aCurrF < aF + Precision::Confusion())
|
||||
if (aCurrF < aF + aSameTol * aValueTol)
|
||||
{
|
||||
if (aCurrF > Abs(aF - Precision::Confusion()) || (aCurrF < 1.0e-15 && aF < 1.0e-15))
|
||||
if (aCurrF > aF - aSameTol * aValueTol)
|
||||
{
|
||||
Standard_Integer myTmpSolCount = aFinder.NbExtrema();
|
||||
if (aCurrF < aF)
|
||||
aF = aCurrF;
|
||||
|
||||
math_Vector sol(1,2);
|
||||
Standard_Integer myTmpSolCount = aFinder.NbExtrema();
|
||||
for(k = 1; k <= myTmpSolCount; k++)
|
||||
{
|
||||
aFinder.Points(k, sol);
|
||||
@@ -127,7 +163,7 @@ void Extrema_GenExtCC::Perform ()
|
||||
myPoints2.Append(sol(2));
|
||||
}
|
||||
mySolCount += myTmpSolCount;
|
||||
} // if (aCurrF > aF - Precision::Confusion())
|
||||
} // if (aCurrF > aF - aSameTol * aValueTol)
|
||||
else
|
||||
{
|
||||
aF = aCurrF;
|
||||
@@ -142,7 +178,7 @@ void Extrema_GenExtCC::Perform ()
|
||||
myPoints2.Append(sol(2));
|
||||
}
|
||||
} // else
|
||||
} //if (aCurrF < aF + Precision::Confusion())
|
||||
} //if (aCurrF < aF + aSameTol * aValueTol)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,10 +187,10 @@ void Extrema_GenExtCC::Perform ()
|
||||
{
|
||||
for(j = i + 1; j <= mySolCount; j++)
|
||||
{
|
||||
if ((myPoints1(i) - myPoints1(j)) < (myUppBorder(1) - myLowBorder(1)) * Precision::Confusion() &&
|
||||
(myPoints2(i) - myPoints2(j)) < (myUppBorder(2) - myLowBorder(2)) * Precision::Confusion())
|
||||
if (Abs(myPoints1(i) - myPoints1(j)) < (myUppBorder(1) - myLowBorder(1)) * Precision::Confusion() &&
|
||||
Abs(myPoints2(i) - myPoints2(j)) < (myUppBorder(2) - myLowBorder(2)) * Precision::Confusion())
|
||||
{
|
||||
// Points with indexes i and j is in same cluster, delete j point from it.
|
||||
// Points with indexes i and j is in same cluster, delete j point from extrema array.
|
||||
myPoints1.Remove(j);
|
||||
myPoints2.Remove(j);
|
||||
j--;
|
||||
@@ -166,34 +202,46 @@ void Extrema_GenExtCC::Perform ()
|
||||
delete aFunc;
|
||||
myDone = Standard_True;
|
||||
}
|
||||
//=============================================================================
|
||||
|
||||
Standard_Boolean Extrema_GenExtCC::IsDone () const
|
||||
//=======================================================================
|
||||
//function : IsDone
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Standard_Boolean Extrema_GenExtCC::IsDone() const
|
||||
{
|
||||
return myDone;
|
||||
}
|
||||
//=============================================================================
|
||||
|
||||
Standard_Integer Extrema_GenExtCC::NbExt () const
|
||||
//=======================================================================
|
||||
//function : NbExt
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Standard_Integer Extrema_GenExtCC::NbExt() const
|
||||
{
|
||||
StdFail_NotDone_Raise_if (!myDone, "Extrema_GenExtCC::NbExt()")
|
||||
|
||||
return mySolCount;
|
||||
}
|
||||
//=============================================================================
|
||||
|
||||
Standard_Real Extrema_GenExtCC::SquareDistance (const Standard_Integer N) const
|
||||
//=======================================================================
|
||||
//function : SquareDistance
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Standard_Real Extrema_GenExtCC::SquareDistance(const Standard_Integer N) const
|
||||
{
|
||||
StdFail_NotDone_Raise_if (!myDone, "Extrema_GenExtCC::SquareDistance()")
|
||||
Standard_OutOfRange_Raise_if ((N < 1 || N > NbExt()), "Extrema_GenExtCC::SquareDistance()")
|
||||
|
||||
return Tool1::Value(*((Curve1*)myC[0]), myPoints1(N)).SquareDistance(Tool2::Value(*((Curve2*)myC[1]), myPoints2(N)));
|
||||
}
|
||||
//=============================================================================
|
||||
|
||||
void Extrema_GenExtCC::Points (const Standard_Integer N,
|
||||
POnC& P1,
|
||||
POnC& P2) const
|
||||
//=======================================================================
|
||||
//function : Points
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
void Extrema_GenExtCC::Points(const Standard_Integer N,
|
||||
POnC& P1,
|
||||
POnC& P2) const
|
||||
{
|
||||
StdFail_NotDone_Raise_if (!myDone, "Extrema_GenExtCC::Points()")
|
||||
Standard_OutOfRange_Raise_if ((N < 1 || N > NbExt()), "Extrema_GenExtCC::Points()")
|
||||
|
Reference in New Issue
Block a user