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