OCC22540 Regression: Exception during building of patch by GeomPlate
[occt.git] / src / Extrema / Extrema_FuncExtPC.gxx
CommitLineData
7fd59977 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
8une courbe C (en partant d'un point approche C(u0)).
9 Cette classe herite de math_FunctionWithDerivative et est utilisee par
10les 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
22Extrema_FuncExtPC::Extrema_FuncExtPC():
23myU(0.),
24myD1f(0.)
25{
26 myPinit = Standard_False;
27 myCinit = Standard_False;
28 myD1Init = Standard_False;
29}
30
31//=============================================================================
32
33Extrema_FuncExtPC::Extrema_FuncExtPC (const Pnt& P,
34 const Curve& C):
35myU(0.),
36myD1f(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
46void 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
57void 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
68Standard_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
93Standard_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
102Standard_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
135Standard_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
156Standard_Integer Extrema_FuncExtPC::NbExt () const { return mySqDist.Length(); }
157//=============================================================================
158
159Standard_Real Extrema_FuncExtPC::SquareDistance (const Standard_Integer N) const
160{
161 if (!myPinit || !myCinit) Standard_TypeMismatch::Raise();
162 return mySqDist.Value(N);
163}
164//=============================================================================
165Standard_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//=============================================================================
171POnC Extrema_FuncExtPC::Point (const Standard_Integer N) const
172{
173 if (!myPinit || !myCinit) Standard_TypeMismatch::Raise();
174 return myPoint.Value(N);
175}
176//=============================================================================
177