0032832: Coding - get rid of unused headers [FairCurve to GeomAPI]
[occt.git] / src / Geom2dGcc / Geom2dGcc_Circ2d2TanRad.cxx
1 // Created on: 1992-10-21
2 // Created by: Remi GILET
3 // Copyright (c) 1992-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 <GccAna_Circ2d2TanRad.hxx>
19 #include <GccEnt_BadQualifier.hxx>
20 #include <GccEnt_QualifiedCirc.hxx>
21 #include <GccEnt_QualifiedLin.hxx>
22 #include <Geom2d_Circle.hxx>
23 #include <Geom2d_Line.hxx>
24 #include <Geom2d_Point.hxx>
25 #include <Geom2dGcc_Circ2d2TanRad.hxx>
26 #include <Geom2dGcc_Circ2d2TanRadGeo.hxx>
27 #include <Geom2dGcc_QCurve.hxx>
28 #include <Geom2dGcc_QualifiedCurve.hxx>
29 #include <gp_Circ2d.hxx>
30 #include <gp_Lin2d.hxx>
31 #include <gp_Pnt2d.hxx>
32 #include <Standard_NegativeValue.hxx>
33 #include <Standard_OutOfRange.hxx>
34 #include <StdFail_NotDone.hxx>
35
36 static const Standard_Integer aNbSolMAX = 16;
37
38 // circulaire tangent a deux cercles et de rayon donne
39 //====================================================
40 //========================================================================
41 // On initialise WellDone a false.                                       +
42 // On recupere le cercle C1 et le cercle C2.                             +
43 // On sort en erreur dans les cas ou la construction est impossible.     +
44 // On distingue les cas limites pour les triater separement.             +
45 // On fait la parallele a C1 dans le bon sens.                           +
46 // On fait la parallele a C2 dans le bon sens.                           +
47 // On intersecte les paralleles ==> point de centre de la solution.      +
48 // On cree la solution qu on ajoute aux solutions deja trouvees.         +
49 // On remplit les champs.                                                +
50 //========================================================================
51
52 Geom2dGcc_Circ2d2TanRad::
53    Geom2dGcc_Circ2d2TanRad (const Geom2dGcc_QualifiedCurve& Qualified1 ,
54                             const Geom2dGcc_QualifiedCurve& Qualified2 ,
55                             const Standard_Real             Radius     ,
56                             const Standard_Real             Tolerance  ):
57   cirsol(1,aNbSolMAX)   ,
58   qualifier1(1,aNbSolMAX),
59   qualifier2(1,aNbSolMAX),
60   TheSame1(1,aNbSolMAX) ,
61   TheSame2(1,aNbSolMAX) ,
62   pnttg1sol(1,aNbSolMAX),
63   pnttg2sol(1,aNbSolMAX),
64   par1sol(1,aNbSolMAX)  ,
65   par2sol(1,aNbSolMAX)  ,
66   pararg1(1,aNbSolMAX)  ,
67   pararg2(1,aNbSolMAX)  
68 {
69   if (Radius < 0.) { throw Standard_NegativeValue(); }
70   else {
71     Geom2dAdaptor_Curve C1 = Qualified1.Qualified();
72     Geom2dAdaptor_Curve C2 = Qualified2.Qualified();
73     Handle(Geom2d_Curve) CC1 = C1.Curve();
74     Handle(Geom2d_Curve) CC2 = C2.Curve();
75     GeomAbs_CurveType Type1 = C1.GetType();
76     GeomAbs_CurveType Type2 = C2.GetType();
77
78 //=============================================================================
79 //                            Appel a GccAna.                                 +
80 //=============================================================================
81
82     Invert = Standard_False;
83     NbrSol = 0;
84     if ((Type1 == GeomAbs_Line || Type1 == GeomAbs_Circle) &&
85         (Type2 == GeomAbs_Line || Type2 == GeomAbs_Circle)) {
86       if (Type1 == GeomAbs_Circle) {
87         Handle(Geom2d_Circle) CCC1 = Handle(Geom2d_Circle)::DownCast(CC1);
88         gp_Circ2d c1(CCC1->Circ2d());
89         GccEnt_QualifiedCirc Qc1 = GccEnt_QualifiedCirc(c1,
90                                                        Qualified1.Qualifier());
91         if (Type2 == GeomAbs_Circle) {
92           Handle(Geom2d_Circle) CCC2 = Handle(Geom2d_Circle)::DownCast(CC2);
93           gp_Circ2d c2(CCC2->Circ2d());
94           GccAna_Circ2d2TanRad CircAna(Qc1,
95                                GccEnt_QualifiedCirc(c2,Qualified2.Qualifier()),
96                                        Radius,Tolerance);
97           WellDone = CircAna.IsDone();
98           NbrSol = CircAna.NbSolutions();
99           for(Standard_Integer i=1; i<=NbrSol; i++) {
100             CircAna.WhichQualifier(i,qualifier1(i),qualifier2(i));
101           }
102           Results(CircAna);
103         }
104         else {
105           Handle(Geom2d_Line) LL2 = Handle(Geom2d_Line)::DownCast(CC2);
106           gp_Lin2d l2(LL2->Lin2d());
107           if (!Qualified2.IsEnclosing()) {
108             GccAna_Circ2d2TanRad CircAna(Qc1,
109                                 GccEnt_QualifiedLin(l2,Qualified2.Qualifier()),
110                                          Radius,Tolerance);
111             WellDone = CircAna.IsDone();
112             NbrSol = CircAna.NbSolutions();
113             for(Standard_Integer i=1; i<=NbrSol; i++) {
114               CircAna.WhichQualifier(i,qualifier1(i),qualifier2(i));
115             }
116             Results(CircAna);
117           }
118           else { 
119             WellDone = Standard_False;
120             throw GccEnt_BadQualifier();
121           }
122         }
123       }
124       else {
125         Handle(Geom2d_Line) LL1 = Handle(Geom2d_Line)::DownCast(CC1);
126         gp_Lin2d l1(LL1->Lin2d());
127         if (Qualified1.IsEnclosing()) {
128           WellDone = Standard_False;
129           throw GccEnt_BadQualifier();
130         }
131         else {
132           GccEnt_QualifiedLin Ql1 = GccEnt_QualifiedLin(l1,
133                                                        Qualified1.Qualifier());
134           if (Type2 == GeomAbs_Circle) {
135             Handle(Geom2d_Circle) CCC2 = Handle(Geom2d_Circle)::DownCast(CC2);
136             gp_Circ2d c2(CCC2->Circ2d());
137             Invert = Standard_True;
138             GccAna_Circ2d2TanRad CircAna(GccEnt_QualifiedCirc(c2,
139                                                        Qualified2.Qualifier()),
140                                          Ql1,Radius,Tolerance);
141             WellDone = CircAna.IsDone();
142             NbrSol = CircAna.NbSolutions();
143             for(Standard_Integer i=1; i<=NbrSol; i++) {
144               CircAna.WhichQualifier(i,qualifier1(i),qualifier2(i));
145             }
146             Results(CircAna);
147           }
148           else {
149             Handle(Geom2d_Line) LL2 = Handle(Geom2d_Line)::DownCast(CC2);
150             gp_Lin2d l2(LL2->Lin2d());
151             if (!Qualified2.IsEnclosing()) {
152               GccAna_Circ2d2TanRad CircAna(Ql1,
153                                 GccEnt_QualifiedLin(l2,Qualified2.Qualifier()),
154                                            Radius,Tolerance);
155               WellDone = CircAna.IsDone();
156               NbrSol = CircAna.NbSolutions();
157               for(Standard_Integer i=1; i<=NbrSol; i++) {
158                 CircAna.WhichQualifier(i,qualifier1(i),qualifier2(i));
159               }
160               Results(CircAna);
161             }
162             else { 
163               WellDone = Standard_False;
164               throw GccEnt_BadQualifier();
165             }
166           }
167         }
168       }
169     }
170 //=============================================================================
171 //                            Appel a GccGeo.                                 +
172 //=============================================================================
173     else {
174       if (Type1 == GeomAbs_Line) {
175         Handle(Geom2d_Line) LL1 = Handle(Geom2d_Line)::DownCast(CC1);
176         gp_Lin2d l1(LL1->Lin2d());
177         if (Qualified1.IsEnclosing()) {
178           WellDone = Standard_False;
179           throw GccEnt_BadQualifier();
180         }
181         else {
182           GccEnt_QualifiedLin Ql1 = GccEnt_QualifiedLin(l1,
183                                                        Qualified1.Qualifier());
184           Geom2dGcc_QCurve Qc2(C2,Qualified2.Qualifier());
185           Geom2dGcc_Circ2d2TanRadGeo CircGeo(Ql1,Qc2,Radius,Tolerance);
186           WellDone = CircGeo.IsDone();
187           NbrSol = CircGeo.NbSolutions();
188           for(Standard_Integer i=1; i<=NbrSol; i++) {
189             CircGeo.WhichQualifier(i,qualifier1(i),qualifier2(i));
190           }
191           Results(CircGeo);
192         }
193       }
194       else if (Type1 == GeomAbs_Circle) {
195         Handle(Geom2d_Circle) CCC1 = Handle(Geom2d_Circle)::DownCast(CC1);
196         gp_Circ2d c1(CCC1->Circ2d());
197         GccEnt_QualifiedCirc Qc1 = GccEnt_QualifiedCirc(c1,
198                                                        Qualified1.Qualifier());
199         Geom2dGcc_QCurve Qc2(C2,Qualified2.Qualifier());
200         Geom2dGcc_Circ2d2TanRadGeo CircGeo(Qc1,Qc2,Radius,Tolerance);
201         WellDone = CircGeo.IsDone();
202         NbrSol = CircGeo.NbSolutions();
203         for(Standard_Integer i=1; i<=NbrSol; i++) {
204           CircGeo.WhichQualifier(i,qualifier1(i),qualifier2(i));
205         }
206         Results(CircGeo);
207       }
208       else if (Type2 == GeomAbs_Line) {
209         Invert = Standard_True;
210         Handle(Geom2d_Line) LL2 = Handle(Geom2d_Line)::DownCast(CC2);
211         gp_Lin2d l2(LL2->Lin2d());
212         if (Qualified2.IsEnclosing()) {
213           WellDone = Standard_False;
214           throw GccEnt_BadQualifier();
215         }
216         else {
217           GccEnt_QualifiedLin Ql2 = GccEnt_QualifiedLin(l2,
218                                                        Qualified2.Qualifier());
219           Geom2dGcc_QCurve Qc1(C1,Qualified1.Qualifier());
220           Geom2dGcc_Circ2d2TanRadGeo CircGeo(Ql2,Qc1,Radius,Tolerance);
221           WellDone = CircGeo.IsDone();
222           NbrSol = CircGeo.NbSolutions();
223           for(Standard_Integer i=1; i<=NbrSol; i++) {
224             CircGeo.WhichQualifier(i,qualifier1(i),qualifier2(i));
225           }
226           Results(CircGeo);
227         }
228       }
229       else if (Type2 == GeomAbs_Circle) {
230         Invert = Standard_True;
231         Handle(Geom2d_Circle) CCC2 = Handle(Geom2d_Circle)::DownCast(CC2);
232         gp_Circ2d c2(CCC2->Circ2d());
233         GccEnt_QualifiedCirc Qc2 = GccEnt_QualifiedCirc(c2,
234                                                        Qualified2.Qualifier());
235         Geom2dGcc_QCurve Qc1(C1,Qualified1.Qualifier());
236         Geom2dGcc_Circ2d2TanRadGeo CircGeo(Qc2,Qc1,Radius,Tolerance);
237         WellDone = CircGeo.IsDone();
238         NbrSol = CircGeo.NbSolutions();
239         for(Standard_Integer i=1; i<=NbrSol; i++) {
240           CircGeo.WhichQualifier(i,qualifier1(i),qualifier2(i));
241         }
242         Results(CircGeo);
243       }
244       else {
245         Geom2dGcc_QCurve Qc1(C1,Qualified1.Qualifier());
246         Geom2dGcc_QCurve Qc2(C2,Qualified2.Qualifier());
247         Geom2dGcc_Circ2d2TanRadGeo CircGeo(Qc1,Qc2,Radius,Tolerance);
248         WellDone = CircGeo.IsDone();
249         NbrSol = CircGeo.NbSolutions();
250         for(Standard_Integer i=1; i<=NbrSol; i++) {
251           CircGeo.WhichQualifier(i,qualifier1(i),qualifier2(i));
252         }
253         Results(CircGeo);
254       }
255     }
256   }
257 }
258
259 Geom2dGcc_Circ2d2TanRad::
260    Geom2dGcc_Circ2d2TanRad (const Geom2dGcc_QualifiedCurve& Qualified1 ,
261                             const Handle(Geom2d_Point)&     Point      ,
262                             const Standard_Real             Radius     ,
263                             const Standard_Real             Tolerance  ):
264   cirsol(1,aNbSolMAX)   ,
265   qualifier1(1,aNbSolMAX),
266   qualifier2(1,aNbSolMAX),
267   TheSame1(1,aNbSolMAX) ,
268   TheSame2(1,aNbSolMAX) ,
269   pnttg1sol(1,aNbSolMAX),
270   pnttg2sol(1,aNbSolMAX),
271   par1sol(1,aNbSolMAX)  ,
272   par2sol(1,aNbSolMAX)  ,
273   pararg1(1,aNbSolMAX)  ,
274   pararg2(1,aNbSolMAX)  
275 {
276   if (Radius < 0.) { throw Standard_NegativeValue(); }
277   else {
278     Geom2dAdaptor_Curve C1 = Qualified1.Qualified();
279     Handle(Geom2d_Curve) CC1 = C1.Curve();
280     GeomAbs_CurveType Type1 = C1.GetType();
281
282 //=============================================================================
283 //                            Appel a GccAna.                                 +
284 //=============================================================================
285
286     Invert = Standard_False;
287     NbrSol = 0;
288     if (Type1 == GeomAbs_Line || Type1 == GeomAbs_Circle) {
289       if (Type1 == GeomAbs_Circle) {
290         Handle(Geom2d_Circle) CCC1 = Handle(Geom2d_Circle)::DownCast(CC1);
291         gp_Circ2d c1(CCC1->Circ2d());
292         GccEnt_QualifiedCirc Qc1(c1,Qualified1.Qualifier());
293         GccAna_Circ2d2TanRad CircAna(Qc1,Point->Pnt2d(),Radius,Tolerance);
294         WellDone = CircAna.IsDone();
295         NbrSol = CircAna.NbSolutions();
296         for(Standard_Integer i=1; i<=NbrSol; i++) {
297           CircAna.WhichQualifier(i,qualifier1(i),qualifier2(i));
298         }
299         Results(CircAna);
300       }
301       else {
302         Handle(Geom2d_Line) LLL1 = Handle(Geom2d_Line)::DownCast(CC1);
303         gp_Lin2d l1(LLL1->Lin2d());
304         GccEnt_QualifiedLin Ql1(l1,Qualified1.Qualifier());
305         GccAna_Circ2d2TanRad CircAna(Ql1,Point->Pnt2d(),Radius,Tolerance);
306         WellDone = CircAna.IsDone();
307         NbrSol = CircAna.NbSolutions();
308         for(Standard_Integer i=1; i<=NbrSol; i++) {
309           CircAna.WhichQualifier(i,qualifier1(i),qualifier2(i));
310         }
311         Results(CircAna);
312       }
313     }
314 //=============================================================================
315 //                            Appel a GccGeo.                                 +
316 //=============================================================================
317     else {
318       Geom2dGcc_QCurve Qc1(C1,Qualified1.Qualifier());
319       Geom2dGcc_Circ2d2TanRadGeo CircGeo(Qc1,Point->Pnt2d(),Radius,Tolerance);
320       WellDone = CircGeo.IsDone();
321       NbrSol = CircGeo.NbSolutions();
322       for(Standard_Integer i=1; i<=NbrSol; i++) {
323         CircGeo.WhichQualifier(i,qualifier1(i),qualifier2(i));
324       }
325       Results(CircGeo);
326     }
327   }
328 }
329   
330 Geom2dGcc_Circ2d2TanRad::
331    Geom2dGcc_Circ2d2TanRad (const Handle(Geom2d_Point)& Point1     ,
332                             const Handle(Geom2d_Point)& Point2     ,
333                             const Standard_Real         Radius     ,
334                             const Standard_Real         Tolerance  ):
335   cirsol(1,2)   ,
336   qualifier1(1,2),
337   qualifier2(1,2),
338   TheSame1(1,2) ,
339   TheSame2(1,2) ,
340   pnttg1sol(1,2),
341   pnttg2sol(1,2),
342   par1sol(1,2)  ,
343   par2sol(1,2)  ,
344   pararg1(1,2)  ,
345   pararg2(1,2)  
346 {
347   if (Radius < 0.) { throw Standard_NegativeValue(); }
348   else {
349
350 //=============================================================================
351 //                            Appel a GccAna.                                 +
352 //=============================================================================
353
354     Invert = Standard_False;
355     NbrSol = 0;
356     GccAna_Circ2d2TanRad CircAna(Point1->Pnt2d(),Point2->Pnt2d(),
357                                  Radius,Tolerance);
358     WellDone = CircAna.IsDone();
359     NbrSol = CircAna.NbSolutions();
360     for(Standard_Integer i=1; i<=NbrSol; i++) {
361       CircAna.WhichQualifier(i,qualifier1(i),qualifier2(i));
362     }
363     Results(CircAna);
364   }
365 }
366
367 void Geom2dGcc_Circ2d2TanRad::Results(const GccAna_Circ2d2TanRad& Circ)
368 {
369   for (Standard_Integer j = 1; j <= NbrSol; j++) {
370     cirsol(j)   = Circ.ThisSolution(j);
371     if (Circ.IsTheSame1(j)) { TheSame1(j) = 1; }
372     else {TheSame1(j) = 0; }
373     if (Circ.IsTheSame2(j)) { TheSame2(j) = 1; }
374     else {TheSame2(j) = 0; }
375     Circ.Tangency1(j,par1sol(j),pararg1(j),pnttg1sol(j));
376     Circ.Tangency2(j,par2sol(j),pararg2(j),pnttg2sol(j));
377   }
378 }
379
380 void Geom2dGcc_Circ2d2TanRad::Results(const Geom2dGcc_Circ2d2TanRadGeo& Circ)
381 {
382   for (Standard_Integer j = 1; j <= NbrSol; j++) {
383     cirsol(j)   = Circ.ThisSolution(j);
384     if (Circ.IsTheSame1(j)) { TheSame1(j) = 1; }
385     else {TheSame1(j) = 0; }
386     if (Circ.IsTheSame2(j)) { TheSame2(j) = 1; }
387     else {TheSame2(j) = 0; }
388     Circ.Tangency1(j,par1sol(j),pararg1(j),pnttg1sol(j));
389     Circ.Tangency2(j,par2sol(j),pararg2(j),pnttg2sol(j));
390   }
391 }
392
393 Standard_Boolean Geom2dGcc_Circ2d2TanRad::
394    IsDone () const { return WellDone; }
395
396 Standard_Integer Geom2dGcc_Circ2d2TanRad::
397   NbSolutions () const 
398
399   return NbrSol;
400 }
401
402 gp_Circ2d Geom2dGcc_Circ2d2TanRad::
403   ThisSolution (const Standard_Integer Index) const 
404 {
405   if (!WellDone) { throw StdFail_NotDone(); }
406   if (Index <= 0 ||Index > NbrSol) { throw Standard_OutOfRange(); }
407   return cirsol(Index);
408 }
409
410 void Geom2dGcc_Circ2d2TanRad::
411   WhichQualifier (const Standard_Integer Index   ,
412                         GccEnt_Position& Qualif1 ,
413                         GccEnt_Position& Qualif2) const
414 {
415   if (!WellDone) { throw StdFail_NotDone(); }
416   else if (Index <= 0 ||Index > NbrSol) { throw Standard_OutOfRange(); }
417   else {
418     if (Invert) {
419       Qualif1 = qualifier2(Index);
420       Qualif2 = qualifier1(Index);
421     }
422     else {
423       Qualif1 = qualifier1(Index);
424       Qualif2 = qualifier2(Index);
425     }
426   }
427 }
428
429 void Geom2dGcc_Circ2d2TanRad::
430   Tangency1 (const Standard_Integer Index,
431                    Standard_Real&   ParSol,
432                    Standard_Real&   ParArg,
433                    gp_Pnt2d&        PntSol) const
434 {
435   if (!WellDone) { throw StdFail_NotDone(); }
436   else if (Index <= 0 ||Index > NbrSol) { throw Standard_OutOfRange(); }
437   else {
438     if (Invert) {
439       if (TheSame2(Index) == 0) {
440         ParSol = par2sol(Index);
441         ParArg = pararg2(Index);
442         PntSol = pnttg2sol(Index);
443       }
444       else { throw StdFail_NotDone(); }
445     }
446     else {
447       if (TheSame1(Index) == 0) {
448         ParSol = par1sol(Index);
449         ParArg = pararg1(Index);
450         PntSol = pnttg1sol(Index);
451       }
452       else { throw StdFail_NotDone(); }
453     }
454   }
455 }
456
457 void Geom2dGcc_Circ2d2TanRad::
458    Tangency2 (const Standard_Integer Index,
459               Standard_Real& ParSol,
460               Standard_Real& ParArg,
461               gp_Pnt2d& PntSol) const
462 {
463   if (!WellDone) { throw StdFail_NotDone(); }
464   else if (Index <= 0 ||Index > NbrSol) { throw Standard_OutOfRange(); }
465   else {
466     if (!Invert) {
467       if (TheSame2(Index) == 0) {
468         ParSol = par2sol(Index);
469         ParArg = pararg2(Index);
470         PntSol = pnttg2sol(Index);
471       }
472       else { throw StdFail_NotDone(); }
473     }
474     else {
475       if (TheSame1(Index) == 0) {
476         ParSol = par1sol(Index);
477         ParArg = pararg1(Index);
478         PntSol = pnttg1sol(Index);
479       }
480       else { throw StdFail_NotDone(); }
481     }
482   }
483 }
484
485 Standard_Boolean Geom2dGcc_Circ2d2TanRad::
486    IsTheSame1 (const Standard_Integer Index) const
487 {
488   if (!WellDone) { throw StdFail_NotDone(); }
489   if (Index <= 0 ||Index > NbrSol) { throw Standard_OutOfRange(); }
490   if (Invert) {
491     if (TheSame2(Index) == 0) { return Standard_False; }
492     else { return Standard_True; }
493   }
494   else {
495     if (TheSame1(Index) == 0) { return Standard_False; }
496     else { return Standard_True; }
497   }
498 }
499
500 Standard_Boolean Geom2dGcc_Circ2d2TanRad::
501    IsTheSame2 (const Standard_Integer Index) const
502 {
503   if (!WellDone) { throw StdFail_NotDone(); }
504   if (Index <= 0 ||Index > NbrSol) { throw Standard_OutOfRange(); }
505   if (!Invert) {
506     if (TheSame2(Index) == 0) { return Standard_False; }
507     else { return Standard_True; }
508   }
509   else {
510     if (TheSame1(Index) == 0) { return Standard_False; }
511     else { return Standard_True; }
512   }
513 //  return Standard_True;
514 }