Commit | Line | Data |
---|---|---|
b311480e | 1 | // Copyright (c) 1995-1999 Matra Datavision |
2 | // Copyright (c) 1999-2012 OPEN CASCADE SAS | |
3 | // | |
4 | // The content of this file is subject to the Open CASCADE Technology Public | |
5 | // License Version 6.5 (the "License"). You may not use the content of this file | |
6 | // except in compliance with the License. Please obtain a copy of the License | |
7 | // at http://www.opencascade.org and read it completely before using this file. | |
8 | // | |
9 | // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its | |
10 | // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. | |
11 | // | |
12 | // The Original Code and all software distributed under the License is | |
13 | // distributed on an "AS IS" basis, without warranty of any kind, and the | |
14 | // Initial Developer hereby disclaims all such warranties, including without | |
15 | // limitation, any warranties of merchantability, fitness for a particular | |
16 | // purpose or non-infringement. Please see the License for the specific terms | |
17 | // and conditions governing the rights and limitations under the License. | |
18 | ||
7fd59977 | 19 | #include <Standard_TypeMismatch.hxx> |
408ecc39 | 20 | #include <Precision.hxx> |
7fd59977 | 21 | #define delta 1.e-9 |
22 | #define Tol 1.e-20 | |
23 | ||
24 | /*----------------------------------------------------------------------------- | |
25 | Fonction permettant de rechercher une distance extremale entre un point P et | |
26 | une courbe C (en partant d'un point approche C(u0)). | |
27 | Cette classe herite de math_FunctionWithDerivative et est utilisee par | |
28 | les algorithmes math_FunctionRoot et math_FunctionRoots. | |
29 | Si on note D1c et D2c les derivees premiere et seconde: | |
30 | { F(u) = (C(u)-P).D1c(u)/ ||Du||} | |
31 | { DF(u) = ||Du|| + (C(u)-P).D2c(u)/||Du|| - F(u)*Duu*Du/||Du||**2 | |
32 | ||
33 | ||
34 | { F(u) = (C(u)-P).D1c(u) } | |
35 | { DF(u) = D1c(u).D1c(u) + (C(u)-P).D2c(u) | |
36 | = ||D1c(u)|| ** 2 + (C(u)-P).D2c(u) } | |
37 | ----------------------------------------------------------------------------*/ | |
38 | ||
39 | ||
40 | Extrema_FuncExtPC::Extrema_FuncExtPC(): | |
41 | myU(0.), | |
42 | myD1f(0.) | |
43 | { | |
44 | myPinit = Standard_False; | |
45 | myCinit = Standard_False; | |
46 | myD1Init = Standard_False; | |
47 | } | |
48 | ||
49 | //============================================================================= | |
50 | ||
51 | Extrema_FuncExtPC::Extrema_FuncExtPC (const Pnt& P, | |
52 | const Curve& C): | |
53 | myU(0.), | |
54 | myD1f(0.) | |
55 | { | |
56 | myP = P; | |
57 | myC = (Standard_Address)&C; | |
58 | myPinit = Standard_True; | |
59 | myCinit = Standard_True; | |
60 | myD1Init = Standard_False; | |
61 | } | |
62 | //============================================================================= | |
63 | ||
64 | void Extrema_FuncExtPC::Initialize(const Curve& C) | |
65 | { | |
66 | myC = (Standard_Address)&C; | |
67 | myCinit = Standard_True; | |
68 | myPoint.Clear(); | |
69 | mySqDist.Clear(); | |
70 | myIsMin.Clear(); | |
71 | } | |
72 | ||
73 | //============================================================================= | |
74 | ||
75 | void Extrema_FuncExtPC::SetPoint(const Pnt& P) | |
76 | { | |
77 | myP = P; | |
78 | myPinit = Standard_True; | |
79 | myPoint.Clear(); | |
80 | mySqDist.Clear(); | |
81 | myIsMin.Clear(); | |
82 | } | |
83 | ||
84 | //============================================================================= | |
85 | ||
86 | Standard_Boolean Extrema_FuncExtPC::Value (const Standard_Real U, Standard_Real& F) | |
87 | { | |
88 | if (!myPinit || !myCinit) Standard_TypeMismatch::Raise(); | |
89 | myU = U; | |
90 | Vec D1c; | |
91 | Tool::D1(*((Curve*)myC),myU,myPc,D1c); | |
92 | Standard_Real Ndu = D1c.Magnitude(); | |
93 | if (Ndu <= Tol) { // Cas Singulier (PMN 22/04/1998) | |
408ecc39 G |
94 | Pnt P1, P2; |
95 | P2 = Tool::Value(*((Curve*)myC),myU + delta); | |
96 | P1 = Tool::Value(*((Curve*)myC),myU - delta); | |
97 | Vec V(P1,P2); | |
98 | D1c = V; | |
99 | Ndu = D1c.Magnitude(); | |
100 | if (Ndu <= Tol) { | |
101 | Vec aD2; | |
102 | Tool::D2(*((Curve*)myC),myU,myPc,D1c,aD2); | |
103 | Ndu = aD2.Magnitude(); | |
104 | ||
105 | if(Ndu <= Tol) | |
106 | return Standard_False; | |
107 | D1c = aD2; | |
7fd59977 | 108 | } |
109 | } | |
408ecc39 | 110 | |
7fd59977 | 111 | Vec PPc (myP,myPc); |
112 | F = PPc.Dot(D1c)/Ndu; | |
113 | return Standard_True; | |
114 | } | |
115 | ||
116 | //============================================================================= | |
117 | ||
118 | Standard_Boolean Extrema_FuncExtPC::Derivative (const Standard_Real U, Standard_Real& D1f) | |
119 | { | |
120 | if (!myPinit || !myCinit) Standard_TypeMismatch::Raise(); | |
121 | Standard_Real F; | |
122 | return Values(U,F,D1f); /* on fait appel a Values pour simplifier la | |
123 | sauvegarde de l'etat. */ | |
124 | } | |
125 | //============================================================================= | |
126 | ||
127 | Standard_Boolean Extrema_FuncExtPC::Values (const Standard_Real U, Standard_Real& F, Standard_Real& D1f) | |
128 | { | |
129 | if (!myPinit || !myCinit) Standard_TypeMismatch::Raise(); | |
130 | myU = U; | |
131 | Vec D1c,D2c; | |
132 | Tool::D2(*((Curve*)myC),myU,myPc,D1c,D2c); | |
133 | ||
134 | Standard_Real Ndu = D1c.Magnitude(); | |
135 | if (Ndu <= Tol) {// Cas Singulier (PMN 22/04/1998) | |
136 | Pnt P1, P2; | |
137 | Vec V1; | |
138 | Tool::D1(*((Curve*)myC),myU+delta, P2, V1); | |
139 | Tool::D1(*((Curve*)myC),myU-delta, P1, D2c); | |
140 | Vec V(P1,P2); | |
141 | D1c = V; | |
142 | D2c -= V1; | |
143 | Ndu = D1c.Magnitude(); | |
144 | if (Ndu <= Tol) { | |
145 | myD1Init = Standard_False; | |
146 | return Standard_False; | |
147 | } | |
148 | } | |
149 | ||
150 | Vec PPc (myP,myPc); | |
151 | F = PPc.Dot(D1c)/Ndu; | |
152 | D1f = Ndu + (PPc.Dot(D2c)/Ndu) - F*(D1c.Dot(D2c))/(Ndu*Ndu); | |
153 | ||
154 | myD1f = D1f; | |
155 | myD1Init = Standard_True; | |
156 | return Standard_True; | |
157 | } | |
158 | //============================================================================= | |
159 | ||
160 | Standard_Integer Extrema_FuncExtPC::GetStateNumber () | |
161 | { | |
162 | if (!myPinit || !myCinit) Standard_TypeMismatch::Raise(); | |
163 | mySqDist.Append(myPc.SquareDistance(myP)); | |
164 | Standard_Integer IntVal; | |
165 | if (!myD1Init) { | |
166 | myD1Init = Standard_True; | |
167 | Standard_Real FF, DD; | |
168 | Values(myU, FF, DD); | |
169 | } | |
170 | if (!myD1Init) IntVal = 0; | |
171 | else { | |
172 | if (myD1f > 0.) { IntVal = 1; } | |
173 | else { IntVal = 0; } | |
174 | } | |
175 | myIsMin.Append(IntVal); | |
176 | myPoint.Append(POnC(myU,myPc)); | |
177 | return 0; | |
178 | } | |
179 | //============================================================================= | |
180 | ||
181 | Standard_Integer Extrema_FuncExtPC::NbExt () const { return mySqDist.Length(); } | |
182 | //============================================================================= | |
183 | ||
184 | Standard_Real Extrema_FuncExtPC::SquareDistance (const Standard_Integer N) const | |
185 | { | |
186 | if (!myPinit || !myCinit) Standard_TypeMismatch::Raise(); | |
187 | return mySqDist.Value(N); | |
188 | } | |
189 | //============================================================================= | |
190 | Standard_Boolean Extrema_FuncExtPC::IsMin (const Standard_Integer N) const | |
191 | { | |
192 | if (!myPinit || !myCinit) Standard_TypeMismatch::Raise(); | |
193 | return (myIsMin.Value(N) == 1); | |
194 | } | |
195 | //============================================================================= | |
196 | POnC Extrema_FuncExtPC::Point (const Standard_Integer N) const | |
197 | { | |
198 | if (!myPinit || !myCinit) Standard_TypeMismatch::Raise(); | |
199 | return myPoint.Value(N); | |
200 | } | |
201 | //============================================================================= | |
202 |