Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 1993-12-13 |
2 | // Created by: Christophe MARION | |
3 | // Copyright (c) 1993-1999 Matra Datavision | |
4 | // Copyright (c) 1999-2012 OPEN CASCADE SAS | |
5 | // | |
6 | // The content of this file is subject to the Open CASCADE Technology Public | |
7 | // License Version 6.5 (the "License"). You may not use the content of this file | |
8 | // except in compliance with the License. Please obtain a copy of the License | |
9 | // at http://www.opencascade.org and read it completely before using this file. | |
10 | // | |
11 | // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its | |
12 | // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. | |
13 | // | |
14 | // The Original Code and all software distributed under the License is | |
15 | // distributed on an "AS IS" basis, without warranty of any kind, and the | |
16 | // Initial Developer hereby disclaims all such warranties, including without | |
17 | // limitation, any warranties of merchantability, fitness for a particular | |
18 | // purpose or non-infringement. Please see the License for the specific terms | |
19 | // and conditions governing the rights and limitations under the License. | |
20 | ||
7fd59977 | 21 | |
22 | #include <Precision.hxx> | |
23 | #include <Extrema_ExtPElC2d.ixx> | |
24 | #include <StdFail_NotDone.hxx> | |
25 | #include <math_DirectPolynomialRoots.hxx> | |
26 | #include <math_TrigonometricFunctionRoots.hxx> | |
27 | #include <ElCLib.hxx> | |
28 | #include <Standard_OutOfRange.hxx> | |
29 | #include <Standard_NotImplemented.hxx> | |
30 | //============================================================================= | |
31 | ||
32 | Extrema_ExtPElC2d::Extrema_ExtPElC2d () { myDone = Standard_False; } | |
33 | //============================================================================= | |
34 | ||
35 | Extrema_ExtPElC2d::Extrema_ExtPElC2d | |
36 | (const gp_Pnt2d& P, | |
37 | const gp_Lin2d& L, | |
38 | const Standard_Real Tol, | |
39 | const Standard_Real Uinf, | |
40 | const Standard_Real Usup) | |
41 | { | |
42 | Perform(P, L, Tol, Uinf, Usup); | |
43 | } | |
44 | ||
45 | void Extrema_ExtPElC2d::Perform(const gp_Pnt2d& P, | |
46 | const gp_Lin2d& L, | |
47 | const Standard_Real Tol, | |
48 | const Standard_Real Uinf, | |
49 | const Standard_Real Usup) | |
50 | { | |
51 | myDone = Standard_True; | |
52 | gp_Pnt2d OR, MyP; | |
53 | myNbExt = 0; | |
54 | ||
55 | gp_Vec2d V1 = gp_Vec2d(L.Direction()); | |
56 | OR = L.Location(); | |
57 | gp_Vec2d V(OR, P); | |
58 | Standard_Real Mydist = V1.Dot(V); | |
59 | if ((Mydist >= Uinf -Tol) && | |
60 | (Mydist <= Usup+ Tol)){ | |
61 | myNbExt = 1; | |
62 | MyP = OR.Translated(Mydist*V1); | |
63 | Extrema_POnCurv2d MyPOnCurve(Mydist, MyP); | |
64 | mySqDist[0] = P.SquareDistance(MyP); | |
65 | myPoint[0] = MyPOnCurve; | |
66 | myIsMin[0] = Standard_True; | |
67 | } | |
68 | } | |
69 | ||
70 | //============================================================================= | |
71 | ||
72 | Extrema_ExtPElC2d::Extrema_ExtPElC2d | |
73 | (const gp_Pnt2d& P, | |
74 | const gp_Circ2d& C, | |
75 | const Standard_Real Tol, | |
76 | const Standard_Real Uinf, | |
77 | const Standard_Real Usup) | |
78 | { | |
79 | Perform(P, C, Tol, Uinf, Usup); | |
80 | } | |
81 | ||
82 | void Extrema_ExtPElC2d::Perform(const gp_Pnt2d& P, | |
83 | const gp_Circ2d& C, | |
84 | const Standard_Real Tol, | |
85 | const Standard_Real Uinf, | |
86 | const Standard_Real Usup) | |
87 | { | |
88 | Standard_Real radius, U1, U2; | |
89 | // gp_Pnt2d OC, P1, P2, OL; | |
90 | gp_Pnt2d OC, P1, P2; | |
91 | OC = C.Location(); | |
92 | myNbExt = 0; | |
93 | ||
94 | if (OC.IsEqual(P, Precision::Confusion())) { | |
95 | myDone = Standard_False; | |
96 | } | |
97 | else { | |
98 | myDone = Standard_True; | |
99 | gp_Dir2d V(gp_Vec2d(P, OC)); | |
100 | radius = C.Radius(); | |
101 | P1 = OC.Translated(radius*V); | |
102 | U1 = ElCLib::Parameter(C, P1); | |
c6541a0c | 103 | U2 = U1 + M_PI; |
7fd59977 | 104 | P2 = OC.Translated(-radius*V); |
105 | Standard_Real myuinf = Uinf; | |
c6541a0c D |
106 | ElCLib::AdjustPeriodic(Uinf, Uinf+2*M_PI, Precision::PConfusion(), myuinf, U1); |
107 | ElCLib::AdjustPeriodic(Uinf, Uinf+2*M_PI, Precision::PConfusion(), myuinf, U2); | |
108 | if (((U1-2*M_PI-Uinf) < Tol) && ((U1-2*M_PI-Uinf) > -Tol)) U1 = Uinf; | |
109 | if (((U2-2*M_PI-Uinf) < Tol) && ((U2-2*M_PI-Uinf) > -Tol)) U2 = Uinf; | |
7fd59977 | 110 | |
111 | if (((Uinf-U1) < Tol) && ((U1-Usup) < Tol)) { | |
112 | Extrema_POnCurv2d MyPOnCurve(U1, P1); | |
113 | mySqDist[0] = P.SquareDistance(P1); | |
114 | myPoint[0] = MyPOnCurve; | |
115 | myIsMin[0] = Standard_True; | |
116 | myNbExt++; | |
117 | } | |
118 | ||
119 | if (((Uinf-U2) < Tol) && ((U2-Usup) < Tol)) { | |
120 | Extrema_POnCurv2d MyPOnCurve(U2, P2); | |
121 | mySqDist[myNbExt] = P.SquareDistance(P2); | |
122 | myPoint[myNbExt] = MyPOnCurve; | |
123 | myIsMin[myNbExt] = Standard_True; | |
124 | myNbExt++; | |
125 | } | |
126 | } | |
127 | } | |
128 | ||
129 | //============================================================================= | |
130 | ||
131 | ||
132 | Extrema_ExtPElC2d::Extrema_ExtPElC2d (const gp_Pnt2d& P, | |
133 | const gp_Elips2d& E, | |
134 | const Standard_Real Tol, | |
135 | const Standard_Real Uinf, | |
136 | const Standard_Real Usup) | |
137 | { | |
138 | Perform(P, E, Tol, Uinf, Usup); | |
139 | } | |
140 | ||
141 | ||
142 | ||
143 | void Extrema_ExtPElC2d::Perform (const gp_Pnt2d& P, | |
144 | const gp_Elips2d& E, | |
145 | const Standard_Real Tol, | |
146 | const Standard_Real Uinf, | |
147 | const Standard_Real Usup) | |
148 | { | |
149 | // gp_Pnt2d OR, P1, P2; | |
150 | gp_Pnt2d OR; | |
151 | OR = E.Location(); | |
152 | ||
153 | Standard_Integer NoSol, NbSol; | |
154 | Standard_Real A = E.MajorRadius(); | |
155 | Standard_Real B = E.MinorRadius(); | |
156 | gp_Vec2d V(OR,P); | |
157 | ||
158 | if (OR.IsEqual(P, Precision::Confusion()) && | |
159 | (Abs(A-B) <= Tol)) { | |
160 | myDone = Standard_False; | |
161 | } | |
162 | else { | |
7fd59977 | 163 | Standard_Real X = V.Dot(gp_Vec2d(E.XAxis().Direction())); |
164 | Standard_Real Y = V.Dot(gp_Vec2d(E.YAxis().Direction())); | |
165 | ||
166 | math_TrigonometricFunctionRoots Sol(0.,(B*B-A*A)/2.,-B*Y,A*X,0.,Uinf,Usup); | |
167 | ||
168 | if (!Sol.IsDone()) { return; } | |
169 | gp_Pnt2d Cu; | |
170 | Standard_Real Us; | |
171 | NbSol = Sol.NbSolutions(); | |
172 | myNbExt = 0; | |
173 | for (NoSol = 1; NoSol <= NbSol; NoSol++) { | |
174 | Us = Sol.Value(NoSol); | |
175 | Cu = ElCLib::Value(Us, E); | |
176 | mySqDist[myNbExt] = Cu.SquareDistance(P); | |
177 | myIsMin[myNbExt] = (NoSol == 0); | |
178 | myPoint[myNbExt] = Extrema_POnCurv2d(Us,Cu); | |
179 | myNbExt++; | |
180 | } | |
181 | myDone = Standard_True; | |
182 | } | |
183 | } | |
184 | //============================================================================= | |
185 | ||
186 | Extrema_ExtPElC2d::Extrema_ExtPElC2d (const gp_Pnt2d& P, | |
187 | const gp_Hypr2d& C, | |
188 | const Standard_Real Tol, | |
189 | const Standard_Real Uinf, | |
190 | const Standard_Real Usup) | |
191 | { | |
192 | Perform(P, C, Tol, Uinf, Usup); | |
193 | } | |
194 | ||
195 | ||
196 | void Extrema_ExtPElC2d::Perform(const gp_Pnt2d& P, | |
197 | const gp_Hypr2d& H, | |
198 | const Standard_Real Tol, | |
199 | const Standard_Real Uinf, | |
200 | const Standard_Real Usup) | |
201 | { | |
202 | gp_Pnt2d O = H.Location(); | |
203 | myDone = Standard_False; | |
204 | myNbExt = 0; | |
205 | ||
206 | Standard_Real R = H.MajorRadius(); | |
207 | Standard_Real r = H.MinorRadius(); | |
208 | gp_Vec2d OPp(O,P); | |
7fd59977 | 209 | Standard_Real Tol2 = Tol * Tol; |
210 | Standard_Real X = OPp.Dot(gp_Vec2d(H.XAxis().Direction())); | |
211 | Standard_Real Y = OPp.Dot(gp_Vec2d(H.YAxis().Direction())); | |
212 | Standard_Real C1 = (R*R+r*r)/4.; | |
213 | math_DirectPolynomialRoots Sol(C1,-(X*R+Y*r)/2.,0.,(X*R-Y*r)/2.,-C1); | |
214 | if (!Sol.IsDone()) { return; } | |
215 | gp_Pnt2d Cu; | |
216 | Standard_Real Us, Vs; | |
217 | Standard_Integer NbSol = Sol.NbSolutions(); | |
218 | Standard_Boolean DejaEnr; | |
219 | Standard_Integer NoExt; | |
220 | gp_Pnt2d TbExt[4]; | |
221 | for (Standard_Integer NoSol = 1; NoSol <= NbSol; NoSol++) { | |
222 | Vs = Sol.Value(NoSol); | |
223 | if (Vs > 0.) { | |
224 | Us = Log(Vs); | |
225 | if ((Us >= Uinf) && (Us <= Usup)) { | |
226 | Cu = ElCLib::Value(Us,H); | |
227 | DejaEnr = Standard_False; | |
228 | for (NoExt = 0; NoExt < myNbExt; NoExt++) { | |
229 | if (TbExt[NoExt].SquareDistance(Cu) < Tol2) { | |
230 | DejaEnr = Standard_True; | |
231 | break; | |
232 | } | |
233 | } | |
234 | if (!DejaEnr) { | |
235 | TbExt[myNbExt] = Cu; | |
236 | mySqDist[myNbExt] = Cu.SquareDistance(P); | |
237 | myIsMin[myNbExt] = (NoSol == 0); | |
238 | myPoint[myNbExt] = Extrema_POnCurv2d(Us,Cu); | |
239 | myNbExt++; | |
240 | } | |
241 | } // if ((Us >= Uinf) && (Us <= Usup)) | |
242 | } // if (Vs > 0.) | |
243 | } // for (Standard_Integer NoSol = 1; ... | |
244 | myDone = Standard_True; | |
245 | } | |
246 | ||
247 | //============================================================================= | |
248 | ||
249 | Extrema_ExtPElC2d::Extrema_ExtPElC2d (const gp_Pnt2d& P, | |
250 | const gp_Parab2d& C, | |
251 | const Standard_Real Tol, | |
252 | const Standard_Real Uinf, | |
253 | const Standard_Real Usup) | |
254 | { | |
255 | Perform(P, C, Tol, Uinf, Usup); | |
256 | } | |
257 | ||
258 | ||
259 | void Extrema_ExtPElC2d::Perform(const gp_Pnt2d& P, | |
260 | const gp_Parab2d& C, | |
261 | const Standard_Real Tol, | |
262 | const Standard_Real Uinf, | |
263 | const Standard_Real Usup) | |
264 | { | |
265 | myDone = Standard_False; | |
266 | myNbExt = 0; | |
267 | gp_Pnt2d O = C.Location(); | |
268 | ||
269 | Standard_Real Tol2 = Tol * Tol; | |
270 | Standard_Real F = C.Focal(); | |
271 | gp_Vec2d OPp (O,P); | |
7fd59977 | 272 | Standard_Real X = OPp.Dot(gp_Vec2d(C.MirrorAxis().Direction())); |
273 | Standard_Real Y = OPp.Dot(gp_Vec2d(C.Axis().YAxis().Direction())); | |
274 | ||
275 | math_DirectPolynomialRoots Sol(1./(4.*F),0.,2.*F-X,-2.*F*Y); | |
276 | if (!Sol.IsDone()) { return; } | |
277 | gp_Pnt2d Cu; | |
278 | Standard_Real Us; | |
279 | Standard_Integer NbSol = Sol.NbSolutions(); | |
280 | Standard_Boolean DejaEnr; | |
281 | Standard_Integer NoExt; | |
282 | gp_Pnt2d TbExt[3]; | |
283 | for (Standard_Integer NoSol = 1; NoSol <= NbSol; NoSol++) { | |
284 | Us = Sol.Value(NoSol); | |
285 | if ((Us >= Uinf) && (Us <= Usup)) { | |
286 | Cu = ElCLib::Value(Us,C); | |
287 | DejaEnr = Standard_False; | |
288 | for (NoExt = 0; NoExt < myNbExt; NoExt++) { | |
289 | if (TbExt[NoExt].SquareDistance(Cu) < Tol2) { | |
290 | DejaEnr = Standard_True; | |
291 | break; | |
292 | } | |
293 | } | |
294 | if (!DejaEnr) { | |
295 | TbExt[myNbExt] = Cu; | |
296 | mySqDist[myNbExt] = Cu.SquareDistance(P); | |
297 | myIsMin[myNbExt] = (NoSol == 0); | |
298 | myPoint[myNbExt] = Extrema_POnCurv2d(Us,Cu); | |
299 | myNbExt++; | |
300 | } | |
301 | } // if ((Us >= Uinf) && (Us <= Usup)) | |
302 | } // for (Standard_Integer NoSol = 1; ... | |
303 | myDone = Standard_True; | |
304 | } | |
305 | //============================================================================= | |
306 | ||
307 | Standard_Boolean Extrema_ExtPElC2d::IsDone () const { return myDone; } | |
308 | //============================================================================= | |
309 | ||
310 | Standard_Integer Extrema_ExtPElC2d::NbExt () const | |
311 | { | |
312 | if (!IsDone()) { StdFail_NotDone::Raise(); } | |
313 | return myNbExt; | |
314 | } | |
315 | //============================================================================= | |
316 | ||
317 | Standard_Real Extrema_ExtPElC2d::SquareDistance (const Standard_Integer N) const | |
318 | { | |
319 | if ((N < 1) || (N > NbExt())) { Standard_OutOfRange::Raise(); } | |
320 | return mySqDist[N-1]; | |
321 | } | |
322 | //============================================================================= | |
323 | ||
324 | Standard_Boolean Extrema_ExtPElC2d::IsMin (const Standard_Integer N) const | |
325 | { | |
326 | if ((N < 1) || (N > NbExt())) { Standard_OutOfRange::Raise(); } | |
327 | return myIsMin[N-1]; | |
328 | } | |
329 | //============================================================================= | |
330 | ||
331 | Extrema_POnCurv2d Extrema_ExtPElC2d::Point (const Standard_Integer N) const | |
332 | { | |
333 | if ((N < 1) || (N > NbExt())) { Standard_OutOfRange::Raise(); } | |
334 | return myPoint[N-1]; | |
335 | } | |
336 | //============================================================================= |