Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 1994-01-04 |
2 | // Created by: Christophe MARION | |
3 | // Copyright (c) 1994-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 | ||
23 | #include <Extrema_ExtElC2d.ixx> | |
24 | ||
25 | #include <StdFail_InfiniteSolutions.hxx> | |
26 | #include <StdFail_NotDone.hxx> | |
27 | #include <ElCLib.hxx> | |
28 | #include <math_TrigonometricFunctionRoots.hxx> | |
29 | #include <math_DirectPolynomialRoots.hxx> | |
30 | #include <Standard_OutOfRange.hxx> | |
31 | #include <Standard_NotImplemented.hxx> | |
32 | #include <Precision.hxx> | |
33 | #include <Extrema_ExtPElC2d.hxx> | |
34 | ||
35 | //============================================================================= | |
36 | ||
37 | Extrema_ExtElC2d::Extrema_ExtElC2d () { myDone = Standard_False; } | |
38 | //============================================================================= | |
39 | ||
40 | Extrema_ExtElC2d::Extrema_ExtElC2d (const gp_Lin2d& C1, | |
41 | const gp_Lin2d& C2, | |
42 | const Standard_Real) | |
43 | /*----------------------------------------------------------------------------- | |
0d969553 Y |
44 | Function: |
45 | Find min distance between 2 straight lines. | |
46 | ||
47 | Method: | |
48 | Let D1 and D2 be 2 directions of straight lines C1 and C2. | |
49 | 2 cases are considered: | |
50 | 1- if Angle(D1,D2) < AngTol, the straight lines are parallel. | |
51 | The distance is the distance between any point of C1 and straight line C2. | |
52 | 2- if Angle(D1,D2) > AngTol: | |
53 | Let P = C1(u1) and P =C2(u2) the point intersection: | |
7fd59977 | 54 | |
55 | -----------------------------------------------------------------------------*/ | |
56 | { | |
57 | myDone = Standard_False; | |
58 | myIsPar = Standard_False; | |
59 | myNbExt = 0; | |
60 | ||
61 | gp_Dir2d D1 = C1.Direction(); | |
62 | gp_Dir2d D2 = C2.Direction(); | |
63 | if (D1.IsParallel(D2, Precision::Angular())) { | |
64 | myIsPar = Standard_True; | |
65 | mySqDist[0] = C2.SquareDistance(C1.Location()); | |
66 | } | |
67 | else { | |
68 | myNbExt = 0; | |
69 | } | |
70 | myDone = Standard_True; | |
71 | } | |
72 | //============================================================================= | |
73 | ||
74 | Extrema_ExtElC2d::Extrema_ExtElC2d (const gp_Lin2d& C1, | |
75 | const gp_Circ2d& C2, | |
76 | const Standard_Real) | |
77 | /*----------------------------------------------------------------------------- | |
0d969553 Y |
78 | Function: |
79 | Find extreme distances between straight line C1 and circle C2. | |
80 | ||
81 | Method: | |
82 | Let P1=C1(u1) and P2=C2(u2) be two solution points | |
83 | D the direction of straight line C1 | |
84 | T the tangent at point P2; | |
85 | Then, ( P1P2.D = 0. (1) | |
7fd59977 | 86 | ( P1P2.T = 0. (2) |
87 | -----------------------------------------------------------------------------*/ | |
88 | { | |
89 | myIsPar = Standard_False; | |
90 | myDone = Standard_False; | |
91 | myNbExt = 0; | |
92 | ||
0d969553 | 93 | // Calculate T1 in the reference of the circle ... |
7fd59977 | 94 | gp_Dir2d D = C1.Direction(); |
95 | gp_Dir2d x2, y2; | |
96 | x2 = C2.XAxis().Direction(); | |
97 | y2 = C2.YAxis().Direction(); | |
98 | ||
99 | Standard_Real Dx = D.Dot(x2); | |
100 | Standard_Real Dy = D.Dot(y2); | |
101 | Standard_Real U1, teta[2]; | |
102 | gp_Pnt2d O1=C1.Location(); | |
103 | #ifdef DEB | |
104 | gp_Pnt2d O2= C2.Location(); | |
105 | gp_Pnt2d P1, P2; | |
106 | #else | |
107 | C2.Location(); | |
108 | gp_Pnt2d P1, P2; | |
109 | #endif | |
110 | ||
111 | if (Abs(Dy) <= RealEpsilon()) { | |
c6541a0c | 112 | teta[0] = M_PI/2.0; |
7fd59977 | 113 | } |
114 | else teta[0] = ATan(-Dx/Dy); | |
c6541a0c D |
115 | teta[1] = teta[0]+ M_PI; |
116 | if (teta[0] < 0.0) teta[0] = teta[0] + 2.0*M_PI; | |
7fd59977 | 117 | |
118 | P2 = ElCLib::Value(teta[0], C2); | |
119 | U1 = (gp_Vec2d(O1, P2)).Dot(D); | |
120 | P1 = ElCLib::Value(U1, C1); | |
121 | mySqDist[myNbExt] = P1.SquareDistance(P2); | |
122 | myPoint[myNbExt][0] = Extrema_POnCurv2d(U1,P1); | |
123 | myPoint[myNbExt][1] = Extrema_POnCurv2d(teta[0],P2); | |
124 | myNbExt++; | |
125 | ||
126 | P2 = ElCLib::Value(teta[1], C2); | |
127 | U1 = (gp_Vec2d(O1, P2)).Dot(D); | |
128 | P1 = ElCLib::Value(U1, C1); | |
129 | mySqDist[myNbExt] = P1.SquareDistance(P2); | |
130 | myPoint[myNbExt][0] = Extrema_POnCurv2d(U1,P1); | |
131 | myPoint[myNbExt][1] = Extrema_POnCurv2d(teta[1],P2); | |
132 | myNbExt++; | |
133 | myDone = Standard_True; | |
134 | } | |
135 | ||
136 | ||
137 | // ============================================================================= | |
138 | Extrema_ExtElC2d::Extrema_ExtElC2d (const gp_Lin2d& C1, | |
139 | const gp_Elips2d& C2) | |
140 | { | |
141 | myDone = Standard_True; | |
142 | myIsPar = Standard_False; | |
143 | myDone = Standard_False; | |
144 | myNbExt = 0; | |
145 | ||
0d969553 | 146 | // Calculate T1 in the reference of the ellipse ... |
7fd59977 | 147 | gp_Dir2d D = C1.Direction(); |
148 | gp_Dir2d x2, y2; | |
149 | x2 = C2.XAxis().Direction(); | |
150 | y2 = C2.YAxis().Direction(); | |
151 | ||
152 | Standard_Real Dx = D.Dot(x2); | |
153 | Standard_Real Dy = D.Dot(y2); | |
154 | Standard_Real U1, teta[2], r1 = C2.MajorRadius(), r2 = C2.MinorRadius(); | |
155 | #ifdef DEB | |
156 | gp_Pnt2d O1=C1.Location(), O2= C2.Location(), P1, P2; | |
157 | #else | |
158 | gp_Pnt2d O1=C1.Location(), P1, P2; | |
159 | #endif | |
160 | ||
161 | if (Abs(Dy) <= RealEpsilon()) { | |
c6541a0c | 162 | teta[0] = M_PI/2.0; |
7fd59977 | 163 | } |
164 | else teta[0] = ATan(-Dx*r2/(Dy*r1)); | |
165 | ||
c6541a0c D |
166 | teta[1] = teta[0] + M_PI; |
167 | if (teta[0] < 0.0) teta[0] += 2.0*M_PI; | |
7fd59977 | 168 | P2 = ElCLib::Value(teta[0], C2); |
169 | U1 = (gp_Vec2d(O1, P2)).Dot(D); | |
170 | P1 = ElCLib::Value(U1, C1); | |
171 | mySqDist[myNbExt] = P1.SquareDistance(P2); | |
172 | myPoint[myNbExt][0] = Extrema_POnCurv2d(U1,P1); | |
173 | myPoint[myNbExt][1] = Extrema_POnCurv2d(teta[0],P2); | |
174 | myNbExt++; | |
175 | ||
176 | ||
177 | P2 = ElCLib::Value(teta[1], C2); | |
178 | U1 = (gp_Vec2d(O1, P2)).Dot(D); | |
179 | P1 = ElCLib::Value(U1, C1); | |
180 | mySqDist[myNbExt] = P1.SquareDistance(P2); | |
181 | myPoint[myNbExt][0] = Extrema_POnCurv2d(U1,P1); | |
182 | myPoint[myNbExt][1] = Extrema_POnCurv2d(teta[1],P2); | |
183 | myNbExt++; | |
184 | myDone = Standard_True; | |
185 | } | |
186 | ||
187 | ||
188 | ||
189 | //============================================================================= | |
190 | ||
191 | Extrema_ExtElC2d::Extrema_ExtElC2d (const gp_Lin2d& C1, const gp_Hypr2d& C2) | |
192 | { | |
193 | myIsPar = Standard_False; | |
194 | myDone = Standard_False; | |
195 | myNbExt = 0; | |
196 | ||
0d969553 | 197 | // Calculate T1 in the reference of the parabole ... |
7fd59977 | 198 | gp_Dir2d D = C1.Direction(); |
199 | gp_Dir2d x2, y2; | |
200 | x2 = C2.XAxis().Direction(); | |
201 | y2 = C2.YAxis().Direction(); | |
202 | Standard_Real Dx = D.Dot(x2); | |
203 | Standard_Real Dy = D.Dot(y2); | |
204 | ||
205 | Standard_Real U1, v2, U2=0, R = C2.MajorRadius(), r = C2.MinorRadius(); | |
206 | gp_Pnt2d P1, P2; | |
207 | if (Abs(Dy) < RealEpsilon()) { return;} | |
208 | if (Abs(R - r*Dx/Dy) < RealEpsilon()) return; | |
209 | ||
210 | v2 = (R + r*Dx/Dy)/(R - r*Dx/Dy); | |
211 | if (v2 > 0.0) U2 = Log(Sqrt(v2)); | |
212 | P2 = ElCLib::Value(U2, C2); | |
213 | ||
214 | U1 = (gp_Vec2d(C1.Location(), P2)).Dot(D); | |
215 | P1 = ElCLib::Value(U1, C1); | |
216 | mySqDist[myNbExt] = P1.SquareDistance(P2); | |
217 | myPoint[myNbExt][0] = Extrema_POnCurv2d(U1,P1); | |
218 | myPoint[myNbExt][1] = Extrema_POnCurv2d(U2,P2); | |
219 | myNbExt++; | |
220 | myDone = Standard_True; | |
221 | } | |
222 | ||
223 | ||
224 | ||
225 | //============================================================================ | |
226 | ||
227 | Extrema_ExtElC2d::Extrema_ExtElC2d (const gp_Lin2d& C1, const gp_Parab2d& C2) | |
228 | { | |
229 | myIsPar = Standard_False; | |
230 | myDone = Standard_False; | |
231 | myNbExt = 0; | |
232 | ||
0d969553 | 233 | // Calculate T1 in the reference of the parabole ... |
7fd59977 | 234 | gp_Dir2d D = C1.Direction(); |
235 | gp_Dir2d x2, y2; | |
236 | x2 = C2.MirrorAxis().Direction(); | |
237 | y2 = C2.Axis().YAxis().Direction(); | |
238 | Standard_Real Dx = D.Dot(x2); | |
239 | Standard_Real Dy = D.Dot(y2); | |
240 | ||
241 | Standard_Real U1, U2, P = C2.Parameter(); | |
242 | gp_Pnt2d P1, P2; | |
243 | if (Abs(Dy) < RealEpsilon()) { return; } | |
244 | U2 = Dx*P/Dy; | |
245 | P2 = ElCLib::Value(U2, C2); | |
246 | ||
247 | U1 = (gp_Vec2d(C1.Location(), P2)).Dot(D); | |
248 | P1 = ElCLib::Value(U1, C1); | |
249 | mySqDist[myNbExt] = P1.SquareDistance(P2); | |
250 | myPoint[myNbExt][0] = Extrema_POnCurv2d(U1,P1); | |
251 | myPoint[myNbExt][1] = Extrema_POnCurv2d(U2,P2); | |
252 | myNbExt++; | |
253 | myDone = Standard_True; | |
254 | } | |
255 | ||
256 | ||
257 | ||
258 | //============================================================================ | |
259 | ||
260 | Extrema_ExtElC2d::Extrema_ExtElC2d (const gp_Circ2d& C1, const gp_Circ2d& C2) | |
261 | { | |
262 | myIsPar = Standard_False; | |
263 | myDone = Standard_False; | |
264 | myNbExt = 0; | |
265 | myDone = Standard_True; | |
266 | ||
267 | gp_Pnt2d O1 = C1.Location(); | |
268 | gp_Pnt2d O2 = C2.Location(); | |
269 | ||
270 | gp_Vec2d DO1O2 (O1, O2); | |
271 | if (DO1O2.Magnitude() < Precision::Confusion()) { | |
272 | myIsPar = Standard_True; | |
273 | return; | |
274 | } | |
275 | ||
276 | Standard_Integer NoSol, kk; | |
277 | Standard_Real U1, U2; | |
278 | Standard_Real r1 = C1.Radius(), r2 = C2.Radius(); | |
279 | Standard_Real Usol2[2], Usol1[2]; | |
280 | gp_Pnt2d P1[2], P2[2]; | |
281 | gp_Dir2d O1O2(DO1O2); | |
282 | ||
283 | P1[0] = O1.Translated(r1*O1O2); | |
284 | Usol1[0] = ElCLib::Parameter(C1, P1[0]); | |
285 | P1[1] = O1.Translated(-r1*O1O2); | |
286 | Usol1[1] = ElCLib::Parameter(C1, P1[1]); | |
287 | ||
288 | P2[0] = O2.Translated(r2*O1O2); | |
289 | Usol2[0] = ElCLib::Parameter(C2, P2[0]); | |
290 | P2[1] = O2.Translated(-r2*O1O2); | |
291 | Usol2[1] = ElCLib::Parameter(C2, P2[1]); | |
292 | ||
293 | for (NoSol = 0; NoSol <= 1; NoSol++) { | |
294 | U1 = Usol1[NoSol]; | |
295 | for (kk = 0; kk <= 1; kk++) { | |
296 | U2 = Usol2[kk]; | |
297 | mySqDist[myNbExt] = P2[kk].SquareDistance(P1[NoSol]); | |
298 | myPoint[myNbExt][0] = Extrema_POnCurv2d(U1, P1[NoSol]); | |
299 | myPoint[myNbExt][1] = Extrema_POnCurv2d(U2, P2[kk]); | |
300 | myNbExt++; | |
301 | } | |
302 | } | |
303 | } | |
304 | //=========================================================================== | |
305 | ||
306 | Extrema_ExtElC2d::Extrema_ExtElC2d (const gp_Circ2d& C1, const gp_Elips2d& C2) | |
307 | { | |
308 | myIsPar = Standard_False; | |
309 | myDone = Standard_False; | |
310 | myNbExt = 0; | |
311 | ||
312 | Standard_Integer i, j; | |
313 | ||
314 | Extrema_ExtPElC2d ExtElip(C1.Location(), C2, | |
c6541a0c | 315 | Precision::Confusion(), 0.0, 2.0*M_PI); |
7fd59977 | 316 | |
317 | if (ExtElip.IsDone()) { | |
318 | for (i = 1; i <= ExtElip.NbExt(); i++) { | |
319 | Extrema_ExtPElC2d ExtCirc(ExtElip.Point(i).Value(), C1, | |
c6541a0c | 320 | Precision::Confusion(), 0.0, 2.0*M_PI); |
7fd59977 | 321 | if (ExtCirc.IsDone()) { |
322 | for (j = 1; j <= ExtCirc.NbExt(); j++) { | |
323 | mySqDist[myNbExt] = ExtCirc.SquareDistance(j); | |
324 | myPoint[myNbExt][0] = ExtCirc.Point(j); | |
325 | myPoint[myNbExt][1] = ExtElip.Point(i); | |
326 | myNbExt++; | |
327 | } | |
328 | } | |
329 | myDone = Standard_True; | |
330 | } | |
331 | } | |
332 | } | |
333 | //============================================================================ | |
334 | ||
335 | Extrema_ExtElC2d::Extrema_ExtElC2d (const gp_Circ2d& C1, const gp_Hypr2d& C2) | |
336 | { | |
337 | myIsPar = Standard_False; | |
338 | myDone = Standard_False; | |
339 | myNbExt = 0; | |
340 | ||
341 | Standard_Integer i, j; | |
342 | ||
343 | Extrema_ExtPElC2d ExtHyp(C1.Location(), C2, Precision::Confusion(), | |
344 | RealFirst(), RealLast()); | |
345 | ||
346 | if (ExtHyp.IsDone()) { | |
347 | for (i = 1; i <= ExtHyp.NbExt(); i++) { | |
348 | Extrema_ExtPElC2d ExtCirc(ExtHyp.Point(i).Value(), C1, | |
c6541a0c | 349 | Precision::Confusion(), 0.0, 2.0*M_PI); |
7fd59977 | 350 | if (ExtCirc.IsDone()) { |
351 | for (j = 1; j <= ExtCirc.NbExt(); j++) { | |
352 | mySqDist[myNbExt] = ExtCirc.SquareDistance(j); | |
353 | myPoint[myNbExt][0] = ExtCirc.Point(j); | |
354 | myPoint[myNbExt][1] = ExtHyp.Point(i); | |
355 | myNbExt++; | |
356 | } | |
357 | } | |
358 | myDone = Standard_True; | |
359 | } | |
360 | } | |
361 | } | |
362 | //============================================================================ | |
363 | ||
364 | Extrema_ExtElC2d::Extrema_ExtElC2d (const gp_Circ2d& C1, const gp_Parab2d& C2) | |
365 | { | |
366 | myIsPar = Standard_False; | |
367 | myDone = Standard_False; | |
368 | myNbExt = 0; | |
369 | ||
370 | Standard_Integer i, j; | |
371 | ||
372 | Extrema_ExtPElC2d ExtParab(C1.Location(), C2, Precision::Confusion(), | |
373 | RealFirst(), RealLast()); | |
374 | ||
375 | if (ExtParab.IsDone()) { | |
376 | for (i = 1; i <= ExtParab.NbExt(); i++) { | |
377 | Extrema_ExtPElC2d ExtCirc(ExtParab.Point(i).Value(), | |
c6541a0c | 378 | C1, Precision::Confusion(), 0.0, 2.0*M_PI); |
7fd59977 | 379 | if (ExtCirc.IsDone()) { |
380 | for (j = 1; j <= ExtCirc.NbExt(); j++) { | |
381 | mySqDist[myNbExt] = ExtCirc.SquareDistance(j); | |
382 | myPoint[myNbExt][0] = ExtCirc.Point(j); | |
383 | myPoint[myNbExt][1] = ExtParab.Point(i); | |
384 | myNbExt++; | |
385 | } | |
386 | } | |
387 | myDone = Standard_True; | |
388 | } | |
389 | } | |
390 | } | |
391 | //============================================================================ | |
392 | ||
393 | Extrema_ExtElC2d::Extrema_ExtElC2d (const gp_Elips2d&, const gp_Elips2d&) | |
394 | { | |
395 | Standard_NotImplemented::Raise(); | |
396 | } | |
397 | //============================================================================ | |
398 | ||
399 | Extrema_ExtElC2d::Extrema_ExtElC2d (const gp_Elips2d&, const gp_Hypr2d&) | |
400 | { | |
401 | Standard_NotImplemented::Raise(); | |
402 | } | |
403 | //============================================================================ | |
404 | ||
405 | Extrema_ExtElC2d::Extrema_ExtElC2d (const gp_Elips2d&, const gp_Parab2d&) | |
406 | { | |
407 | Standard_NotImplemented::Raise(); | |
408 | } | |
409 | //============================================================================ | |
410 | ||
411 | Extrema_ExtElC2d::Extrema_ExtElC2d (const gp_Hypr2d&, const gp_Hypr2d&) | |
412 | { | |
413 | Standard_NotImplemented::Raise(); | |
414 | } | |
415 | //============================================================================ | |
416 | ||
417 | Extrema_ExtElC2d::Extrema_ExtElC2d (const gp_Hypr2d&, const gp_Parab2d&) | |
418 | { | |
419 | Standard_NotImplemented::Raise(); | |
420 | } | |
421 | //============================================================================ | |
422 | ||
423 | Extrema_ExtElC2d::Extrema_ExtElC2d (const gp_Parab2d&, const gp_Parab2d&) | |
424 | { | |
425 | Standard_NotImplemented::Raise(); | |
426 | } | |
427 | //============================================================================ | |
428 | ||
429 | Standard_Boolean Extrema_ExtElC2d::IsDone () const { return myDone; } | |
430 | //============================================================================ | |
431 | ||
432 | Standard_Boolean Extrema_ExtElC2d::IsParallel () const | |
433 | { | |
434 | if (!IsDone()) { StdFail_NotDone::Raise(); } | |
435 | return myIsPar; | |
436 | } | |
437 | //============================================================================ | |
438 | ||
439 | Standard_Integer Extrema_ExtElC2d::NbExt () const | |
440 | { | |
441 | if (IsParallel()) { StdFail_InfiniteSolutions::Raise(); } | |
442 | return myNbExt; | |
443 | } | |
444 | //============================================================================ | |
445 | ||
446 | Standard_Real Extrema_ExtElC2d::SquareDistance (const Standard_Integer N) const | |
447 | { | |
448 | if (!(N == 1 && myDone)) { | |
449 | if (N < 1 || N > NbExt()) { Standard_OutOfRange::Raise(); } | |
450 | } | |
451 | return mySqDist[N-1]; | |
452 | } | |
453 | //============================================================================ | |
454 | ||
455 | void Extrema_ExtElC2d::Points (const Standard_Integer N, | |
456 | Extrema_POnCurv2d& P1, | |
457 | Extrema_POnCurv2d& P2) const | |
458 | { | |
459 | if (N < 1 || N > NbExt()) { Standard_OutOfRange::Raise(); } | |
460 | P1 = myPoint[N-1][0]; | |
461 | P2 = myPoint[N-1][1]; | |
462 | } | |
463 | //============================================================================ |