0023830: BRepExtrema_DistShapeShape does not find intersection of face with edge
[occt.git] / src / Extrema / Extrema_ExtElC2d.cxx
CommitLineData
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
37Extrema_ExtElC2d::Extrema_ExtElC2d () { myDone = Standard_False; }
38//=============================================================================
39
40Extrema_ExtElC2d::Extrema_ExtElC2d (const gp_Lin2d& C1,
41 const gp_Lin2d& C2,
42 const Standard_Real)
43/*-----------------------------------------------------------------------------
0d969553
Y
44Function:
45 Find min distance between 2 straight lines.
46
47Method:
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
74Extrema_ExtElC2d::Extrema_ExtElC2d (const gp_Lin2d& C1,
75 const gp_Circ2d& C2,
76 const Standard_Real)
77/*-----------------------------------------------------------------------------
0d969553
Y
78Function:
79 Find extreme distances between straight line C1 and circle C2.
80
81Method:
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// =============================================================================
138Extrema_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
191Extrema_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
227Extrema_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
260Extrema_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
306Extrema_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
335Extrema_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
364Extrema_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
393Extrema_ExtElC2d::Extrema_ExtElC2d (const gp_Elips2d&, const gp_Elips2d&)
394{
395 Standard_NotImplemented::Raise();
396}
397//============================================================================
398
399Extrema_ExtElC2d::Extrema_ExtElC2d (const gp_Elips2d&, const gp_Hypr2d&)
400{
401 Standard_NotImplemented::Raise();
402}
403//============================================================================
404
405Extrema_ExtElC2d::Extrema_ExtElC2d (const gp_Elips2d&, const gp_Parab2d&)
406{
407 Standard_NotImplemented::Raise();
408}
409//============================================================================
410
411Extrema_ExtElC2d::Extrema_ExtElC2d (const gp_Hypr2d&, const gp_Hypr2d&)
412{
413 Standard_NotImplemented::Raise();
414}
415//============================================================================
416
417Extrema_ExtElC2d::Extrema_ExtElC2d (const gp_Hypr2d&, const gp_Parab2d&)
418{
419 Standard_NotImplemented::Raise();
420}
421//============================================================================
422
423Extrema_ExtElC2d::Extrema_ExtElC2d (const gp_Parab2d&, const gp_Parab2d&)
424{
425 Standard_NotImplemented::Raise();
426}
427//============================================================================
428
429Standard_Boolean Extrema_ExtElC2d::IsDone () const { return myDone; }
430//============================================================================
431
432Standard_Boolean Extrema_ExtElC2d::IsParallel () const
433{
434 if (!IsDone()) { StdFail_NotDone::Raise(); }
435 return myIsPar;
436}
437//============================================================================
438
439Standard_Integer Extrema_ExtElC2d::NbExt () const
440{
441 if (IsParallel()) { StdFail_InfiniteSolutions::Raise(); }
442 return myNbExt;
443}
444//============================================================================
445
446Standard_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
455void 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//============================================================================