X-Git-Url: http://git.dev.opencascade.org/gitweb/?p=occt.git;a=blobdiff_plain;f=src%2FExtrema%2FExtrema_FuncExtPC.gxx;h=8700bd3486cdd9d69c9d111f02eeeb502773e32d;hb=28cec2ba3e2fbf31d0cebcbd2dc429f2f8909904;hpb=3cb19cf162ebbf3f52b0086a01efc17a5dca832e 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); - - } + +} //============================================================================= @@ -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 +}