diff --git a/src/Extrema/Extrema_FuncExtCC.gxx b/src/Extrema/Extrema_FuncExtCC.gxx index 7eda01c766..19317b8160 100755 --- a/src/Extrema/Extrema_FuncExtCC.gxx +++ b/src/Extrema/Extrema_FuncExtCC.gxx @@ -23,19 +23,19 @@ // GetStateNumber() /*----------------------------------------------------------------------------- - Fonctions permettant de rechercher une distance extremale entre 2 courbes +Fonctions permettant de rechercher une distance extremale entre 2 courbes C1 et C2 (en partant de points approches C1(u0) et C2(v0)). - Cette classe herite de math_FunctionSetWithDerivatives et est utilisee par +Cette classe herite de math_FunctionSetWithDerivatives et est utilisee par l'algorithme math_FunctionSetRoot. - Si on note Du et Dv, les derivees en u et v, les 2 fonctions a annuler sont: - { F1(u,v) = (C2(v)-C1(u)).Du(u)/||Du|| } - { F2(u,v) = (C2(v)-C1(u)).Dv(v)||Dv|| } - Si on note Duu et Dvv, les derivees secondes de C1 et C2, les derivees de F1 +Si on note Du et Dv, les derivees en u et v, les 2 fonctions a annuler sont: +{ F1(u,v) = (C2(v)-C1(u)).Du(u)/||Du|| } +{ F2(u,v) = (C2(v)-C1(u)).Dv(v)||Dv|| } +Si on note Duu et Dvv, les derivees secondes de C1 et C2, les derivees de F1 et F2 sont egales a: - { Duf1(u,v) = -||Du|| + C1C2.Duu/||Du||- F1(u,v)*Duu*Du/||Du||**2 - { Dvf1(u,v) = Dv.Du/||Du|| - { Duf2(u,v) = -Du.Dv/||Dv|| - { Dvf2(u,v) = ||Dv|| + C2C1.Dvv/||Dv||- F2(u,v)*Dv*Dvv/||Dv||**2 +{ Duf1(u,v) = -||Du|| + C1C2.Duu/||Du||- F1(u,v)*Duu*Du/||Du||**2 +{ Dvf1(u,v) = Dv.Du/||Du|| +{ Duf2(u,v) = -Du.Dv/||Dv|| +{ Dvf2(u,v) = ||Dv|| + C2C1.Dvv/||Dv||- F2(u,v)*Dv*Dvv/||Dv||**2 ----------------------------------------------------------------------------*/ @@ -52,56 +52,53 @@ static const Standard_Integer MaxOrder = 3; //============================================================================= Standard_Real Extrema_FuncExtCC::SearchOfTolerance(const Standard_Address C) - { +{ const Standard_Integer NPoint = 10; Standard_Real aStartParam, anEndParam; - + if(C==myC1) - { + { aStartParam = myUinfium; anEndParam = myUsupremum; - } + } else if(C==myC2) - { + { aStartParam = myVinfium; anEndParam = myVsupremum; - } + } else - { -#ifdef DEB - cout << "+++ Function Extrema_FuncExtCC::SearchOfTolerance(...)" << endl; - cout << "Warning: No curve for tolerance computing!---"< anEndParam) u = anEndParam; - + Pnt Ptemp; //empty point (is not used below) Vec VDer; // 1st derivative vector Tool1::D1(*((Curve1*)C), u, Ptemp, VDer); Standard_Real vm = VDer.Magnitude(); if(vm > aMax) aMax = vm; - } - while(++aNum < NPoint+1); - - return Max(aMax*TolFactor,MinTol); } + while(++aNum < NPoint+1); + + return Max(aMax*TolFactor,MinTol); +} //============================================================================= Extrema_FuncExtCC::Extrema_FuncExtCC(const Standard_Real thetol) : myC1 (0), myC2 (0), myTol (thetol) - { +{ math_Vector V1(1,2), V2(1,2); V1(1) = 0.0; V2(1) = 0.0; @@ -112,60 +109,60 @@ Extrema_FuncExtCC::Extrema_FuncExtCC(const Standard_Real thetol) : myC1 (0), myC myTolC1=MinTol; myMaxDerivOrderC2 = 0; myTolC2=MinTol; - } +} //============================================================================= Extrema_FuncExtCC::Extrema_FuncExtCC (const Curve1& C1, - const Curve2& C2, - const Standard_Real thetol) : - myC1 ((Standard_Address)&C1), myC2 ((Standard_Address)&C2), - myTol (thetol) - { + const Curve2& C2, + const Standard_Real thetol) : +myC1 ((Standard_Address)&C1), myC2 ((Standard_Address)&C2), +myTol (thetol) +{ math_Vector V1(1,2), V2(1,2); V1(1) = Tool1::FirstParameter(*((Curve1*)myC1)); V2(1) = Tool1::LastParameter(*((Curve1*)myC1)); V1(2) = Tool2::FirstParameter(*((Curve2*)myC2)); V2(2) = Tool2::LastParameter(*((Curve2*)myC2)); SubIntervalInitialize(V1, V2); - + switch(Tool1::GetType(*((Curve1*)myC1))) - { - case GeomAbs_BezierCurve: - case GeomAbs_BSplineCurve: - case GeomAbs_OtherCurve: - myMaxDerivOrderC1 = MaxOrder; - myTolC1 = SearchOfTolerance((Standard_Address)&C1); - break; - default: - myMaxDerivOrderC1 = 0; - myTolC1=MinTol; - break; - } - - switch(Tool2::GetType(*((Curve2*)myC2))) - { - case GeomAbs_BezierCurve: - case GeomAbs_BSplineCurve: - case GeomAbs_OtherCurve: - myMaxDerivOrderC2 = MaxOrder; - myTolC2 = SearchOfTolerance((Standard_Address)&C2); - break; - default: - myMaxDerivOrderC2 = 0; - myTolC2=MinTol; - break; - } + { + case GeomAbs_BezierCurve: + case GeomAbs_BSplineCurve: + case GeomAbs_OtherCurve: + myMaxDerivOrderC1 = MaxOrder; + myTolC1 = SearchOfTolerance((Standard_Address)&C1); + break; + default: + myMaxDerivOrderC1 = 0; + myTolC1=MinTol; + break; } + switch(Tool2::GetType(*((Curve2*)myC2))) + { + case GeomAbs_BezierCurve: + case GeomAbs_BSplineCurve: + case GeomAbs_OtherCurve: + myMaxDerivOrderC2 = MaxOrder; + myTolC2 = SearchOfTolerance((Standard_Address)&C2); + break; + default: + myMaxDerivOrderC2 = 0; + myTolC2=MinTol; + break; + } +} + //============================================================================= void Extrema_FuncExtCC::SetCurve (const Standard_Integer theRank, const Curve1& C) - { +{ Standard_OutOfRange_Raise_if (theRank < 1 || theRank > 2, "Extrema_FuncExtCC::SetCurve()") - - if (theRank == 1) + + if (theRank == 1) { - myC1 = (Standard_Address)&C; - switch(/*Tool1::GetType(*((Curve1*)myC1))*/ C.GetType()) + myC1 = (Standard_Address)&C; + switch(/*Tool1::GetType(*((Curve1*)myC1))*/ C.GetType()) { case GeomAbs_BezierCurve: case GeomAbs_BSplineCurve: @@ -179,10 +176,10 @@ void Extrema_FuncExtCC::SetCurve (const Standard_Integer theRank, const Curve1& break; } } - else if (theRank == 2) + else if (theRank == 2) { - myC2 = (Standard_Address)&C; - switch(/*Tool2::GetType(*((Curve2*)myC2))*/C.GetType()) + myC2 = (Standard_Address)&C; + switch(/*Tool2::GetType(*((Curve2*)myC2))*/C.GetType()) { case GeomAbs_BezierCurve: case GeomAbs_BSplineCurve: @@ -196,11 +193,11 @@ void Extrema_FuncExtCC::SetCurve (const Standard_Integer theRank, const Curve1& break; } } - } +} //============================================================================= Standard_Boolean Extrema_FuncExtCC::Value (const math_Vector& UV, math_Vector& F) - { +{ myU = UV(1); myV = UV(2); Tool1::D1(*((Curve1*)myC1), myU,myP1,myDu); @@ -212,264 +209,254 @@ Standard_Boolean Extrema_FuncExtCC::Value (const math_Vector& UV, math_Vector& F if(myMaxDerivOrderC1 != 0) - { + { if (Ndu <= myTolC1) - { - //Derivative is approximated by Taylor-series + { + //Derivative is approximated by Taylor-series const Standard_Real DivisionFactor = 1.e-3; Standard_Real du; if((myUsupremum >= RealLast()) || (myUinfium <= RealFirst())) du = 0.0; else du = myUsupremum-myUinfium; - + const Standard_Real aDelta = Max(du*DivisionFactor,MinStep); - + Standard_Integer n = 1; //Derivative order Vec V; Standard_Boolean IsDeriveFound; - + do - { + { V = Tool1::DN(*((Curve1*)myC1),myU,++n); Ndu = V.Magnitude(); IsDeriveFound = (Ndu > myTolC1); - } + } while(!IsDeriveFound && n < myMaxDerivOrderC1); - + if(IsDeriveFound) - { + { Standard_Real u; - + if(myU-myUinfium < aDelta) u = myU+aDelta; else u = myU-aDelta; - + Pnt P1, P2; Tool1::D0(*((Curve1*)myC1),Min(myU, u),P1); Tool1::D0(*((Curve1*)myC1),Max(myU, u),P2); - + Vec V1(P1,P2); Standard_Real aDirFactor = V.Dot(V1); - + if(aDirFactor < 0.0) myDu = -V; else myDu = V; - }//if(IsDeriveFound) + }//if(IsDeriveFound) else - { - //Derivative is approximated by three points + { + //Derivative is approximated by three points Pnt Ptemp; //(0,0,0)-coordinate Pnt P1, P2, P3; Standard_Boolean IsParameterGrown; - + if(myU-myUinfium < 2*aDelta) - { + { Tool1::D0(*((Curve1*)myC1),myU,P1); Tool1::D0(*((Curve1*)myC1),myU+aDelta,P2); Tool1::D0(*((Curve1*)myC1),myU+2*aDelta,P3); IsParameterGrown = Standard_True; - } + } else - { + { Tool1::D0(*((Curve1*)myC1),myU-2*aDelta,P1); Tool1::D0(*((Curve1*)myC1),myU-aDelta,P2); Tool1::D0(*((Curve1*)myC1),myU,P3); IsParameterGrown = Standard_False; - } - + } + Vec V1(Ptemp,P1), V2(Ptemp,P2), V3(Ptemp,P3); - + if(IsParameterGrown) myDu=-3*V1+4*V2-V3; else myDu=V1-4*V2+3*V3; - }//else of if(IsDeriveFound) + }//else of if(IsDeriveFound) Ndu = myDu.Magnitude(); - }//if (Ndu <= myTolC1) condition - }//if(myMaxDerivOrder != 0) + }//if (Ndu <= myTolC1) condition + }//if(myMaxDerivOrder != 0) if (Ndu <= MinTol) - { -#ifdef DEB - cout << "+++Function Extrema_FuncExtCC::Value(...)." << endl; - cout << "Warning: 1st derivative of C1 is equal to zero!---"<= RealLast()) || (myVinfium <= RealFirst())) dv = 0.0; else dv = myVsupremum-myVinfium; - + const Standard_Real aDelta = Max(dv*DivisionFactor,MinStep); -//Derivative is approximated by Taylor-series - + //Derivative is approximated by Taylor-series + Standard_Integer n = 1; //Derivative order Vec V; Standard_Boolean IsDeriveFound; - + do - { + { V = Tool2::DN(*((Curve2*)myC2),myV,++n); Ndv = V.Magnitude(); IsDeriveFound = (Ndv > myTolC2); - } + } while(!IsDeriveFound && n < myMaxDerivOrderC2); - + if(IsDeriveFound) - { + { Standard_Real v; - + if(myV-myVinfium < aDelta) v = myV+aDelta; else v = myV-aDelta; - + Pnt P1, P2; Tool2::D0(*((Curve2*)myC2),Min(myV, v),P1); Tool2::D0(*((Curve2*)myC2),Max(myV, v),P2); - + Vec V1(P1,P2); Standard_Real aDirFactor = V.Dot(V1); - + if(aDirFactor < 0.0) myDv = -V; else myDv = V; - }//if(IsDeriveFound) + }//if(IsDeriveFound) else - { - //Derivative is approximated by three points + { + //Derivative is approximated by three points Pnt Ptemp; //(0,0,0)-coordinate Pnt P1, P2, P3; Standard_Boolean IsParameterGrown; - + if(myV-myVinfium < 2*aDelta) - { + { Tool2::D0(*((Curve2*)myC2),myV,P1); Tool2::D0(*((Curve2*)myC2),myV+aDelta,P2); Tool2::D0(*((Curve2*)myC2),myV+2*aDelta,P3); IsParameterGrown = Standard_True; - } + } else - { + { Tool2::D0(*((Curve2*)myC2),myV-2*aDelta,P1); Tool2::D0(*((Curve2*)myC2),myV-aDelta,P2); Tool2::D0(*((Curve2*)myC2),myV,P3); IsParameterGrown = Standard_False; - } - + } + Vec V1(Ptemp,P1), V2(Ptemp,P2), V3(Ptemp,P3); - + if(IsParameterGrown) myDv=-3*V1+4*V2-V3; else myDv=V1-4*V2+3*V3; - }//else of if(IsDeriveFound) - - Ndv = myDv.Magnitude(); - }//if (Ndv <= myTolC2) - }//if(myMaxDerivOrder != 0) + }//else of if(IsDeriveFound) + + Ndv = myDv.Magnitude(); + }//if (Ndv <= myTolC2) + }//if(myMaxDerivOrder != 0) if (Ndv <= MinTol) - { -#ifdef DEB - cout << "+++Function Extrema_FuncExtCC::Value(...)." << endl; - cout << "1st derivative of C2 is equal to zero!---"<= RealLast()) || (myUinfium <= RealFirst())) du = 0.0; else du = myUsupremum-myUinfium; - + const Standard_Real aDeltaU = Max(du*DivisionFactor,MinStep); - + Standard_Real dv; if((myVsupremum >= RealLast()) || (myVinfium <= RealFirst())) dv = 0.0; else dv = myVsupremum-myVinfium; - + const Standard_Real aDeltaV = Max(dv*DivisionFactor,MinStep); Vec P1P2 (myP1,myP2); - + if((myMaxDerivOrderC1 != 0) && (Du.Magnitude() <= myTolC1)) - { -//Derivative is approximated by three points + { + //Derivative is approximated by three points math_Vector FF1(1,2), FF2(1,2), FF3(1,2); Standard_Real F1, F2, F3; -/////////////////////////// Search of DF1_u derivative (begin) /////////////////// + /////////////////////////// Search of DF1_u derivative (begin) /////////////////// if(myU-myUinfium < 2*aDeltaU) - { + { F1=F(1); math_Vector UV2(1,2), UV3(1,2); UV2(1)=myU+aDeltaU; @@ -477,23 +464,19 @@ Standard_Boolean Extrema_FuncExtCC::Values (const math_Vector& UV, UV3(1)=myU+2*aDeltaU; UV3(2)=myV; if(!((Value(UV2,FF2)) && (Value(UV3,FF3)))) - { -#ifdef DEB - cout << "+++ Function Extrema_FuncExtCC::Values(...)" << endl; - cout << "There are many points close to singularity points " - "and which have zero-derivative." << endl; - cout << "Try to decrease aDelta variable's value. ---" << endl; -#endif + { + //There are many points close to singularity points and which have zero-derivative. + //Try to decrease aDelta variable's value. return Standard_False; - } - + } + F2 = FF2(1); F3 = FF3(1); - + Df(1,1) = (-3*F1+4*F2-F3)/(2.0*aDeltaU); - }//if(myU-myUinfium < 2*aDeltaU) + }//if(myU-myUinfium < 2*aDeltaU) else - { + { F3 = F(1); math_Vector UV2(1,2), UV1(1,2); UV2(1)=myU-aDeltaU; @@ -502,30 +485,26 @@ Standard_Boolean Extrema_FuncExtCC::Values (const math_Vector& UV, UV1(2)=myV; if(!((Value(UV2,FF2)) && (Value(UV1,FF1)))) - { -#ifdef DEB - cout << "+++ Function Extrema_FuncExtCC::Values(...)" << endl; - cout << "There are many points close to singularity points " - "and which have zero-derivative." << endl; - cout << "Try to decrease aDelta variable's value. ---" << endl; -#endif + { + //There are many points close to singularity points and which have zero-derivative. + //Try to decrease aDelta variable's value. return Standard_False; - } - + } + F1 = FF1(1); F2 = FF2(1); Df(1,1) = (F1-4*F2+3*F3)/(2.0*aDeltaU); - }//else of if(myU-myUinfium < 2*aDeltaU) condition -/////////////////////////// Search of DF1_u derivative (end) /////////////////// - - //Return to previous values - myU = myU_old; - myV = myV_old; + }//else of if(myU-myUinfium < 2*aDeltaU) condition + /////////////////////////// Search of DF1_u derivative (end) /////////////////// -/////////////////////////// Search of DF1_v derivative (begin) /////////////////// + //Return to previous values + myU = myU_old; + myV = myV_old; + + /////////////////////////// Search of DF1_v derivative (begin) /////////////////// if(myV-myVinfium < 2*aDeltaV) - { + { F1=F(1); math_Vector UV2(1,2), UV3(1,2); UV2(1)=myU; @@ -534,22 +513,18 @@ Standard_Boolean Extrema_FuncExtCC::Values (const math_Vector& UV, UV3(2)=myV+2*aDeltaV; if(!((Value(UV2,FF2)) && (Value(UV3,FF3)))) - { -#ifdef DEB - cout << "+++ Function Extrema_FuncExtCC::Values(...)" << endl; - cout << "There are many points close to singularity points " - "and which have zero-derivative." << endl; - cout << "Try to decrease aDelta variable's value. ---" << endl; -#endif + { + //There are many points close to singularity points and which have zero-derivative. + //Try to decrease aDelta variable's value. return Standard_False; - } + } F2 = FF2(1); F3 = FF3(1); - + Df(1,2) = (-3*F1+4*F2-F3)/(2.0*aDeltaV); - }//if(myV-myVinfium < 2*aDeltaV) + }//if(myV-myVinfium < 2*aDeltaV) else - { + { F3 = F(1); math_Vector UV2(1,2), UV1(1,2); UV2(1)=myU; @@ -557,46 +532,42 @@ Standard_Boolean Extrema_FuncExtCC::Values (const math_Vector& UV, UV1(1)=myU; UV1(2)=myV-2*aDeltaV; if(!((Value(UV2,FF2)) && (Value(UV1,FF1)))) - { -#ifdef DEB - cout << "+++ Function Extrema_FuncExtCC::Values(...)" << endl; - cout << "There are many points close to singularity points " - "and which have zero-derivative." << endl; - cout << "Try to decrease aDelta variable's value. ---" << endl; -#endif + { + //There are many points close to singularity points and which have zero-derivative. + //Try to decrease aDelta variable's value. return Standard_False; - } - + } + F1 = FF1(1); F2 = FF2(1); Df(1,2) = (F1-4*F2+3*F3)/(2.0*aDeltaV); - }//else of if(myV-myVinfium < 2*aDeltaV) -/////////////////////////// Search of DF1_v derivative (end) /////////////////// - + }//else of if(myV-myVinfium < 2*aDeltaV) + /////////////////////////// Search of DF1_v derivative (end) /////////////////// + //Return to previous values myU = myU_old; myV = myV_old; myP1 = myP1_old, myP2 = myP2_old; myDu = myDu_old, myDv = myDv_old; - }//if((myMaxDerivOrderC1 != 0) && (Du.Magnitude() <= myTolC1)) + }//if((myMaxDerivOrderC1 != 0) && (Du.Magnitude() <= myTolC1)) else - { + { const Standard_Real Ndu = myDu.Magnitude(); Df(1,1) = - Ndu + (P1P2.Dot(Duu)/Ndu) - F(1)*(myDu.Dot(Duu)/(Ndu*Ndu)); Df(1,2) = myDv.Dot(myDu)/Ndu; - }//else of if((myMaxDerivOrderC1 != 0) && (Du.Magnitude() <= myTolC1)) - + }//else of if((myMaxDerivOrderC1 != 0) && (Du.Magnitude() <= myTolC1)) + if((myMaxDerivOrderC2 != 0) && (Dv.Magnitude() <= myTolC2)) - { -//Derivative is approximated by three points + { + //Derivative is approximated by three points math_Vector FF1(1,2), FF2(1,2), FF3(1,2); Standard_Real F1, F2, F3; -/////////////////////////// Search of DF2_v derivative (begin) /////////////////// + /////////////////////////// Search of DF2_v derivative (begin) /////////////////// if(myV-myVinfium < 2*aDeltaV) - { + { F1=F(2); math_Vector UV2(1,2), UV3(1,2); UV2(1)=myU; @@ -605,24 +576,20 @@ Standard_Boolean Extrema_FuncExtCC::Values (const math_Vector& UV, UV3(2)=myV+2*aDeltaV; if(!((Value(UV2,FF2)) && (Value(UV3,FF3)))) - { -#ifdef DEB - cout << "+++ Function Extrema_FuncExtCC::Values(...)" << endl; - cout << "There are many points close to singularity points " - "and which have zero-derivative." << endl; - cout << "Try to decrease aDelta variable's value. ---" << endl; -#endif + { + //There are many points close to singularity points and which have zero-derivative. + //Try to decrease aDelta variable's value. return Standard_False; - } - + } + F2 = FF2(2); F3 = FF3(2); - + Df(2,2) = (-3*F1+4*F2-F3)/(2.0*aDeltaV); - - }//if(myV-myVinfium < 2*aDeltaV) + + }//if(myV-myVinfium < 2*aDeltaV) else - { + { F3 = F(2); math_Vector UV2(1,2), UV1(1,2); UV2(1)=myU; @@ -631,30 +598,26 @@ Standard_Boolean Extrema_FuncExtCC::Values (const math_Vector& UV, UV1(2)=myV-2*aDeltaV; if(!((Value(UV2,FF2)) && (Value(UV1,FF1)))) - { -#ifdef DEB - cout << "+++ Function Extrema_FuncExtCC::Values(...)" << endl; - cout << "There are many points close to singularity points " - "and which have zero-derivative." << endl; - cout << "Try to decrease aDelta variable's value. ---" << endl; -#endif + { + //There are many points close to singularity points and which have zero-derivative. + //Try to decrease aDelta variable's value. return Standard_False; - } - + } + F1 = FF1(2); F2 = FF2(2); Df(2,2) = (F1-4*F2+3*F3)/(2.0*aDeltaV); - }//else of if(myV-myVinfium < 2*aDeltaV) -/////////////////////////// Search of DF2_v derivative (end) /////////////////// + }//else of if(myV-myVinfium < 2*aDeltaV) + /////////////////////////// Search of DF2_v derivative (end) /////////////////// - //Return to previous values - myU = myU_old; - myV = myV_old; + //Return to previous values + myU = myU_old; + myV = myV_old; -/////////////////////////// Search of DF2_u derivative (begin) /////////////////// + /////////////////////////// Search of DF2_u derivative (begin) /////////////////// if(myU-myUinfium < 2*aDeltaU) - { + { F1=F(2); math_Vector UV2(1,2), UV3(1,2); UV2(1)=myU+aDeltaU; @@ -662,48 +625,41 @@ Standard_Boolean Extrema_FuncExtCC::Values (const math_Vector& UV, UV3(1)=myU+2*aDeltaU; UV3(2)=myV; if(!((Value(UV2,FF2)) && (Value(UV3,FF3)))) - { -#ifdef DEB - cout << "+++ Function Extrema_FuncExtCC::Values(...)" << endl; - cout << "There are many points close to singularity points " - "and which have zero-derivative." << endl; - cout << "Try to decrease aDelta variable's value. ---" << endl; -#endif + { + //There are many points close to singularity points and which have zero-derivative. + //Try to decrease aDelta variable's value. return Standard_False; - } - + } + F2 = FF2(2); F3 = FF3(2); - + Df(2,1) = (-3*F1+4*F2-F3)/(2.0*aDeltaU); - }//if(myU-myUinfium < 2*aDelta) + }//if(myU-myUinfium < 2*aDelta) else - { + { F3 = F(2); math_Vector UV2(1,2), UV1(1,2); UV2(1)=myU-aDeltaU; UV2(2)=myV; UV1(1)=myU-2*aDeltaU; UV1(2)=myV; - + if(!((Value(UV2,FF2)) && (Value(UV1,FF1)))) - { -#ifdef DEB - cout << "+++ Function Extrema_FuncExtCC::Values(...)" << endl; - cout << "There are many points close to singularity points " - "and which have zero-derivative." << endl; - cout << "Try to decrease aDelta variable's value. ---" << endl; -#endif + { + //There are many points close to singularity points + //and which have zero-derivative. + //Try to decrease aDelta variable's value. return Standard_False; - } - + } + F1 = FF1(2); F2 = FF2(2); Df(2,1) = (F1-4*F2+3*F3)/(2.0*aDeltaU); - }//else of if(myU-myUinfium < 2*aDeltaU) -/////////////////////////// Search of DF2_u derivative (end) /////////////////// - + }//else of if(myU-myUinfium < 2*aDeltaU) + /////////////////////////// Search of DF2_u derivative (end) /////////////////// + //Return to previous values myU = myU_old; myV = myV_old; @@ -711,17 +667,17 @@ Standard_Boolean Extrema_FuncExtCC::Values (const math_Vector& UV, myP2 = myP2_old; myDu = myDu_old; myDv = myDv_old; - }//if((myMaxDerivOrderC2 != 0) && (Dv.Magnitude() <= myTolC2)) + }//if((myMaxDerivOrderC2 != 0) && (Dv.Magnitude() <= myTolC2)) else - { + { Standard_Real Ndv = myDv.Magnitude(); Df(2,2) = Ndv + (P1P2.Dot(Dvv)/Ndv) - F(2)*(myDv.Dot(Dvv)/(Ndv*Ndv)); Df(2,1) = -myDu.Dot(myDv)/Ndv; - }//else of if((myMaxDerivOrderC2 != 0) && (Dv.Magnitude() <= myTolC2)) - + }//else of if((myMaxDerivOrderC2 != 0) && (Dv.Magnitude() <= myTolC2)) + return Standard_True; - }//end of function +}//end of function //============================================================================= Standard_Integer Extrema_FuncExtCC::GetStateNumber () @@ -748,8 +704,8 @@ Standard_Integer Extrema_FuncExtCC::GetStateNumber () //============================================================================= void Extrema_FuncExtCC::Points (const Standard_Integer N, - POnC& P1, - POnC& P2) const + POnC& P1, + POnC& P2) const { P1 = myPoints.Value(2*N-1); P2 = myPoints.Value(2*N); @@ -758,10 +714,10 @@ void Extrema_FuncExtCC::Points (const Standard_Integer N, void Extrema_FuncExtCC::SubIntervalInitialize(const math_Vector& theInfBound, const math_Vector& theSupBound) - { +{ myUinfium = theInfBound(1); myUsupremum = theSupBound(1); myVinfium = theInfBound(2); myVsupremum = theSupBound(2); - } -//============================================================================= \ No newline at end of file +} +//============================================================================= diff --git a/src/Extrema/Extrema_FuncExtPC.gxx b/src/Extrema/Extrema_FuncExtPC.gxx index b10ba260ee..8700bd3486 100755 --- a/src/Extrema/Extrema_FuncExtPC.gxx +++ b/src/Extrema/Extrema_FuncExtPC.gxx @@ -27,47 +27,47 @@ static const Standard_Integer MaxOrder = 3; /*----------------------------------------------------------------------------- - Fonction permettant de rechercher une distance extremale entre un point P et +Fonction permettant de rechercher une distance extremale entre un point P et une courbe C (en partant d'un point approche C(u0)). - Cette classe herite de math_FunctionWithDerivative et est utilisee par +Cette classe herite de math_FunctionWithDerivative et est utilisee par les algorithmes math_FunctionRoot et math_FunctionRoots. - Si on note D1c et D2c les derivees premiere et seconde: - { F(u) = (C(u)-P).D1c(u)/ ||Du||} - { DF(u) = ||Du|| + (C(u)-P).D2c(u)/||Du|| - F(u)*Duu*Du/||Du||**2 +Si on note D1c et D2c les derivees premiere et seconde: +{ F(u) = (C(u)-P).D1c(u)/ ||Du||} +{ DF(u) = ||Du|| + (C(u)-P).D2c(u)/||Du|| - F(u)*Duu*Du/||Du||**2 - { F(u) = (C(u)-P).D1c(u) } - { DF(u) = D1c(u).D1c(u) + (C(u)-P).D2c(u) - = ||D1c(u)|| ** 2 + (C(u)-P).D2c(u) } +{ F(u) = (C(u)-P).D1c(u) } +{ DF(u) = D1c(u).D1c(u) + (C(u)-P).D2c(u) += ||D1c(u)|| ** 2 + (C(u)-P).D2c(u) } ----------------------------------------------------------------------------*/ Standard_Real Extrema_FuncExtPC::SearchOfTolerance() - { +{ const Standard_Integer NPoint = 10; const Standard_Real aStep = (myUsupremum - myUinfium)/(Standard_Real)NPoint; - + Standard_Integer aNum = 0; Standard_Real aMax = -Precision::Infinite(); //Maximum value of 1st derivative - //(it is computed with using NPoint point) - + //(it is computed with using NPoint point) + do - { + { Standard_Real u = myUinfium + aNum*aStep; //parameter for every point if(u > myUsupremum) u = myUsupremum; - + Pnt Ptemp; //empty point (is not used below) Vec VDer; // 1st derivative vector Tool::D1(*((Curve*)myC), u, Ptemp, VDer); Standard_Real vm = VDer.Magnitude(); if(vm > aMax) aMax = vm; - } - while(++aNum < NPoint+1); - - return Max(aMax*TolFactor,MinTol); - } + while(++aNum < NPoint+1); + + return Max(aMax*TolFactor,MinTol); + +} //============================================================================= @@ -78,7 +78,7 @@ myD1f(0.) myPinit = Standard_False; myCinit = Standard_False; myD1Init = Standard_False; - + SubIntervalInitialize(0.0,0.0); myMaxDerivOrder = 0; myTol=MinTol; @@ -87,58 +87,58 @@ myD1f(0.) //============================================================================= Extrema_FuncExtPC::Extrema_FuncExtPC (const Pnt& P, - const Curve& C): myU(0.), myD1f(0.) - { + const Curve& C): myU(0.), myD1f(0.) +{ myP = P; myC = (Standard_Address)&C; myPinit = Standard_True; myCinit = Standard_True; myD1Init = Standard_False; - + SubIntervalInitialize(Tool::FirstParameter(*((Curve*)myC)), - Tool::LastParameter(*((Curve*)myC))); - + Tool::LastParameter(*((Curve*)myC))); + switch(Tool::GetType(*((Curve*)myC))) - { - case GeomAbs_BezierCurve: - case GeomAbs_BSplineCurve: - case GeomAbs_OtherCurve: - myMaxDerivOrder = MaxOrder; - myTol = SearchOfTolerance(); - break; - default: - myMaxDerivOrder = 0; - myTol=MinTol; - break; - } + { + case GeomAbs_BezierCurve: + case GeomAbs_BSplineCurve: + case GeomAbs_OtherCurve: + myMaxDerivOrder = MaxOrder; + myTol = SearchOfTolerance(); + break; + default: + myMaxDerivOrder = 0; + myTol=MinTol; + break; } +} //============================================================================= void Extrema_FuncExtPC::Initialize(const Curve& C) - { +{ myC = (Standard_Address)&C; myCinit = Standard_True; myPoint.Clear(); mySqDist.Clear(); myIsMin.Clear(); - + SubIntervalInitialize(Tool::FirstParameter(*((Curve*)myC)), - Tool::LastParameter(*((Curve*)myC))); - + Tool::LastParameter(*((Curve*)myC))); + switch(Tool::GetType(*((Curve*)myC))) - { - case GeomAbs_BezierCurve: - case GeomAbs_BSplineCurve: - case GeomAbs_OtherCurve: - myMaxDerivOrder = MaxOrder; - myTol = SearchOfTolerance(); - break; - default: - myMaxDerivOrder = 0; - myTol=MinTol; - break; - } + { + case GeomAbs_BezierCurve: + case GeomAbs_BSplineCurve: + case GeomAbs_OtherCurve: + myMaxDerivOrder = MaxOrder; + myTol = SearchOfTolerance(); + break; + default: + myMaxDerivOrder = 0; + myTol=MinTol; + break; } +} //============================================================================= @@ -158,102 +158,99 @@ Standard_Boolean Extrema_FuncExtPC::Value (const Standard_Real U, Standard_Real& { if (!myPinit || !myCinit) Standard_TypeMismatch::Raise("No init"); - + myU = U; Vec D1c; Tool::D1(*((Curve*)myC),myU,myPc,D1c); Standard_Real Ndu = D1c.Magnitude(); if(myMaxDerivOrder != 0) - { + { if (Ndu <= myTol) // Cas Singulier (PMN 22/04/1998) - { + { const Standard_Real DivisionFactor = 1.e-3; Standard_Real du; if((myUsupremum >= RealLast()) || (myUinfium <= RealFirst())) du = 0.0; else du = myUsupremum-myUinfium; - + const Standard_Real aDelta = Max(du*DivisionFactor,MinStep); -//Derivative is approximated by Taylor-series - + //Derivative is approximated by Taylor-series + Standard_Integer n = 1; //Derivative order Vec V; Standard_Boolean IsDeriveFound; - + do - { + { V = Tool::DN(*((Curve*)myC),myU,++n); Ndu = V.Magnitude(); IsDeriveFound = (Ndu > myTol); - } + } while(!IsDeriveFound && n < myMaxDerivOrder); - + if(IsDeriveFound) - { + { Standard_Real u; - + if(myU-myUinfium < aDelta) u = myU+aDelta; else u = myU-aDelta; - + Pnt P1, P2; Tool::D0(*((Curve*)myC),Min(myU, u),P1); Tool::D0(*((Curve*)myC),Max(myU, u),P2); - + Vec V1(P1,P2); Standard_Real aDirFactor = V.Dot(V1); - + if(aDirFactor < 0.0) D1c = -V; else D1c = V; - }//if(IsDeriveFound) + }//if(IsDeriveFound) else - { -//Derivative is approximated by three points + { + //Derivative is approximated by three points Pnt Ptemp; //(0,0,0)-coordinate Pnt P1, P2, P3; Standard_Boolean IsParameterGrown; - + if(myU-myUinfium < 2*aDelta) - { + { Tool::D0(*((Curve*)myC),myU,P1); Tool::D0(*((Curve*)myC),myU+aDelta,P2); Tool::D0(*((Curve*)myC),myU+2*aDelta,P3); IsParameterGrown = Standard_True; - } + } else - { + { Tool::D0(*((Curve*)myC),myU-2*aDelta,P1); Tool::D0(*((Curve*)myC),myU-aDelta,P2); Tool::D0(*((Curve*)myC),myU,P3); IsParameterGrown = Standard_False; - } - + } + Vec V1(Ptemp,P1), V2(Ptemp,P2), V3(Ptemp,P3); - + if(IsParameterGrown) D1c=-3*V1+4*V2-V3; else D1c=V1-4*V2+3*V3; - } - Ndu = D1c.Magnitude(); - }//(if (Ndu <= myTol)) condition - }//if(myMaxDerivOrder != 0) + } + Ndu = D1c.Magnitude(); + }//(if (Ndu <= myTol)) condition + }//if(myMaxDerivOrder != 0) if (Ndu <= MinTol) - { -#ifdef DEB - cout << "+++Function Extrema_FuncExtPC::Value(...)." << endl; - cout << "Warning: 1st derivative is equal to zero!---"<= RealLast()) || (myUinfium <= RealFirst())) du = 0.0; else du = myUsupremum-myUinfium; - + const Standard_Real aDelta = Max(du*DivisionFactor,MinStep); - + Standard_Real F1, F2, F3; - + if(myU-myUinfium < 2*aDelta) - { + { F1=F; //const Standard_Real U1 = myU; const Standard_Real U2 = myU + aDelta; const Standard_Real U3 = myU + aDelta * 2.0; - + if(!((Value(U2,F2)) && (Value(U3,F3)))) - { -#ifdef DEB - cout << "+++ Function Extrema_FuncExtPC::Values(...)" << endl; - cout << "There are many points close to singularity points " - "and which have zero-derivative." << endl; - cout << "Try to decrease aDelta variable's value. ---" << endl; -#endif + { + //There are many points close to singularity points and + //which have zero-derivative. Try to decrease aDelta variable's value. + myD1Init = Standard_False; return Standard_False; - } - -//After calling of Value(...) function variable myU will be redeterminated. -//So we must return it previous value. - D1f=(-3*F1+4*F2-F3)/(2.0*aDelta); } + + //After calling of Value(...) function variable myU will be redeterminated. + //So we must return it previous value. + D1f=(-3*F1+4*F2-F3)/(2.0*aDelta); + } else - { + { F3 = F; const Standard_Real U1 = myU - aDelta * 2.0; const Standard_Real U2 = myU - aDelta; //const Standard_Real U3 = myU; if(!((Value(U2,F2)) && (Value(U1,F1)))) - { -#ifdef DEB - cout << "+++ Function Extrema_FuncExtPC::Values(...)" << endl; - cout << "There are many points close to singularity points " - "and which have zero-derivative." << endl; - cout << "Try to decrease aDelta variable's value. ---" << endl; -#endif + { + //There are many points close to singularity points and + //which have zero-derivative. Try to decrease aDelta variable's value. myD1Init = Standard_False; return Standard_False; - } -//After calling of Value(...) function variable myU will be redeterminated. -//So we must return it previous value. - D1f=(F1-4*F2+3*F3)/(2.0*aDelta); } - myU = U; - myPc = myPc_old; - myP = myP_old; + //After calling of Value(...) function variable myU will be redeterminated. + //So we must return it previous value. + D1f=(F1-4*F2+3*F3)/(2.0*aDelta); } + myU = U; + myPc = myPc_old; + myP = myP_old; + } else - { + { Vec PPc (myP,myPc); D1f = Ndu + (PPc.Dot(D2c)/Ndu) - F*(D1c.Dot(D2c))/(Ndu*Ndu); - } + } myD1f = D1f; myD1Init = Standard_True; return Standard_True; - } +} //============================================================================= Standard_Integer Extrema_FuncExtPC::GetStateNumber () @@ -419,7 +408,7 @@ const POnC & Extrema_FuncExtPC::Point (const Standard_Integer N) const //============================================================================= void Extrema_FuncExtPC::SubIntervalInitialize(const Standard_Real theUfirst, const Standard_Real theUlast) - { +{ myUinfium = theUfirst; myUsupremum = theUlast; - } \ No newline at end of file +}