mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-07-30 13:05:50 +03:00
188 lines
5.0 KiB
Plaintext
Executable File
188 lines
5.0 KiB
Plaintext
Executable File
//Modified by MPS : 21-05-97 PRO 7598
|
|
// Le nombre de solutions rendu est mySqDist.Length() et non
|
|
// mySqDist.Length()/2
|
|
// ajout des valeurs absolues dans le test d'orthogonalite de
|
|
// GetStateNumber()
|
|
|
|
/*-----------------------------------------------------------------------------
|
|
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
|
|
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
|
|
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
|
|
|
|
----------------------------------------------------------------------------*/
|
|
//=============================================================================
|
|
|
|
#define Tol 1.e-20
|
|
#define delta 1.e-9
|
|
|
|
Extrema_FuncExtCC::Extrema_FuncExtCC(const Standard_Real thetol) : myC1 (0), myC2 (0), myTol (thetol)
|
|
{
|
|
}
|
|
|
|
Extrema_FuncExtCC::Extrema_FuncExtCC (const Curve1& C1,
|
|
const Curve2& C2,
|
|
const Standard_Real thetol) :
|
|
myC1 ((Standard_Address)&C1), myC2 ((Standard_Address)&C2),
|
|
myTol (thetol)
|
|
{
|
|
}
|
|
|
|
Standard_Boolean Extrema_FuncExtCC::Value (const math_Vector& UV,
|
|
math_Vector& F)
|
|
{
|
|
|
|
Vec Du, Dv;
|
|
|
|
myU = UV(1);
|
|
myV = UV(2);
|
|
Tool1::D1(*((Curve1*)myC1), myU,myP1,Du);
|
|
Tool2::D1(*((Curve2*)myC2), myV,myP2,Dv);
|
|
Vec P1P2 (myP1,myP2);
|
|
|
|
Standard_Real Ndu = Du.Magnitude();
|
|
if (Ndu <= Tol) {
|
|
Pnt P1, P2;
|
|
P1 = Tool1::Value(*((Curve1*)myC1), myU-delta);
|
|
P2 = Tool1::Value(*((Curve1*)myC1), myU+delta);
|
|
Vec V(P1,P2);
|
|
Du = V;
|
|
Ndu = Du.Magnitude();
|
|
if (Ndu <= Tol) {
|
|
return Standard_False;
|
|
}
|
|
}
|
|
|
|
Standard_Real Ndv = Dv.Magnitude();
|
|
if (Ndv <= Tol) {
|
|
// Traitement des singularite, on approche la Tangente
|
|
// par une corde
|
|
Pnt P1, P2;
|
|
P1 = Tool2::Value(*((Curve2*)myC2), myV-delta);
|
|
P2 = Tool2::Value(*((Curve2*)myC2), myV+delta);
|
|
Vec V(P1,P2);
|
|
Dv = V;
|
|
Ndv = Dv.Magnitude();
|
|
if (Ndv <= Tol) {
|
|
return Standard_False;
|
|
}
|
|
}
|
|
|
|
F(1) = P1P2.Dot(Du)/Ndu;
|
|
F(2) = P1P2.Dot(Dv)/Ndv;
|
|
return Standard_True;
|
|
}
|
|
//=============================================================================
|
|
|
|
Standard_Boolean Extrema_FuncExtCC::Derivatives (const math_Vector& UV,
|
|
math_Matrix& Df)
|
|
{
|
|
math_Vector F(1,2);
|
|
return Values(UV,F,Df);
|
|
}
|
|
//=============================================================================
|
|
|
|
Standard_Boolean Extrema_FuncExtCC::Values (const math_Vector& UV,
|
|
math_Vector& F,
|
|
math_Matrix& Df)
|
|
{
|
|
myU = UV(1);
|
|
myV = UV(2);
|
|
Vec Du, Dv, Duu, Dvv;
|
|
Tool1::D2(*((Curve1*)myC1), myU,myP1,Du,Duu);
|
|
Tool2::D2(*((Curve2*)myC2), myV,myP2,Dv,Dvv);
|
|
|
|
Vec P1P2 (myP1,myP2);
|
|
|
|
Standard_Real Ndu = Du.Magnitude();
|
|
if (Ndu <= Tol) {
|
|
Pnt P1, P2;
|
|
Vec V1;
|
|
Tool1::D1(*((Curve1*)myC1),myU+delta, P2, Duu);
|
|
Tool1::D1(*((Curve1*)myC1),myU-delta, P1, V1);
|
|
Vec V(P1,P2);
|
|
Du = V;
|
|
Duu -= V1;
|
|
Ndu = Du.Magnitude();
|
|
if (Ndu <= Tol) {
|
|
return Standard_False;
|
|
}
|
|
}
|
|
|
|
Standard_Real Ndv = Dv.Magnitude();
|
|
if (Ndv <= Tol) {
|
|
Pnt P1, P2;
|
|
Vec V1;
|
|
Tool2::D1(*((Curve2*)myC2),myV+delta, P2, Dvv);
|
|
Tool2::D1(*((Curve2*)myC2),myV-delta, P1, V1);
|
|
Vec V(P1,P2);
|
|
Dv = V;
|
|
Dvv -= V1;
|
|
Ndv = Dv.Magnitude();
|
|
if (Ndv <= Tol) {
|
|
return Standard_False;
|
|
}
|
|
}
|
|
|
|
F(1) = P1P2.Dot(Du)/Ndu;
|
|
F(2) = P1P2.Dot(Dv)/Ndv;
|
|
|
|
Df(1,1) = - Ndu + (P1P2.Dot(Duu)/Ndu) - F(1)*(Du.Dot(Duu)/(Ndu*Ndu));
|
|
Df(1,2) = Dv.Dot(Du)/Ndu;
|
|
Df(2,1) = -Du.Dot(Dv)/Ndv;
|
|
Df(2,2) = Ndv + (P1P2.Dot(Dvv)/Ndv) - F(2)*(Dv.Dot(Dvv)/(Ndv*Ndv));
|
|
return Standard_True;
|
|
|
|
}
|
|
//=============================================================================
|
|
|
|
Standard_Integer Extrema_FuncExtCC::GetStateNumber ()
|
|
{
|
|
Vec Du, Dv;
|
|
Pnt P1, P2;
|
|
Tool1::D1(*((Curve1*)myC1), myU, P1, Du);
|
|
Tool2::D1(*((Curve2*)myC2), myV, P2, Dv);
|
|
Vec P1P2 (P1, P2);
|
|
Standard_Real mod = Du.Magnitude();
|
|
if(mod > Tol) {
|
|
Du /= mod;
|
|
}
|
|
mod = Dv.Magnitude();
|
|
if(mod > Tol) {
|
|
Dv /= mod;
|
|
}
|
|
|
|
if (Abs(P1P2.Dot(Du)) <= myTol && Abs(P1P2.Dot(Dv)) <= myTol) {
|
|
mySqDist.Append(myP1.SquareDistance(myP2));
|
|
myPoints.Append(POnC(myU, myP1));
|
|
myPoints.Append(POnC(myV, myP2));
|
|
}
|
|
return 0;
|
|
}
|
|
//=============================================================================
|
|
|
|
void Extrema_FuncExtCC::Points (const Standard_Integer N,
|
|
POnC& P1,
|
|
POnC& P2) const
|
|
{
|
|
P1 = myPoints.Value(2*N-1);
|
|
P2 = myPoints.Value(2*N);
|
|
}
|
|
//=============================================================================
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|