0025004: Extrema curve/curve incorrect result
[occt.git] / src / Extrema / Extrema_GenExtCC.gxx
index 90e4e8a..a793d9c 100644 (file)
 #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()")