Integration of OCCT 6.5.0 from SVN
[occt.git] / src / Extrema / Extrema_FuncExtPC.gxx
1 #include <Standard_TypeMismatch.hxx>
2   
3 #define delta 1.e-9
4 #define Tol   1.e-20
5
6 /*-----------------------------------------------------------------------------
7  Fonction permettant de rechercher une distance extremale entre un point P et
8 une courbe C (en partant d'un point approche C(u0)).
9  Cette classe herite de math_FunctionWithDerivative et est utilisee par
10 les algorithmes math_FunctionRoot et math_FunctionRoots.
11  Si on note D1c et D2c les derivees premiere et seconde:
12   { F(u) = (C(u)-P).D1c(u)/ ||Du||}
13   { DF(u) = ||Du|| + (C(u)-P).D2c(u)/||Du|| - F(u)*Duu*Du/||Du||**2
14
15
16   { F(u) = (C(u)-P).D1c(u) }
17   { DF(u) = D1c(u).D1c(u) + (C(u)-P).D2c(u)
18           = ||D1c(u)|| ** 2 + (C(u)-P).D2c(u) }
19 ----------------------------------------------------------------------------*/
20
21
22 Extrema_FuncExtPC::Extrema_FuncExtPC():
23 myU(0.),
24 myD1f(0.) 
25
26   myPinit = Standard_False;
27   myCinit = Standard_False;
28   myD1Init = Standard_False;
29 }
30
31 //=============================================================================
32
33 Extrema_FuncExtPC::Extrema_FuncExtPC (const Pnt& P, 
34                                       const Curve& C):
35 myU(0.),
36 myD1f(0.) 
37 {
38   myP = P;
39   myC = (Standard_Address)&C;
40   myPinit = Standard_True;
41   myCinit = Standard_True;
42   myD1Init = Standard_False;
43 }
44 //=============================================================================
45
46 void Extrema_FuncExtPC::Initialize(const Curve& C)
47 {
48   myC = (Standard_Address)&C;
49   myCinit = Standard_True;
50   myPoint.Clear();
51   mySqDist.Clear();
52   myIsMin.Clear();
53 }
54
55 //=============================================================================
56
57 void Extrema_FuncExtPC::SetPoint(const Pnt& P)
58 {
59   myP = P;
60   myPinit = Standard_True;
61   myPoint.Clear();
62   mySqDist.Clear();
63   myIsMin.Clear();
64 }
65
66 //=============================================================================
67
68 Standard_Boolean Extrema_FuncExtPC::Value (const Standard_Real U, Standard_Real& F)
69 {
70   if (!myPinit || !myCinit) Standard_TypeMismatch::Raise();
71   myU = U;
72   Vec D1c;
73   Tool::D1(*((Curve*)myC),myU,myPc,D1c);
74   Standard_Real Ndu = D1c.Magnitude();
75   if (Ndu <= Tol) { // Cas Singulier (PMN 22/04/1998)
76     Pnt P1, P2;
77     P2 = Tool::Value(*((Curve*)myC),myU+delta);
78     P1 = Tool::Value(*((Curve*)myC),myU-delta);
79     Vec V(P1,P2);
80     D1c = V;
81     Ndu = D1c.Magnitude();
82     if (Ndu <= Tol) {
83       return Standard_False;
84     }
85   }
86   Vec PPc (myP,myPc);
87   F = PPc.Dot(D1c)/Ndu;
88   return Standard_True;
89 }
90
91 //=============================================================================
92
93 Standard_Boolean Extrema_FuncExtPC::Derivative (const Standard_Real U, Standard_Real& D1f)
94 {
95   if (!myPinit || !myCinit) Standard_TypeMismatch::Raise();
96   Standard_Real F;
97   return Values(U,F,D1f);  /* on fait appel a Values pour simplifier la
98                               sauvegarde de l'etat. */
99 }
100 //=============================================================================
101
102 Standard_Boolean Extrema_FuncExtPC::Values (const Standard_Real U, Standard_Real& F, Standard_Real& D1f)
103 {
104   if (!myPinit || !myCinit) Standard_TypeMismatch::Raise();
105   myU = U;
106   Vec D1c,D2c;
107   Tool::D2(*((Curve*)myC),myU,myPc,D1c,D2c);
108
109   Standard_Real Ndu = D1c.Magnitude();
110   if (Ndu <= Tol) {// Cas Singulier (PMN 22/04/1998)
111     Pnt P1, P2;
112     Vec V1;
113     Tool::D1(*((Curve*)myC),myU+delta, P2, V1);
114     Tool::D1(*((Curve*)myC),myU-delta, P1, D2c);
115     Vec V(P1,P2);
116     D1c = V;
117     D2c -= V1;
118     Ndu = D1c.Magnitude();
119     if (Ndu <= Tol) {
120       myD1Init = Standard_False;
121       return Standard_False;
122     }
123   }
124   
125   Vec PPc (myP,myPc);
126   F = PPc.Dot(D1c)/Ndu;
127   D1f = Ndu + (PPc.Dot(D2c)/Ndu) - F*(D1c.Dot(D2c))/(Ndu*Ndu);
128
129   myD1f = D1f;
130   myD1Init = Standard_True;
131   return Standard_True;
132 }
133 //=============================================================================
134
135 Standard_Integer Extrema_FuncExtPC::GetStateNumber ()
136 {
137   if (!myPinit || !myCinit) Standard_TypeMismatch::Raise();
138   mySqDist.Append(myPc.SquareDistance(myP));
139   Standard_Integer IntVal;
140   if (!myD1Init) {
141     myD1Init = Standard_True;
142     Standard_Real FF, DD;
143     Values(myU, FF, DD);
144   }
145   if (!myD1Init) IntVal = 0;
146   else {
147     if (myD1f > 0.) { IntVal = 1; }
148     else { IntVal = 0; }
149   }
150   myIsMin.Append(IntVal);
151   myPoint.Append(POnC(myU,myPc));
152   return 0;
153 }
154 //=============================================================================
155
156 Standard_Integer Extrema_FuncExtPC::NbExt () const { return mySqDist.Length(); }
157 //=============================================================================
158
159 Standard_Real Extrema_FuncExtPC::SquareDistance (const Standard_Integer N) const
160 {
161   if (!myPinit || !myCinit) Standard_TypeMismatch::Raise();
162   return mySqDist.Value(N);
163 }
164 //=============================================================================
165 Standard_Boolean Extrema_FuncExtPC::IsMin (const Standard_Integer N) const
166 {
167   if (!myPinit || !myCinit) Standard_TypeMismatch::Raise();
168   return (myIsMin.Value(N) == 1);
169 }
170 //=============================================================================
171 POnC Extrema_FuncExtPC::Point (const Standard_Integer N) const
172 {
173   if (!myPinit || !myCinit) Standard_TypeMismatch::Raise();
174   return myPoint.Value(N);
175 }
176 //=============================================================================
177