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