0022922: Clean up warnings on uninitialized / unused variables
[occt.git] / src / GccAna / GccAna_Circ2d2TanOn.cxx
1 // File GccAna_Circ2d2TanOn.cxx, REG 08/07/91
2
3 #include <GccAna_Circ2d2TanOn.ixx>
4
5 #include <TColStd_Array1OfReal.hxx>
6 #include <TColStd_SequenceOfReal.hxx>
7 #include <IntAna2d_AnaIntersection.hxx>
8 #include <IntAna2d_IntPoint.hxx>
9 #include <Standard_OutOfRange.hxx>
10 #include <ElCLib.hxx>
11 #include <gp_Dir2d.hxx>
12 #include <gp_Ax2d.hxx>
13 #include <GccInt_IType.hxx>
14 #include <GccInt_BCirc.hxx>
15 #include <GccInt_BLine.hxx>
16 #include <IntAna2d_Conic.hxx>
17 #include <StdFail_NotDone.hxx>
18 #include <GccEnt_BadQualifier.hxx>
19 #include <GccAna_Circ2dBisec.hxx>
20
21 //=========================================================================
22 //  Circles tangent to two circles C1 and C2 and centered on a straight line.   +
23 //  We start by distinguishing various boundary cases that will be processed separately. +
24 //  In the general case:                                                  +
25 //  ====================                                                  +
26 //  We calculate bissectrices to two circles that give us     +
27 //  all possible locations of centers of all circles tangent to C1 and C2.                                                  +
28 //  We intersect these bissectrices with straight line which gives us  +
29 //  points among which we are going to find solutions.   +
30 //  The choices are made basing on Qualifiers of C1 and C2.  +
31 //=========================================================================
32
33 GccAna_Circ2d2TanOn::
34    GccAna_Circ2d2TanOn (const GccEnt_QualifiedCirc&  Qualified1 , 
35                         const GccEnt_QualifiedCirc&  Qualified2 , 
36                         const gp_Lin2d&              OnLine     ,
37                         const Standard_Real          Tolerance  ):
38    cirsol(1,4)   ,
39    qualifier1(1,4),
40    qualifier2(1,4) ,
41    TheSame1(1,4) ,
42    TheSame2(1,4) ,
43    pnttg1sol(1,4),
44    pnttg2sol(1,4),
45    pntcen(1,4)   ,
46    par1sol(1,4)  ,
47    par2sol(1,4)  ,
48    pararg1(1,4)  ,
49    pararg2(1,4)  ,
50    parcen3(1,4)  
51 {
52
53   TheSame1.Init(0);
54   TheSame2.Init(0);
55   WellDone = Standard_False;
56   NbrSol = 0;
57   Standard_Integer nbsol = 0;
58   Standard_Real Tol = Abs(Tolerance);
59   if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() || 
60         Qualified1.IsOutside() || Qualified1.IsUnqualified()) ||
61       !(Qualified2.IsEnclosed() || Qualified2.IsEnclosing() || 
62         Qualified2.IsOutside() || Qualified2.IsUnqualified())) {
63    GccEnt_BadQualifier::Raise();
64      return;
65    }
66   gp_Circ2d C1 = Qualified1.Qualified();
67   gp_Circ2d C2 = Qualified2.Qualified();
68   Standard_Real R1 = C1.Radius();
69   Standard_Real R2 = C2.Radius();
70   gp_Dir2d dirx(1.,0.);
71   gp_Pnt2d center1(C1.Location());
72   gp_Pnt2d center2(C2.Location());
73   TColStd_Array1OfReal Radius(1,2);
74
75   Standard_Real dist1 = OnLine.Distance(center1);
76   Standard_Real dist2 = OnLine.Distance(center2);
77   Standard_Real d1 = dist1+R1;
78   Standard_Real d2 = dist2+R2;
79   Standard_Real d3 = dist1-R1;
80   Standard_Real d4 = dist2-R2;
81
82 //=========================================================================
83 //  Processing of boundary cases.                                           +
84 //=========================================================================
85    
86   if (Abs(d3-d4)<Tol && 
87       (Qualified1.IsEnclosed() || Qualified1.IsOutside() ||
88        Qualified1.IsUnqualified()) && 
89       (Qualified2.IsEnclosed() || Qualified2.IsOutside() ||
90        Qualified2.IsUnqualified())) {
91     nbsol++;
92     Radius(nbsol) = Abs(d3);
93     WellDone = Standard_True;
94   }
95   if (Abs(d1-d2)<Tol &&
96       (Qualified1.IsEnclosing() || Qualified1.IsUnqualified()) &&
97       (Qualified2.IsEnclosing() || Qualified2.IsUnqualified())){
98     nbsol++;
99     Radius(nbsol) = Abs(d1);
100     WellDone = Standard_True;
101   }
102   if (Abs(d1-d4)<Tol &&
103       (Qualified1.IsEnclosing() || Qualified1.IsUnqualified()) &&
104       (Qualified2.IsEnclosed() || Qualified2.IsOutside() ||
105        Qualified2.IsUnqualified())){
106     nbsol++;
107     Radius(nbsol) = Abs(d1);
108     WellDone = Standard_True;
109   }
110   if (Abs(d3-d2)<Tol &&
111       (Qualified2.IsEnclosing() || Qualified2.IsUnqualified()) &&
112       (Qualified1.IsEnclosed() || Qualified1.IsOutside() ||
113        Qualified1.IsUnqualified())){
114     nbsol++;
115     Radius(nbsol) = Abs(d3);
116     WellDone = Standard_True;
117   }
118   gp_Lin2d L(center1,gp_Dir2d(center2.XY()-center1.XY()));
119   IntAna2d_AnaIntersection Intp(OnLine,L);
120   if (Intp.IsDone()) {
121     if (!Intp.IsEmpty()){
122       for (Standard_Integer j = 1 ; j <= Intp.NbPoints() ; j++) {
123         gp_Pnt2d Center(Intp.Point(j).Value());
124         for (Standard_Integer i = 1 ; i <= nbsol ; i++) {
125           NbrSol++;
126           cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius(i));
127 //        ==========================================================
128           WellDone = Standard_True;
129           Standard_Real distcc1 = Center.Distance(center1);
130           Standard_Real distcc2 = Center.Distance(center2);
131           if (!Qualified1.IsUnqualified()) { 
132             qualifier1(NbrSol) = Qualified1.Qualifier();
133           }
134           else if (Abs(distcc1+Radius(i)-R1) < Tol) {
135             qualifier1(NbrSol) = GccEnt_enclosed;
136           }
137           else if (Abs(distcc1-R1-Radius(i)) < Tol) {
138             qualifier1(NbrSol) = GccEnt_outside;
139           }
140           else { qualifier1(NbrSol) = GccEnt_enclosing; }
141           if (!Qualified2.IsUnqualified()) { 
142             qualifier2(NbrSol) = Qualified2.Qualifier();
143           }
144           else if (Abs(distcc2+Radius(i)-R2) < Tol) {
145             qualifier2(NbrSol) = GccEnt_enclosed;
146           }
147           else if (Abs(distcc2-R2-Radius(i)) < Tol) {
148             qualifier2(NbrSol) = GccEnt_outside;
149           }
150           else { qualifier2(NbrSol) = GccEnt_enclosing; }
151           gp_Dir2d dc1(center1.XY()-Center.XY());
152           gp_Dir2d dc2(center2.XY()-Center.XY());
153           pnttg1sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius(i)*dc1.XY());
154           pnttg2sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius(i)*dc2.XY());
155           par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
156                                             pnttg1sol(NbrSol));
157           pararg1(NbrSol)=ElCLib::Parameter(C1,pnttg1sol(NbrSol));
158           par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
159                                             pnttg2sol(NbrSol));
160           pararg2(NbrSol)=ElCLib::Parameter(C2,pnttg2sol(NbrSol));
161           pntcen(NbrSol) = cirsol(NbrSol).Location();
162           parcen3(NbrSol)=ElCLib::Parameter(OnLine,pntcen(NbrSol));
163         }
164       }
165     }
166   }
167   
168 //=========================================================================
169 //   General case.                                                       +
170 //=========================================================================
171
172   if (!WellDone) {
173     GccAna_Circ2dBisec Bis(C1,C2);
174     if (Bis.IsDone()) {
175       TColStd_Array1OfReal Rbid(1,2);
176       TColStd_Array1OfReal RBid(1,2);
177       Standard_Integer nbsolution = Bis.NbSolutions();
178       for (Standard_Integer i = 1 ; i <=  nbsolution ; i++) {
179         Handle(GccInt_Bisec) Sol = Bis.ThisSolution(i);
180         GccInt_IType typ = Sol->ArcType();
181
182         if (typ == GccInt_Cir) {
183           Intp.Perform(OnLine,Sol->Circle());
184         }
185         else if (typ == GccInt_Lin) {
186           Intp.Perform(OnLine,Sol->Line());
187         }
188         else if (typ == GccInt_Hpr) {
189           Intp.Perform(OnLine,IntAna2d_Conic(Sol->Hyperbola()));
190         }
191         else if (typ == GccInt_Ell) {
192           Intp.Perform(OnLine,IntAna2d_Conic(Sol->Ellipse()));
193         }
194         if (Intp.IsDone()) {
195           if (!Intp.IsEmpty()){
196             for (Standard_Integer j = 1 ; j <= Intp.NbPoints() ; j++) {
197               gp_Pnt2d Center(Intp.Point(j).Value());
198               dist1 = Center.Distance(center1);
199               dist2 = Center.Distance(center2);
200               nbsol = 0;
201               Standard_Integer nsol = 0;
202               Standard_Integer nnsol = 0;
203               R1 = C1.Radius();
204               R2 = C2.Radius();
205               if (Qualified1.IsEnclosed()) {
206                 if (dist1-R1 < Tol) { 
207                   nbsol = 1;
208                   Rbid(1) = Abs(R1-dist1);
209                 }
210               }
211               else if (Qualified1.IsOutside()) {
212                 if (R1-dist1 < Tol) { 
213                   nbsol = 1;
214                   Rbid(1) = Abs(dist1-R1);
215                 }
216               }
217               else if (Qualified1.IsEnclosing()) {
218                 nbsol = 1;
219                 Rbid(1) = dist1+R1;
220               }
221               else if (Qualified1.IsUnqualified()) {
222                 nbsol = 2;
223                 Rbid(1) = dist1+R1;
224                 Rbid(1) = Abs(dist1-R1);
225               }
226               if (Qualified2.IsEnclosed() && nbsol != 0) {
227                 if (dist2-R2 < Tol) {
228                   nsol = 1;
229                   RBid(1) = Abs(R2-dist2);
230                 }
231               }
232               else if (Qualified2.IsOutside() && nbsol != 0) {
233                 if (R2-dist2 < Tol) {
234                   nsol = 1;
235                   RBid(1) = Abs(R2-dist2);
236                 }
237               }
238               else if (Qualified2.IsEnclosing() && nbsol != 0) {
239                 nsol = 1;
240                 RBid(1) = dist2+R2;
241               }
242               else if (Qualified2.IsUnqualified() && nbsol != 0) {
243                 nsol = 2;
244                 RBid(1) = dist2+R2;
245                 RBid(2) = Abs(R2-dist2);
246               }
247               for (Standard_Integer isol = 1; isol <= nbsol ; isol++) {
248                 for (Standard_Integer jsol = 1; jsol <= nsol ; jsol++) {
249                   if (Abs(Rbid(isol)-RBid(jsol)) <= Tol) {
250                     nnsol++;
251                     Radius(nnsol) = (RBid(jsol)+Rbid(isol))/2.;
252                   }
253                 }
254               }
255               if (nnsol > 0) {
256                 for (Standard_Integer k = 1 ; k <= nnsol ; k++) {
257                   NbrSol++;
258                   cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius(k));
259 //                ==========================================================
260                   Standard_Real distcc1 = Center.Distance(center1);
261                   Standard_Real distcc2 = Center.Distance(center2);
262                   if (!Qualified1.IsUnqualified()) { 
263                     qualifier1(NbrSol) = Qualified1.Qualifier();
264                   }
265                   else if (Abs(distcc1+Radius(i)-R1) < Tol) {
266                     qualifier1(NbrSol) = GccEnt_enclosed;
267                   }
268                   else if (Abs(distcc1-R1-Radius(i)) < Tol) {
269                     qualifier1(NbrSol) = GccEnt_outside;
270                   }
271                   else { qualifier1(NbrSol) = GccEnt_enclosing; }
272                   if (!Qualified2.IsUnqualified()) { 
273                     qualifier2(NbrSol) = Qualified2.Qualifier();
274                   }
275                   else if (Abs(distcc2+Radius(i)-R2) < Tol) {
276                     qualifier2(NbrSol) = GccEnt_enclosed;
277                   }
278                   else if (Abs(distcc2-R2-Radius(i)) < Tol) {
279                     qualifier2(NbrSol) = GccEnt_outside;
280                   }
281                   else { qualifier2(NbrSol) = GccEnt_enclosing; }
282                   if (Center.Distance(center1) <= Tol &&
283                       Abs(Radius(k)-C1.Radius()) <= Tol) {TheSame1(NbrSol)=1;}
284                   else {
285                     TheSame1(NbrSol) = 0;
286                     gp_Dir2d dc1(center1.XY()-Center.XY());
287                     pnttg1sol(NbrSol) = gp_Pnt2d(Center.XY()+
288                                                  Radius(k)*dc1.XY());
289                     par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
290                                                       pnttg1sol(NbrSol));
291                     pararg1(NbrSol)=ElCLib::Parameter(C1,pnttg2sol(NbrSol));
292                   }
293                   if (Center.Distance(center2) <= Tol &&
294                       Abs(Radius(k)-C2.Radius()) <= Tol) {TheSame2(NbrSol)=1;}
295                   else {
296                     TheSame2(NbrSol) = 0;
297                     gp_Dir2d dc2(center2.XY()-Center.XY());
298                     pnttg2sol(NbrSol) = gp_Pnt2d(Center.XY()+
299                                                  Radius(k)*dc2.XY());
300                     par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
301                                                       pnttg2sol(NbrSol));
302                     pararg2(NbrSol)=ElCLib::Parameter(C2,pnttg2sol(NbrSol));
303                   }
304                   pntcen(NbrSol) = Center;
305                   parcen3(NbrSol)=ElCLib::Parameter(OnLine,pntcen(NbrSol));
306                 }
307               }
308             }
309           }
310           WellDone = Standard_True;
311         }
312       }
313     }
314   }
315 }
316
317 //========================================================================
318
319 Standard_Boolean GccAna_Circ2d2TanOn::
320    IsDone () const{ return WellDone; }
321
322 Standard_Integer GccAna_Circ2d2TanOn::
323    NbSolutions () const{ return NbrSol; }
324
325 gp_Circ2d GccAna_Circ2d2TanOn::
326    ThisSolution (const Standard_Integer Index) const{ return cirsol(Index); }
327
328 void GccAna_Circ2d2TanOn::
329   WhichQualifier(const Standard_Integer Index   ,
330                        GccEnt_Position& Qualif1 ,
331                        GccEnt_Position& Qualif2 ) const
332 {
333   if (!WellDone) { StdFail_NotDone::Raise(); }
334    else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
335    else {
336      Qualif1 = qualifier1(Index);
337      Qualif2 = qualifier2(Index);
338    }
339 }
340
341 void GccAna_Circ2d2TanOn:: 
342    Tangency1 (const Standard_Integer    Index  , 
343                     Standard_Real&      ParSol ,
344                     Standard_Real&      ParArg ,
345                     gp_Pnt2d&  PntSol ) const{
346    if (!WellDone) { StdFail_NotDone::Raise(); }
347    else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
348    else {
349      if (TheSame1(Index) == 0) {
350        ParSol = par1sol(Index);
351        ParArg = pararg1(Index);
352        PntSol = gp_Pnt2d(pnttg1sol(Index));
353      }
354      else { StdFail_NotDone::Raise(); }
355    }
356  }
357
358 void GccAna_Circ2d2TanOn:: 
359    Tangency2 (const Standard_Integer    Index  , 
360                     Standard_Real&      ParSol ,
361                     Standard_Real&      ParArg ,
362                     gp_Pnt2d&  PntSol ) const{
363    if (!WellDone) { StdFail_NotDone::Raise(); }
364    else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
365    else {
366      if (TheSame2(Index) == 0) {
367        ParSol = par2sol(Index);
368        ParArg = pararg2(Index);
369        PntSol = gp_Pnt2d(pnttg2sol(Index));
370      }
371      else { StdFail_NotDone::Raise(); }
372    }
373  }
374
375 void GccAna_Circ2d2TanOn::
376    CenterOn3 (const Standard_Integer    Index  ,
377                     Standard_Real&      ParArg ,
378                     gp_Pnt2d&  PntSol ) const{
379    if (!WellDone) { StdFail_NotDone::Raise(); }
380    else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
381    else {
382      ParArg = parcen3(Index);
383      PntSol = pnttg1sol(Index);
384    }
385  }
386  
387 Standard_Boolean GccAna_Circ2d2TanOn::
388    IsTheSame1 (const Standard_Integer Index) const
389 {
390   if (!WellDone) { StdFail_NotDone::Raise(); }
391   else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
392
393   if (TheSame1(Index) == 0) { return Standard_False; }
394   return Standard_True;
395 }
396
397 Standard_Boolean GccAna_Circ2d2TanOn::
398    IsTheSame2 (const Standard_Integer Index) const
399 {
400   if (!WellDone) { StdFail_NotDone::Raise(); }
401   else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
402
403   if (TheSame2(Index) == 0) { return Standard_False; }
404   return Standard_True;
405 }