Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 1993-12-13 |
2 | // Created by: Christophe MARION | |
3 | // Copyright (c) 1993-1999 Matra Datavision | |
973c2be1 | 4 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e | 5 | // |
973c2be1 | 6 | // This file is part of Open CASCADE Technology software library. |
b311480e | 7 | // |
d5f74e42 | 8 | // This library is free software; you can redistribute it and/or modify it under |
9 | // the terms of the GNU Lesser General Public License version 2.1 as published | |
973c2be1 | 10 | // by the Free Software Foundation, with special exception defined in the file |
11 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT | |
12 | // distribution for complete text of the license and disclaimer of any warranty. | |
b311480e | 13 | // |
973c2be1 | 14 | // Alternatively, this file may be used under the terms of Open CASCADE |
15 | // commercial license or contractual agreement. | |
7fd59977 | 16 | |
42cf5bc1 | 17 | |
18 | #include <ElCLib.hxx> | |
19 | #include <Extrema_ExtPElC2d.hxx> | |
20 | #include <Extrema_POnCurv2d.hxx> | |
21 | #include <gp_Circ2d.hxx> | |
22 | #include <gp_Elips2d.hxx> | |
23 | #include <gp_Hypr2d.hxx> | |
24 | #include <gp_Lin2d.hxx> | |
25 | #include <gp_Parab2d.hxx> | |
26 | #include <gp_Pnt2d.hxx> | |
7fd59977 | 27 | #include <math_DirectPolynomialRoots.hxx> |
28 | #include <math_TrigonometricFunctionRoots.hxx> | |
42cf5bc1 | 29 | #include <Precision.hxx> |
7fd59977 | 30 | #include <Standard_NotImplemented.hxx> |
42cf5bc1 | 31 | #include <Standard_OutOfRange.hxx> |
32 | #include <StdFail_NotDone.hxx> | |
7fd59977 | 33 | |
42cf5bc1 | 34 | //============================================================================= |
638ad7f3 | 35 | Extrema_ExtPElC2d::Extrema_ExtPElC2d() |
36 | { | |
37 | myDone = Standard_False; | |
38 | myNbExt = 0; | |
39 | ||
40 | for (Standard_Integer i = 0; i < 4; i++) | |
41 | { | |
42 | mySqDist[i] = RealLast(); | |
43 | myIsMin[i] = Standard_False; | |
44 | } | |
45 | } | |
46 | ||
7fd59977 | 47 | //============================================================================= |
48 | ||
49 | Extrema_ExtPElC2d::Extrema_ExtPElC2d | |
50 | (const gp_Pnt2d& P, | |
73cd8a8a | 51 | const gp_Lin2d& L, |
52 | const Standard_Real Tol, | |
53 | const Standard_Real Uinf, | |
54 | const Standard_Real Usup) | |
7fd59977 | 55 | { |
56 | Perform(P, L, Tol, Uinf, Usup); | |
57 | } | |
58 | ||
59 | void Extrema_ExtPElC2d::Perform(const gp_Pnt2d& P, | |
73cd8a8a | 60 | const gp_Lin2d& L, |
61 | const Standard_Real Tol, | |
62 | const Standard_Real Uinf, | |
63 | const Standard_Real Usup) | |
7fd59977 | 64 | { |
65 | myDone = Standard_True; | |
66 | gp_Pnt2d OR, MyP; | |
67 | myNbExt = 0; | |
68 | ||
69 | gp_Vec2d V1 = gp_Vec2d(L.Direction()); | |
70 | OR = L.Location(); | |
71 | gp_Vec2d V(OR, P); | |
72 | Standard_Real Mydist = V1.Dot(V); | |
73 | if ((Mydist >= Uinf -Tol) && | |
73cd8a8a | 74 | (Mydist <= Usup+ Tol)){ |
75 | myNbExt = 1; | |
76 | MyP = OR.Translated(Mydist*V1); | |
77 | Extrema_POnCurv2d MyPOnCurve(Mydist, MyP); | |
78 | mySqDist[0] = P.SquareDistance(MyP); | |
79 | myPoint[0] = MyPOnCurve; | |
80 | myIsMin[0] = Standard_True; | |
7fd59977 | 81 | } |
82 | } | |
83 | ||
84 | //============================================================================= | |
85 | ||
86 | Extrema_ExtPElC2d::Extrema_ExtPElC2d | |
87 | (const gp_Pnt2d& P, | |
73cd8a8a | 88 | const gp_Circ2d& C, |
89 | const Standard_Real Tol, | |
90 | const Standard_Real Uinf, | |
91 | const Standard_Real Usup) | |
7fd59977 | 92 | { |
93 | Perform(P, C, Tol, Uinf, Usup); | |
94 | } | |
95 | ||
96 | void Extrema_ExtPElC2d::Perform(const gp_Pnt2d& P, | |
73cd8a8a | 97 | const gp_Circ2d& C, |
98 | const Standard_Real Tol, | |
99 | const Standard_Real Uinf, | |
100 | const Standard_Real Usup) | |
7fd59977 | 101 | { |
73cd8a8a | 102 | // gp_Pnt2d OC, P1, P2, OL; |
103 | gp_Pnt2d OC(C.Location()); | |
7fd59977 | 104 | myNbExt = 0; |
73cd8a8a | 105 | |
7fd59977 | 106 | if (OC.IsEqual(P, Precision::Confusion())) { |
107 | myDone = Standard_False; | |
108 | } | |
73cd8a8a | 109 | else |
110 | { | |
111 | Standard_Real radius, U1, U2; | |
112 | gp_Pnt2d P1, P2; | |
113 | ||
7fd59977 | 114 | myDone = Standard_True; |
115 | gp_Dir2d V(gp_Vec2d(P, OC)); | |
116 | radius = C.Radius(); | |
117 | P1 = OC.Translated(radius*V); | |
118 | U1 = ElCLib::Parameter(C, P1); | |
c6541a0c | 119 | U2 = U1 + M_PI; |
7fd59977 | 120 | P2 = OC.Translated(-radius*V); |
121 | Standard_Real myuinf = Uinf; | |
c6541a0c D |
122 | ElCLib::AdjustPeriodic(Uinf, Uinf+2*M_PI, Precision::PConfusion(), myuinf, U1); |
123 | ElCLib::AdjustPeriodic(Uinf, Uinf+2*M_PI, Precision::PConfusion(), myuinf, U2); | |
73cd8a8a | 124 | if (((U1-2*M_PI-Uinf) < Tol) && ((U1-2*M_PI-Uinf) > -Tol)) |
125 | { | |
126 | U1 = Uinf; | |
127 | P1 = OC.XY() + radius * (cos(U1) * C.XAxis().Direction().XY() + sin(U1) * C.YAxis().Direction().XY()); | |
128 | } | |
7fd59977 | 129 | |
73cd8a8a | 130 | if (((U2-2*M_PI-Uinf) < Tol) && ((U2-2*M_PI-Uinf) > -Tol)) |
131 | { | |
132 | U2 = Uinf; | |
133 | P2 = OC.XY() + radius * (cos(U2) * C.XAxis().Direction().XY() + sin(U2) * C.YAxis().Direction().XY()); | |
134 | } | |
135 | ||
136 | if (((Uinf-U1) < Tol) && ((U1-Usup) < Tol)) | |
137 | { | |
7fd59977 | 138 | Extrema_POnCurv2d MyPOnCurve(U1, P1); |
139 | mySqDist[0] = P.SquareDistance(P1); | |
140 | myPoint[0] = MyPOnCurve; | |
141 | myIsMin[0] = Standard_True; | |
142 | myNbExt++; | |
143 | } | |
73cd8a8a | 144 | |
145 | if (((Uinf-U2) < Tol) && ((U2-Usup) < Tol)) | |
146 | { | |
7fd59977 | 147 | Extrema_POnCurv2d MyPOnCurve(U2, P2); |
148 | mySqDist[myNbExt] = P.SquareDistance(P2); | |
149 | myPoint[myNbExt] = MyPOnCurve; | |
150 | myIsMin[myNbExt] = Standard_True; | |
151 | myNbExt++; | |
152 | } | |
153 | } | |
154 | } | |
155 | ||
156 | //============================================================================= | |
157 | ||
158 | ||
159 | Extrema_ExtPElC2d::Extrema_ExtPElC2d (const gp_Pnt2d& P, | |
73cd8a8a | 160 | const gp_Elips2d& E, |
161 | const Standard_Real Tol, | |
162 | const Standard_Real Uinf, | |
163 | const Standard_Real Usup) | |
7fd59977 | 164 | { |
165 | Perform(P, E, Tol, Uinf, Usup); | |
166 | } | |
167 | ||
168 | ||
169 | ||
170 | void Extrema_ExtPElC2d::Perform (const gp_Pnt2d& P, | |
73cd8a8a | 171 | const gp_Elips2d& E, |
172 | const Standard_Real Tol, | |
173 | const Standard_Real Uinf, | |
174 | const Standard_Real Usup) | |
7fd59977 | 175 | { |
638ad7f3 | 176 | myDone = Standard_False; |
177 | myNbExt = 0; | |
73cd8a8a | 178 | // gp_Pnt2d OR, P1, P2; |
7fd59977 | 179 | gp_Pnt2d OR; |
180 | OR = E.Location(); | |
73cd8a8a | 181 | |
7fd59977 | 182 | Standard_Integer NoSol, NbSol; |
183 | Standard_Real A = E.MajorRadius(); | |
184 | Standard_Real B = E.MinorRadius(); | |
185 | gp_Vec2d V(OR,P); | |
186 | ||
187 | if (OR.IsEqual(P, Precision::Confusion()) && | |
73cd8a8a | 188 | (Abs(A-B) <= Tol)) { |
638ad7f3 | 189 | return; |
7fd59977 | 190 | } |
191 | else { | |
7fd59977 | 192 | Standard_Real X = V.Dot(gp_Vec2d(E.XAxis().Direction())); |
193 | Standard_Real Y = V.Dot(gp_Vec2d(E.YAxis().Direction())); | |
194 | ||
195 | math_TrigonometricFunctionRoots Sol(0.,(B*B-A*A)/2.,-B*Y,A*X,0.,Uinf,Usup); | |
196 | ||
197 | if (!Sol.IsDone()) { return; } | |
198 | gp_Pnt2d Cu; | |
199 | Standard_Real Us; | |
200 | NbSol = Sol.NbSolutions(); | |
201 | myNbExt = 0; | |
202 | for (NoSol = 1; NoSol <= NbSol; NoSol++) { | |
203 | Us = Sol.Value(NoSol); | |
204 | Cu = ElCLib::Value(Us, E); | |
205 | mySqDist[myNbExt] = Cu.SquareDistance(P); | |
206 | myIsMin[myNbExt] = (NoSol == 0); | |
207 | myPoint[myNbExt] = Extrema_POnCurv2d(Us,Cu); | |
208 | myNbExt++; | |
209 | } | |
210 | myDone = Standard_True; | |
211 | } | |
212 | } | |
213 | //============================================================================= | |
214 | ||
215 | Extrema_ExtPElC2d::Extrema_ExtPElC2d (const gp_Pnt2d& P, | |
73cd8a8a | 216 | const gp_Hypr2d& C, |
217 | const Standard_Real Tol, | |
218 | const Standard_Real Uinf, | |
219 | const Standard_Real Usup) | |
7fd59977 | 220 | { |
221 | Perform(P, C, Tol, Uinf, Usup); | |
222 | } | |
223 | ||
224 | ||
225 | void Extrema_ExtPElC2d::Perform(const gp_Pnt2d& P, | |
73cd8a8a | 226 | const gp_Hypr2d& H, |
227 | const Standard_Real Tol, | |
228 | const Standard_Real Uinf, | |
229 | const Standard_Real Usup) | |
7fd59977 | 230 | { |
231 | gp_Pnt2d O = H.Location(); | |
232 | myDone = Standard_False; | |
233 | myNbExt = 0; | |
234 | ||
235 | Standard_Real R = H.MajorRadius(); | |
236 | Standard_Real r = H.MinorRadius(); | |
237 | gp_Vec2d OPp(O,P); | |
7fd59977 | 238 | Standard_Real Tol2 = Tol * Tol; |
239 | Standard_Real X = OPp.Dot(gp_Vec2d(H.XAxis().Direction())); | |
240 | Standard_Real Y = OPp.Dot(gp_Vec2d(H.YAxis().Direction())); | |
241 | Standard_Real C1 = (R*R+r*r)/4.; | |
242 | math_DirectPolynomialRoots Sol(C1,-(X*R+Y*r)/2.,0.,(X*R-Y*r)/2.,-C1); | |
243 | if (!Sol.IsDone()) { return; } | |
244 | gp_Pnt2d Cu; | |
245 | Standard_Real Us, Vs; | |
246 | Standard_Integer NbSol = Sol.NbSolutions(); | |
247 | Standard_Boolean DejaEnr; | |
248 | Standard_Integer NoExt; | |
249 | gp_Pnt2d TbExt[4]; | |
250 | for (Standard_Integer NoSol = 1; NoSol <= NbSol; NoSol++) { | |
251 | Vs = Sol.Value(NoSol); | |
252 | if (Vs > 0.) { | |
253 | Us = Log(Vs); | |
254 | if ((Us >= Uinf) && (Us <= Usup)) { | |
73cd8a8a | 255 | Cu = ElCLib::Value(Us,H); |
256 | DejaEnr = Standard_False; | |
257 | for (NoExt = 0; NoExt < myNbExt; NoExt++) { | |
258 | if (TbExt[NoExt].SquareDistance(Cu) < Tol2) { | |
259 | DejaEnr = Standard_True; | |
260 | break; | |
261 | } | |
262 | } | |
263 | if (!DejaEnr) { | |
264 | TbExt[myNbExt] = Cu; | |
265 | mySqDist[myNbExt] = Cu.SquareDistance(P); | |
266 | myIsMin[myNbExt] = (NoSol == 0); | |
267 | myPoint[myNbExt] = Extrema_POnCurv2d(Us,Cu); | |
268 | myNbExt++; | |
269 | } | |
7fd59977 | 270 | } // if ((Us >= Uinf) && (Us <= Usup)) |
271 | } // if (Vs > 0.) | |
272 | } // for (Standard_Integer NoSol = 1; ... | |
273 | myDone = Standard_True; | |
274 | } | |
275 | ||
276 | //============================================================================= | |
277 | ||
278 | Extrema_ExtPElC2d::Extrema_ExtPElC2d (const gp_Pnt2d& P, | |
73cd8a8a | 279 | const gp_Parab2d& C, |
280 | const Standard_Real Tol, | |
281 | const Standard_Real Uinf, | |
282 | const Standard_Real Usup) | |
7fd59977 | 283 | { |
284 | Perform(P, C, Tol, Uinf, Usup); | |
285 | } | |
286 | ||
287 | ||
288 | void Extrema_ExtPElC2d::Perform(const gp_Pnt2d& P, | |
73cd8a8a | 289 | const gp_Parab2d& C, |
290 | const Standard_Real Tol, | |
291 | const Standard_Real Uinf, | |
292 | const Standard_Real Usup) | |
7fd59977 | 293 | { |
294 | myDone = Standard_False; | |
295 | myNbExt = 0; | |
296 | gp_Pnt2d O = C.Location(); | |
297 | ||
298 | Standard_Real Tol2 = Tol * Tol; | |
299 | Standard_Real F = C.Focal(); | |
300 | gp_Vec2d OPp (O,P); | |
7fd59977 | 301 | Standard_Real X = OPp.Dot(gp_Vec2d(C.MirrorAxis().Direction())); |
302 | Standard_Real Y = OPp.Dot(gp_Vec2d(C.Axis().YAxis().Direction())); | |
303 | ||
304 | math_DirectPolynomialRoots Sol(1./(4.*F),0.,2.*F-X,-2.*F*Y); | |
305 | if (!Sol.IsDone()) { return; } | |
306 | gp_Pnt2d Cu; | |
307 | Standard_Real Us; | |
308 | Standard_Integer NbSol = Sol.NbSolutions(); | |
309 | Standard_Boolean DejaEnr; | |
310 | Standard_Integer NoExt; | |
311 | gp_Pnt2d TbExt[3]; | |
312 | for (Standard_Integer NoSol = 1; NoSol <= NbSol; NoSol++) { | |
313 | Us = Sol.Value(NoSol); | |
314 | if ((Us >= Uinf) && (Us <= Usup)) { | |
315 | Cu = ElCLib::Value(Us,C); | |
316 | DejaEnr = Standard_False; | |
317 | for (NoExt = 0; NoExt < myNbExt; NoExt++) { | |
73cd8a8a | 318 | if (TbExt[NoExt].SquareDistance(Cu) < Tol2) { |
319 | DejaEnr = Standard_True; | |
320 | break; | |
321 | } | |
7fd59977 | 322 | } |
323 | if (!DejaEnr) { | |
73cd8a8a | 324 | TbExt[myNbExt] = Cu; |
325 | mySqDist[myNbExt] = Cu.SquareDistance(P); | |
326 | myIsMin[myNbExt] = (NoSol == 0); | |
327 | myPoint[myNbExt] = Extrema_POnCurv2d(Us,Cu); | |
328 | myNbExt++; | |
7fd59977 | 329 | } |
330 | } // if ((Us >= Uinf) && (Us <= Usup)) | |
331 | } // for (Standard_Integer NoSol = 1; ... | |
332 | myDone = Standard_True; | |
333 | } | |
334 | //============================================================================= | |
335 | ||
336 | Standard_Boolean Extrema_ExtPElC2d::IsDone () const { return myDone; } | |
337 | //============================================================================= | |
338 | ||
339 | Standard_Integer Extrema_ExtPElC2d::NbExt () const | |
340 | { | |
9775fa61 | 341 | if (!IsDone()) { throw StdFail_NotDone(); } |
7fd59977 | 342 | return myNbExt; |
343 | } | |
344 | //============================================================================= | |
345 | ||
346 | Standard_Real Extrema_ExtPElC2d::SquareDistance (const Standard_Integer N) const | |
347 | { | |
9775fa61 | 348 | if ((N < 1) || (N > NbExt())) { throw Standard_OutOfRange(); } |
7fd59977 | 349 | return mySqDist[N-1]; |
350 | } | |
351 | //============================================================================= | |
352 | ||
353 | Standard_Boolean Extrema_ExtPElC2d::IsMin (const Standard_Integer N) const | |
354 | { | |
9775fa61 | 355 | if ((N < 1) || (N > NbExt())) { throw Standard_OutOfRange(); } |
7fd59977 | 356 | return myIsMin[N-1]; |
357 | } | |
358 | //============================================================================= | |
359 | ||
5d99f2c8 | 360 | const Extrema_POnCurv2d& Extrema_ExtPElC2d::Point (const Standard_Integer N) const |
7fd59977 | 361 | { |
9775fa61 | 362 | if ((N < 1) || (N > NbExt())) { throw Standard_OutOfRange(); } |
7fd59977 | 363 | return myPoint[N-1]; |
364 | } | |
365 | //============================================================================= |