0024510: Remove unused local variables
[occt.git] / src / GccAna / GccAna_Circ2d3Tan_4.cxx
1 // Copyright (c) 1995-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and / or modify it
7 // under the terms of the GNU Lesser General Public version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15 // cas de 2 cercles concentriques JCT 28/11/97
16
17 #include <ElCLib.hxx>
18 #include <GccAna_Circ2d3Tan.jxx>
19 #include <IntAna2d_AnaIntersection.hxx>
20 #include <IntAna2d_IntPoint.hxx>
21 #include <gp_Lin2d.hxx>
22 #include <gp_Circ2d.hxx>
23 #include <gp_Dir2d.hxx>
24 #include <TColStd_Array1OfReal.hxx>
25 #include <GccAna_Circ2dBisec.hxx>
26 #include <GccAna_CircPnt2dBisec.hxx>
27 #include <GccInt_IType.hxx>
28 #include <GccInt_BCirc.hxx>
29 #include <GccInt_BLine.hxx>
30 #include <GccInt_BElips.hxx>
31 #include <GccInt_BHyper.hxx>
32 #include <IntAna2d_Conic.hxx>
33 #include <GccEnt_BadQualifier.hxx>
34
35 static Standard_Integer MaxSol = 20;
36 //=========================================================================
37 //   Creation of a circle tangent to two circles and a point.           +
38 //=========================================================================
39
40 GccAna_Circ2d3Tan::
41    GccAna_Circ2d3Tan (const GccEnt_QualifiedCirc& Qualified1 ,
42                       const GccEnt_QualifiedCirc& Qualified2 ,
43                       const gp_Pnt2d&             Point3     ,
44                       const Standard_Real         Tolerance  ):
45
46 //=========================================================================
47 //   Initialization of fields.                                           +
48 //=========================================================================
49
50    cirsol(1,MaxSol)     ,
51    qualifier1(1,MaxSol) ,
52    qualifier2(1,MaxSol) ,
53    qualifier3(1,MaxSol) ,
54    TheSame1(1,MaxSol)   ,
55    TheSame2(1,MaxSol)   ,
56    TheSame3(1,MaxSol)   ,
57    pnttg1sol(1,MaxSol)  ,
58    pnttg2sol(1,MaxSol)  ,
59    pnttg3sol(1,MaxSol)  ,
60    par1sol(1,MaxSol)    ,
61    par2sol(1,MaxSol)    ,
62    par3sol(1,MaxSol)    ,
63    pararg1(1,MaxSol)    ,
64    pararg2(1,MaxSol)    ,
65    pararg3(1,MaxSol)    
66 {
67
68    gp_Dir2d dirx(1.0,0.0);
69    Standard_Real Tol = Abs(Tolerance);
70    WellDone = Standard_False;
71    NbrSol = 0;
72    if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() || 
73          Qualified1.IsOutside() || Qualified1.IsUnqualified()) ||
74        !(Qualified2.IsEnclosed() || Qualified2.IsEnclosing() || 
75          Qualified2.IsOutside() || Qualified2.IsUnqualified())) {
76      GccEnt_BadQualifier::Raise();
77      return;
78    }
79
80 //=========================================================================
81 //   Processing.                                                          +
82 //=========================================================================
83
84    gp_Circ2d C1(Qualified1.Qualified());
85    gp_Circ2d C2(Qualified2.Qualified());
86    Standard_Real R1 = C1.Radius();
87    Standard_Real R2 = C2.Radius();
88    gp_Pnt2d center1(C1.Location());
89    gp_Pnt2d center2(C2.Location());
90
91    TColStd_Array1OfReal Radius(1,2);
92    GccAna_Circ2dBisec Bis1(C1,C2);
93    GccAna_CircPnt2dBisec Bis2(C1,Point3);
94    if (Bis1.IsDone() && Bis2.IsDone()) {
95      Standard_Integer nbsolution1 = Bis1.NbSolutions();
96      Standard_Integer nbsolution2 = Bis2.NbSolutions();
97      for (Standard_Integer i = 1 ; i <=  nbsolution1; i++) {
98        Handle(GccInt_Bisec) Sol1 = Bis1.ThisSolution(i);
99        GccInt_IType typ1 = Sol1->ArcType();
100        IntAna2d_AnaIntersection Intp;
101        for (Standard_Integer k = 1 ; k <=  nbsolution2; k++) {
102          Handle(GccInt_Bisec) Sol2 = Bis2.ThisSolution(k);
103          GccInt_IType typ2 = Sol2->ArcType();
104          if (typ1 == GccInt_Cir) {
105            if (typ2 == GccInt_Cir) {
106              Intp.Perform(Sol1->Circle(),Sol2->Circle());
107            }
108            else if (typ2 == GccInt_Lin) {
109              Intp.Perform(Sol2->Line(),Sol1->Circle());
110            }
111            else if (typ2 == GccInt_Hpr) {
112              Intp.Perform(Sol1->Circle(),IntAna2d_Conic(Sol2->Hyperbola()));
113            }
114            else if (typ2 == GccInt_Ell) {
115              Intp.Perform(Sol1->Circle(),IntAna2d_Conic(Sol2->Ellipse()));
116            }
117          }
118          else if (typ1 == GccInt_Ell) {
119            if (typ2 == GccInt_Cir) {
120              Intp.Perform(Sol2->Circle(),IntAna2d_Conic(Sol1->Ellipse()));
121            }
122            else if (typ2 == GccInt_Lin) {
123              Intp.Perform(Sol2->Line(),IntAna2d_Conic(Sol1->Ellipse()));
124            }
125            else if (typ2 == GccInt_Hpr) {
126              Intp.Perform(Sol1->Ellipse(),IntAna2d_Conic(Sol2->Hyperbola()));
127            }
128            else if (typ2 == GccInt_Ell) {
129              Intp.Perform(Sol1->Ellipse(),IntAna2d_Conic(Sol2->Ellipse()));
130            }
131          }
132          else if (typ1 == GccInt_Lin) {
133            if (typ2 == GccInt_Cir) {
134              Intp.Perform(Sol1->Line(),Sol2->Circle());
135            }
136            else if (typ2 == GccInt_Lin) {
137              Intp.Perform(Sol1->Line(),Sol2->Line());
138            }
139            else if (typ2 == GccInt_Hpr) {
140              Intp.Perform(Sol1->Line(),IntAna2d_Conic(Sol2->Hyperbola()));
141            }
142            else if (typ2 == GccInt_Ell) {
143              Intp.Perform(Sol1->Line(),IntAna2d_Conic(Sol2->Ellipse()));
144            }
145          }
146          else if (typ1 == GccInt_Hpr) {
147            if (typ2 == GccInt_Cir) {
148              Intp.Perform(Sol2->Circle(),IntAna2d_Conic(Sol1->Hyperbola()));
149            }
150            else if (typ2 == GccInt_Lin) {
151              Intp.Perform(Sol2->Line(),IntAna2d_Conic(Sol1->Hyperbola()));
152            }
153            else if (typ2 == GccInt_Hpr) {
154              Intp.Perform(Sol2->Hyperbola(),IntAna2d_Conic(Sol1->Hyperbola()));
155            }
156            else if (typ2 == GccInt_Ell) {
157              Intp.Perform(Sol2->Ellipse(),IntAna2d_Conic(Sol1->Hyperbola()));
158            }
159          }
160          if (Intp.IsDone()) {
161            if (!Intp.IsEmpty()) {
162              for (Standard_Integer j = 1 ; j <= Intp.NbPoints() ; j++) {
163                Standard_Real Rradius=0;
164                gp_Pnt2d Center(Intp.Point(j).Value());
165                Standard_Real dist1 = Center.Distance(center1);
166                Standard_Real dist2 = Center.Distance(center2);
167                Standard_Real dist3 = Center.Distance(Point3);
168                Standard_Integer nbsol1 = 0;
169                Standard_Integer nbsol2 = 0;
170                Standard_Integer nbsol3 = 0;
171                Standard_Boolean ok = Standard_False;
172                if (Qualified1.IsEnclosed()) {
173                  if (dist1-R1 < Tolerance) {
174                    Radius(1) = Abs(R1-dist1);
175                    nbsol1 = 1;
176                    ok = Standard_True;
177                  }
178                }
179                else if (Qualified1.IsOutside()) {
180                  if (R1-dist1 < Tolerance) {
181                    Radius(1) = Abs(R1-dist1);
182                    nbsol1 = 1;
183                    ok = Standard_True;
184                  }
185                }
186                else if (Qualified1.IsEnclosing()) {
187                  ok = Standard_True;
188                  nbsol1 = 1;
189                  Radius(1) = R1+dist1;
190                }
191                else if (Qualified1.IsUnqualified()) {
192                  ok = Standard_True;
193                  nbsol1 = 2;
194                  Radius(1) = Abs(R1-dist1);
195                  Radius(2) = R1+dist1;
196                }
197                if (Qualified2.IsEnclosed() && ok) {
198                  if (dist2-R2 < Tolerance) {
199                    for (Standard_Integer ii = 1 ; ii <= nbsol1 ; ii++) {
200                      if (Abs(Radius(ii)-Abs(R2-dist2)) < Tol) {
201                        Radius(1) = Abs(R2-dist2);
202                        ok = Standard_True;
203                        nbsol2 = 1;
204                      }
205                    }
206                  }
207                }
208                else if (Qualified2.IsOutside() && ok) {
209                  if (R2-dist2 < Tolerance) {
210                    for (Standard_Integer ii = 1 ; ii <= nbsol1 ; ii++) {
211                      if (Abs(Radius(ii)-Abs(R2-dist2)) < Tol) {
212                        Radius(1) = Abs(R2-dist2);
213                        ok = Standard_True;
214                        nbsol2 = 1;
215                      }
216                    }
217                  }
218                }
219                else if (Qualified2.IsEnclosing() && ok) {
220                  for (Standard_Integer ii = 1 ; ii <= nbsol1 ; ii++) {
221                    if (Abs(Radius(ii)-R2-dist2) < Tol) {
222                      Radius(1) = R2+dist2;
223                      ok = Standard_True;
224                      nbsol2 = 1;
225                    }
226                  }
227                }
228                else if (Qualified2.IsUnqualified() && ok) {
229                  for (Standard_Integer ii = 1 ; ii <= nbsol1 ; ii++) {
230                    if (Abs(Radius(ii)-Abs(R2-dist2)) < Tol) {
231                      Rradius = Abs(R2-dist2);
232                      ok = Standard_True;
233                      nbsol2++;
234                    }
235                    else if (Abs(Radius(ii)-R2-dist2) < Tol) {
236                      Rradius = R2+dist2;
237                      ok = Standard_True;
238                      nbsol2++;
239                    }
240                  }
241                  if (nbsol2 == 1) {
242                    Radius(1) = Rradius;
243                  }
244                  else if (nbsol2 == 2) {
245                    Radius(1) = Abs(R2-dist2);
246                    Radius(2) = R2+dist2;
247                  }
248                }
249                for (Standard_Integer ii = 1 ; ii <= nbsol2 ; ii++) {
250                  if (Abs(dist3-Radius(ii)) <= Tol) {
251                    nbsol3++;
252                    ok = Standard_True;
253                  }
254                }
255                if (ok) {
256                  for (Standard_Integer k1 = 1 ; k1 <= nbsol3 ; k1++) {
257                    NbrSol++;
258                    cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius(k1));
259 //                 ==========================================================
260                    Standard_Real distcc1 = Center.Distance(center1);
261                    if (!Qualified1.IsUnqualified()) { 
262                      qualifier1(NbrSol) = Qualified1.Qualifier();
263                    }
264                    else if (Abs(distcc1+Radius(k1)-R1) < Tol) {
265                      qualifier1(NbrSol) = GccEnt_enclosed;
266                    }
267                    else if (Abs(distcc1-R1-Radius(k1)) < Tol) {
268                      qualifier1(NbrSol) = GccEnt_outside;
269                    }
270                    else { qualifier1(NbrSol) = GccEnt_enclosing; }
271
272 //                 Standard_Real distcc2 = Center.Distance(center1);
273                    Standard_Real distcc2 = Center.Distance(center2);
274                    if (!Qualified2.IsUnqualified()) { 
275                      qualifier2(NbrSol) = Qualified2.Qualifier();
276                    }
277                    else if (Abs(distcc2+Radius(k1)-R2) < Tol) {
278                      qualifier2(NbrSol) = GccEnt_enclosed;
279                    }
280                    else if (Abs(distcc2-R2-Radius(k1)) < Tol) {
281                      qualifier2(NbrSol) = GccEnt_outside;
282                    }
283                    else { qualifier2(NbrSol) = GccEnt_enclosing; }
284                    qualifier3(NbrSol) = GccEnt_noqualifier;
285                    if (Center.Distance(center1) <= Tolerance &&
286                        Abs(Radius(k1)-R1) <= Tolerance) {
287                      TheSame1(NbrSol) = 1;
288                    }
289                    else {
290                      TheSame1(NbrSol) = 0;
291                      gp_Dir2d dc(center1.XY()-Center.XY());
292                      pnttg1sol(NbrSol)=gp_Pnt2d(Center.XY()+Radius(k1)*dc.XY());
293                      par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
294                                                       pnttg1sol(NbrSol));
295                      pararg1(NbrSol)=ElCLib::Parameter(C1,
296                                                       pnttg1sol(NbrSol));
297                    }
298                    if (Center.Distance(center2) <= Tolerance &&
299                        Abs(Radius(k1)-R2) <= Tolerance) {
300                      TheSame2(NbrSol) = 1;
301                    }
302                    else {
303                      TheSame2(NbrSol) = 0;
304                      gp_Dir2d dc(center2.XY()-Center.XY());
305                      // case of concentric circles : 
306                      // 2nd tangency point is at the other side of the circle solution
307                      Standard_Real alpha = 1.;
308                      if (center1.Distance(center2)<=Tolerance) alpha = -1;
309                      pnttg2sol(NbrSol)=gp_Pnt2d(Center.XY()+alpha*Radius(k1)*dc.XY());
310                      par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
311                                                       pnttg2sol(NbrSol));
312                      pararg2(NbrSol)=ElCLib::Parameter(C2,pnttg2sol(NbrSol));
313                    }
314                    TheSame3(NbrSol) = 0;
315                    pnttg3sol(NbrSol) = Point3;
316                    par3sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
317                                                     pnttg3sol(NbrSol));
318                    pararg3(NbrSol) = 0.;
319                    WellDone = Standard_True;
320                    if (NbrSol==MaxSol) break;
321                  }
322                }
323              }
324            }
325            WellDone = Standard_True;
326            if (NbrSol==MaxSol) break;
327          }
328          if (NbrSol==MaxSol) break;
329        }
330        if (NbrSol==MaxSol) break;
331      }
332    }
333
334    // Debug to create the point on the solution circles.
335
336    Standard_Integer kk ;
337    for ( kk = 1; kk <= NbrSol; kk++) {
338      gp_Circ2d CC = cirsol(kk);
339      Standard_Real NR = CC.Location().Distance(Point3);
340      if (Abs(NR - CC.Radius()) > Tol) {
341        cirsol(kk).SetRadius(NR);
342      }
343    }
344
345    // Debug to eliminate multiple solution.
346    // this happens in case of intersection line hyperbola.
347    Standard_Real Tol2 = Tol*Tol;
348    for (kk = 1; kk <NbrSol; kk++) {
349      gp_Pnt2d PK = cirsol(kk).Location();
350      for (Standard_Integer ll = kk+1 ; ll <= NbrSol; ll++) {
351        gp_Pnt2d PL = cirsol(ll).Location();
352        if (PK.SquareDistance(PL) < Tol2) {
353          for (Standard_Integer mm = ll+1 ; mm <= NbrSol; mm++) {
354            cirsol(mm - 1)   = cirsol (mm);   
355            pnttg1sol(mm-1)  = pnttg1sol(mm);
356            pnttg2sol(mm-1)  = pnttg2sol(mm);
357            pnttg3sol(mm-1)  = pnttg3sol(mm);
358            par1sol(mm-1)    = par1sol(mm);
359            par2sol(mm-1)    = par2sol(mm);
360            par3sol(mm-1)    = par3sol(mm);
361            pararg1(mm-1)    = pararg1(mm);
362            pararg2(mm-1)    = pararg2(mm);
363            pararg3(mm-1)    = pararg3(mm);
364            qualifier1(mm-1) = qualifier1(mm);
365            qualifier2(mm-1) = qualifier2(mm);
366            qualifier3(mm-1) = qualifier3(mm);
367          }
368          NbrSol--;
369        }
370      }
371    }
372  }
373