6d1370b289303e86a62972340d407da356b79ec8
[occt.git] / src / Geom2dGcc / Geom2dGcc_Circ2d2TanOn.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_Circ2d2TanOn.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 <Geom2dAdaptor_Curve.hxx>
26 #include <Geom2dGcc_Circ2d2TanOn.hxx>
27 #include <Geom2dGcc_Circ2d2TanOnGeo.hxx>
28 #include <Geom2dGcc_Circ2d2TanOnIter.hxx>
29 #include <Geom2dGcc_QCurve.hxx>
30 #include <Geom2dGcc_QualifiedCurve.hxx>
31 #include <gp_Circ2d.hxx>
32 #include <gp_Pnt2d.hxx>
33 #include <Standard_OutOfRange.hxx>
34 #include <StdFail_NotDone.hxx>
35
36 Geom2dGcc_Circ2d2TanOn::
37    Geom2dGcc_Circ2d2TanOn (const Geom2dGcc_QualifiedCurve&    Qualified1 , 
38                            const Geom2dGcc_QualifiedCurve&    Qualified2 , 
39                            const Geom2dAdaptor_Curve&         OnCurve    ,
40                            const Standard_Real                Tolerance  ,
41                            const Standard_Real                Param1     ,
42                            const Standard_Real                Param2     ,
43                            const Standard_Real                ParamOn    ):
44   cirsol(1,8)   ,
45   qualifier1(1,8),
46   qualifier2(1,8),
47   TheSame1(1,8) ,
48   TheSame2(1,8) ,
49   pnttg1sol(1,8),
50   pnttg2sol(1,8),
51   pntcen(1,8)   ,
52   par1sol(1,8)  ,
53   par2sol(1,8)  ,
54   pararg1(1,8)  ,
55   pararg2(1,8)  ,
56   parcen3(1,8)  
57 {
58   Geom2dAdaptor_Curve C1 = Qualified1.Qualified();
59   Geom2dAdaptor_Curve C2 = Qualified2.Qualified();
60   GeomAbs_CurveType Type1 = C1.GetType();
61   GeomAbs_CurveType Type2 = C2.GetType();
62   GeomAbs_CurveType Type3 = OnCurve.GetType();
63   Handle(Geom2d_Curve) CC1 = C1.Curve();
64   Handle(Geom2d_Curve) CC2 = C2.Curve();
65   Handle(Geom2d_Curve) Con = OnCurve.Curve();
66
67 //=============================================================================
68 //                            Appel a GccAna.                                 +
69 //=============================================================================
70
71   Invert = Standard_False;
72   NbrSol = 0;
73   if ((Type1 == GeomAbs_Line || Type1 == GeomAbs_Circle) &&
74       (Type2 == GeomAbs_Line || Type2 == GeomAbs_Circle)) {
75     if (Type3 == GeomAbs_Line || Type3 == GeomAbs_Circle) {
76       if (Type1 == GeomAbs_Circle) {
77         Handle(Geom2d_Circle) CCC1 = Handle(Geom2d_Circle)::DownCast(CC1);
78         gp_Circ2d c1(CCC1->Circ2d());
79         GccEnt_QualifiedCirc Qc1 = 
80           GccEnt_QualifiedCirc(c1,Qualified1.Qualifier());
81         if (Type2 == GeomAbs_Circle) {
82           Handle(Geom2d_Circle) CCC2 = Handle(Geom2d_Circle)::DownCast(CC2);
83           gp_Circ2d c2(CCC2->Circ2d());
84           if (Type3 == GeomAbs_Circle) {
85             Handle(Geom2d_Circle) CCon = Handle(Geom2d_Circle)::DownCast(Con);
86             GccAna_Circ2d2TanOn CircAna(Qc1,
87                                GccEnt_QualifiedCirc(c2,Qualified2.Qualifier()),
88                                         CCon->Circ2d(),Tolerance);
89             WellDone = CircAna.IsDone();
90             if (WellDone)
91             {
92               NbrSol = CircAna.NbSolutions();
93               for(Standard_Integer i=1; i<=NbrSol; i++) {
94                 CircAna.WhichQualifier(i,qualifier1(i),qualifier2(i));
95               }
96               Results(CircAna);
97             }
98           }
99           else {
100             Handle(Geom2d_Line) LLon = Handle(Geom2d_Line)::DownCast(Con);
101             GccAna_Circ2d2TanOn CircAna(Qc1,
102                                GccEnt_QualifiedCirc(c2,Qualified2.Qualifier()),
103                                         LLon->Lin2d(),Tolerance);
104             WellDone = CircAna.IsDone();
105             if (WellDone)
106             {
107               NbrSol = CircAna.NbSolutions();
108               for(Standard_Integer i=1; i<=NbrSol; i++) {
109                 CircAna.WhichQualifier(i,qualifier1(i),qualifier2(i));
110               }
111               Results(CircAna);
112             }
113           }
114         }
115         else {
116           Handle(Geom2d_Line) LL2 = Handle(Geom2d_Line)::DownCast(CC2);
117           gp_Lin2d l2(LL2->Lin2d());
118           if (Type3 == GeomAbs_Circle) {
119             Handle(Geom2d_Circle) CCon = Handle(Geom2d_Circle)::DownCast(Con);
120             GccAna_Circ2d2TanOn CircAna(Qc1,
121                                GccEnt_QualifiedLin(l2,Qualified2.Qualifier()),
122                                         CCon->Circ2d(),Tolerance);
123             WellDone = CircAna.IsDone();
124             if (WellDone)
125             {
126               NbrSol = CircAna.NbSolutions();
127               for(Standard_Integer i=1; i<=NbrSol; i++) {
128                 CircAna.WhichQualifier(i,qualifier1(i),qualifier2(i));
129               }
130               Results(CircAna);
131             }
132           }
133           else {
134             Handle(Geom2d_Line) LLon = Handle(Geom2d_Line)::DownCast(Con);
135             GccAna_Circ2d2TanOn CircAna(Qc1,
136                                GccEnt_QualifiedLin(l2,Qualified2.Qualifier()),
137                                         LLon->Lin2d(),Tolerance);
138             WellDone = CircAna.IsDone();
139             if (WellDone)
140             {
141               NbrSol = CircAna.NbSolutions();
142               for(Standard_Integer i=1; i<=NbrSol; i++) {
143                 CircAna.WhichQualifier(i,qualifier1(i),qualifier2(i));
144               }
145               Results(CircAna);
146             }
147           }
148         }
149       }
150       else {
151         Handle(Geom2d_Line) LL1 = Handle(Geom2d_Line)::DownCast(CC1);
152         gp_Lin2d l1(LL1->Lin2d());
153         GccEnt_QualifiedLin Ql1 = 
154           GccEnt_QualifiedLin(l1,Qualified1.Qualifier());
155         if (Type2 == GeomAbs_Circle) {
156           Handle(Geom2d_Circle) CCC2 = Handle(Geom2d_Circle)::DownCast(CC2);
157           gp_Circ2d c2(CCC2->Circ2d());
158           if (Type3 == GeomAbs_Circle) {
159             Handle(Geom2d_Circle) CCon = Handle(Geom2d_Circle)::DownCast(Con);
160             GccAna_Circ2d2TanOn CircAna(GccEnt_QualifiedCirc(c2,
161                                                        Qualified2.Qualifier()),
162                                         Ql1,CCon->Circ2d(),Tolerance);
163             WellDone = CircAna.IsDone();
164             if (WellDone)
165             {
166               NbrSol = CircAna.NbSolutions();
167               for(Standard_Integer i=1; i<=NbrSol; i++) {
168                 CircAna.WhichQualifier(i,qualifier1(i),qualifier2(i));
169               }
170               Results(CircAna);
171               Invert = Standard_True;
172             }
173           }
174           else {
175             Handle(Geom2d_Line) LLon = Handle(Geom2d_Line)::DownCast(Con);
176             GccAna_Circ2d2TanOn CircAna(GccEnt_QualifiedCirc(c2,
177                                                        Qualified2.Qualifier()),
178                                         Ql1,LLon->Lin2d(),Tolerance);
179             WellDone = CircAna.IsDone();
180             if (WellDone)
181             {
182               NbrSol = CircAna.NbSolutions();
183               for(Standard_Integer i=1; i<=NbrSol; i++) {
184                 CircAna.WhichQualifier(i,qualifier1(i),qualifier2(i));
185               }
186               Results(CircAna);
187               Invert = Standard_True;
188             }
189           }
190         }
191         else {
192           Handle(Geom2d_Line) LL2 = Handle(Geom2d_Line)::DownCast(CC2);
193           gp_Lin2d l2(LL2->Lin2d());
194           if (Type3 == GeomAbs_Circle) {
195             Handle(Geom2d_Circle) CCon = Handle(Geom2d_Circle)::DownCast(Con);
196             GccAna_Circ2d2TanOn CircAna(Ql1,
197                                GccEnt_QualifiedLin(l2,Qualified2.Qualifier()),
198                                         CCon->Circ2d(),Tolerance);
199             WellDone = CircAna.IsDone();
200             if (WellDone)
201             {
202               NbrSol = CircAna.NbSolutions();
203               for(Standard_Integer i=1; i<=NbrSol; i++) {
204                 CircAna.WhichQualifier(i,qualifier1(i),qualifier2(i));
205               }
206               Results(CircAna);
207             }
208           }
209           else {
210             Handle(Geom2d_Line) LLon = Handle(Geom2d_Line)::DownCast(Con);
211             GccAna_Circ2d2TanOn CircAna(Ql1,
212                                GccEnt_QualifiedLin(l2,Qualified2.Qualifier()),
213                                         LLon->Lin2d(),Tolerance);
214             WellDone = CircAna.IsDone();
215             if (WellDone)
216             {
217               NbrSol = CircAna.NbSolutions();
218               for(Standard_Integer i=1; i<=NbrSol; i++) {
219                 CircAna.WhichQualifier(i,qualifier1(i),qualifier2(i));
220               }
221               Results(CircAna);
222             }
223           }
224         }
225       }
226     }
227
228 //=============================================================================
229 //                            Appel a GccGeo.                                 +
230 //=============================================================================
231
232     else {
233       if (Type1 == GeomAbs_Circle) {
234         Handle(Geom2d_Circle) CCC1 = Handle(Geom2d_Circle)::DownCast(CC1);
235         gp_Circ2d c1(CCC1->Circ2d());
236         GccEnt_QualifiedCirc Qc1 =
237           GccEnt_QualifiedCirc(c1,Qualified1.Qualifier());
238         if (Type2 == GeomAbs_Circle) {
239           Handle(Geom2d_Circle) CCC2 = Handle(Geom2d_Circle)::DownCast(CC2);
240           gp_Circ2d c2(CCC2->Circ2d());
241           GccEnt_QualifiedCirc Qc2 =
242             GccEnt_QualifiedCirc(c2,Qualified2.Qualifier());
243           Geom2dGcc_Circ2d2TanOnGeo CircGeo(Qc1,Qc2,OnCurve,Tolerance);
244           WellDone = CircGeo.IsDone();
245           if (WellDone)
246           {
247             NbrSol = CircGeo.NbSolutions();
248             for(Standard_Integer i=1; i<=NbrSol; i++) {
249               CircGeo.WhichQualifier(i,qualifier1(i),qualifier2(i));
250             }
251             Results(CircGeo);
252           }
253         }
254         else {
255           Handle(Geom2d_Line) LL2 = Handle(Geom2d_Line)::DownCast(CC2);
256           gp_Lin2d l2(LL2->Lin2d());
257           GccEnt_QualifiedLin Ql2 =
258             GccEnt_QualifiedLin(l2,Qualified2.Qualifier());
259           Geom2dGcc_Circ2d2TanOnGeo CircGeo(Qc1,Ql2,OnCurve,Tolerance);
260           WellDone = CircGeo.IsDone();
261           if (WellDone)
262           {
263             NbrSol = CircGeo.NbSolutions();
264             for(Standard_Integer i=1; i<=NbrSol; i++) {
265               CircGeo.WhichQualifier(i,qualifier1(i),qualifier2(i));
266             }
267             Results(CircGeo);
268           }
269         }
270       }
271       else {
272         Handle(Geom2d_Line) LL1 = Handle(Geom2d_Line)::DownCast(CC1);
273         gp_Lin2d l1(LL1->Lin2d());
274         GccEnt_QualifiedLin Ql1 =
275           GccEnt_QualifiedLin(l1,Qualified1.Qualifier());
276         if (Type2 == GeomAbs_Circle) {
277           Handle(Geom2d_Circle) CCC2 = Handle(Geom2d_Circle)::DownCast(CC2);
278           gp_Circ2d c2(CCC2->Circ2d());
279           GccEnt_QualifiedCirc Qc2 =
280             GccEnt_QualifiedCirc(c2,Qualified2.Qualifier());
281           Geom2dGcc_Circ2d2TanOnGeo CircGeo(Qc2,Ql1,OnCurve,Tolerance);
282           WellDone = CircGeo.IsDone();
283           if (WellDone)
284           {
285             NbrSol = CircGeo.NbSolutions();
286             for(Standard_Integer i=1; i<=NbrSol; i++) {
287               CircGeo.WhichQualifier(i,qualifier1(i),qualifier2(i));
288             }
289             Results(CircGeo);
290             Invert = Standard_True;
291           }
292         }
293         else {
294           Handle(Geom2d_Line) LL2 = Handle(Geom2d_Line)::DownCast(CC2);
295           gp_Lin2d l2(LL2->Lin2d());
296           GccEnt_QualifiedLin Ql2 =
297             GccEnt_QualifiedLin(l2,Qualified2.Qualifier());
298           Geom2dGcc_Circ2d2TanOnGeo CircGeo(Ql1,Ql2,OnCurve,Tolerance);
299           WellDone = CircGeo.IsDone();
300           if (WellDone)
301           {
302             NbrSol = CircGeo.NbSolutions();
303             for(Standard_Integer i=1; i<=NbrSol; i++) {
304               CircGeo.WhichQualifier(i,qualifier1(i),qualifier2(i));
305             }
306             Results(CircGeo);
307           }
308         }
309       }
310     }
311   }
312   else {
313     Geom2dGcc_QCurve Qc1(C1,Qualified1.Qualifier());
314     Geom2dGcc_QCurve Qc2(C2,Qualified2.Qualifier());
315     if ((Type3 == GeomAbs_Circle || Type3 == GeomAbs_Line)) {
316       if (Type3 == GeomAbs_Circle) {
317         Handle(Geom2d_Circle) CCon = Handle(Geom2d_Circle)::DownCast(Con);
318         Geom2dGcc_Circ2d2TanOnIter Circ(Qc1,Qc2,CCon->Circ2d(),
319                                    Param1,Param2,ParamOn,Tolerance);
320         WellDone = Circ.IsDone();
321         if (WellDone)
322         {
323           NbrSol = 1;
324           cirsol(1)   = Circ.ThisSolution();
325           if (Circ.IsTheSame1()) { TheSame1(1) = 1; }
326           else {TheSame1(1) = 0; }
327           if (Circ.IsTheSame2()) { TheSame2(1) = 1; }
328           else {TheSame2(1) = 0; }
329           Circ.Tangency1(par1sol(1),pararg1(1),pnttg1sol(1));
330           Circ.Tangency2(par2sol(1),pararg2(1),pnttg2sol(1));
331         }
332       }
333       else {
334         Handle(Geom2d_Line) LLon = Handle(Geom2d_Line)::DownCast(Con);
335         Geom2dGcc_Circ2d2TanOnIter Circ(Qc1,Qc2,LLon->Lin2d(),
336                                        Param1,Param2,ParamOn,Tolerance);
337         WellDone = Circ.IsDone();
338         if (WellDone)
339         {
340           NbrSol = 1;
341           cirsol(1)   = Circ.ThisSolution();
342           if (Circ.IsTheSame1()) { TheSame1(1) = 1; }
343           else {TheSame1(1) = 0; }
344           if (Circ.IsTheSame2()) { TheSame2(1) = 1; }
345           else {TheSame2(1) = 0; }
346           Circ.WhichQualifier(qualifier1(1),qualifier2(1));
347           Circ.Tangency1(par1sol(1),pararg1(1),pnttg1sol(1));
348           Circ.Tangency2(par2sol(1),pararg2(1),pnttg2sol(1));
349         }
350       }
351     }
352     Geom2dGcc_Circ2d2TanOnIter Circ(Qc1,Qc2,OnCurve,
353                                    Param1,Param2,ParamOn,Tolerance);
354     WellDone = Circ.IsDone();
355     if (WellDone)
356     {
357       NbrSol = 1;
358       cirsol(1)   = Circ.ThisSolution();
359       if (Circ.IsTheSame1()) { TheSame1(1) = 1; }
360       else {TheSame1(1) = 0; }
361       if (Circ.IsTheSame2()) { TheSame2(1) = 1; }
362       else {TheSame2(1) = 0; }
363       Circ.WhichQualifier(qualifier1(1),qualifier2(1));
364       Circ.Tangency1(par1sol(1),pararg1(1),pnttg1sol(1));
365       Circ.Tangency2(par2sol(1),pararg2(1),pnttg2sol(1));
366     }
367   }
368 }
369
370 Geom2dGcc_Circ2d2TanOn::
371    Geom2dGcc_Circ2d2TanOn (const Geom2dGcc_QualifiedCurve&    Qualified1 , 
372                            const Handle(Geom2d_Point)&        Point      , 
373                            const Geom2dAdaptor_Curve&         OnCurve    ,
374                            const Standard_Real                Tolerance  ,
375                            const Standard_Real                Param1     ,
376                            const Standard_Real                ParamOn    ):
377   cirsol(1,8)   ,
378   qualifier1(1,8),
379   qualifier2(1,8),
380   TheSame1(1,8) ,
381   TheSame2(1,8) ,
382   pnttg1sol(1,8),
383   pnttg2sol(1,8),
384   pntcen(1,8)   ,
385   par1sol(1,8)  ,
386   par2sol(1,8)  ,
387   pararg1(1,8)  ,
388   pararg2(1,8)  ,
389   parcen3(1,8)  
390 {
391   Geom2dAdaptor_Curve C1 = Qualified1.Qualified();
392   GeomAbs_CurveType Type1 = C1.GetType();
393   GeomAbs_CurveType Type3 = OnCurve.GetType();
394   Handle(Geom2d_Curve) CC1 = C1.Curve();
395   Handle(Geom2d_Curve) Con = OnCurve.Curve();
396
397 //=============================================================================
398 //                            Appel a GccAna.                                 +
399 //=============================================================================
400
401   Invert = Standard_False;
402   NbrSol = 0;
403   if (Type1 == GeomAbs_Line || Type1 == GeomAbs_Circle) {
404     if (Type3 == GeomAbs_Line || Type3 == GeomAbs_Circle) {
405       gp_Pnt2d pnt(Point->Pnt2d());
406       if (Type1 == GeomAbs_Circle) {
407         Handle(Geom2d_Circle) CCC1 = Handle(Geom2d_Circle)::DownCast(CC1);
408         gp_Circ2d c1(CCC1->Circ2d());
409         GccEnt_QualifiedCirc Qc1(c1,Qualified1.Qualifier());
410         if (Type3 == GeomAbs_Circle) {
411           Handle(Geom2d_Circle) CCon = Handle(Geom2d_Circle)::DownCast(Con);
412           GccAna_Circ2d2TanOn CircAna(Qc1,pnt,CCon->Circ2d(),Tolerance);
413           WellDone = CircAna.IsDone();
414           if (WellDone)
415           {
416             NbrSol = CircAna.NbSolutions();
417             for(Standard_Integer i=1; i<=NbrSol; i++) {
418               CircAna.WhichQualifier(i,qualifier1(i),qualifier2(i));
419             }
420             Results(CircAna);
421           }
422         }
423         else if (Type3 == GeomAbs_Line) {
424           Handle(Geom2d_Line) CCon = Handle(Geom2d_Line)::DownCast(Con);
425           GccAna_Circ2d2TanOn CircAna(Qc1,pnt,CCon->Lin2d(),Tolerance);
426           WellDone = CircAna.IsDone();
427           if (WellDone)
428           {
429             NbrSol = CircAna.NbSolutions();
430             for(Standard_Integer i=1; i<=NbrSol; i++) {
431               CircAna.WhichQualifier(i,qualifier1(i),qualifier2(i));
432             }
433             Results(CircAna);
434           }
435         }
436       }
437       else {
438         Handle(Geom2d_Line) LLL1 = Handle(Geom2d_Line)::DownCast(CC1);
439         gp_Lin2d l1(LLL1->Lin2d());
440         GccEnt_QualifiedLin Ql1(l1,Qualified1.Qualifier());
441         if (Type3 == GeomAbs_Circle) {
442           Handle(Geom2d_Circle) CCon = Handle(Geom2d_Circle)::DownCast(Con);
443           GccAna_Circ2d2TanOn CircAna(Ql1,pnt,CCon->Circ2d(),Tolerance);
444           WellDone = CircAna.IsDone();
445           if (WellDone)
446           {
447             NbrSol = CircAna.NbSolutions();
448             for(Standard_Integer i=1; i<=NbrSol; i++) {
449               CircAna.WhichQualifier(i,qualifier1(i),qualifier2(i));
450             }
451             Results(CircAna);
452           }
453         }
454         else if (Type3 == GeomAbs_Line) {
455           Handle(Geom2d_Line) LLon = Handle(Geom2d_Line)::DownCast(Con);
456           GccAna_Circ2d2TanOn CircAna(Ql1,pnt,LLon->Lin2d(),Tolerance);
457           WellDone = CircAna.IsDone();
458           if (WellDone)
459           {
460             NbrSol = CircAna.NbSolutions();
461             for(Standard_Integer i=1; i<=NbrSol; i++) {
462               CircAna.WhichQualifier(i,qualifier1(i),qualifier2(i));
463             }
464             Results(CircAna);
465           }
466         }
467       }
468     }
469 //=============================================================================
470 //                            Appel a GccGeo.                                 +
471 //=============================================================================
472
473     else {
474       if (Type1 == GeomAbs_Circle) {
475         Handle(Geom2d_Circle) CCC1 = Handle(Geom2d_Circle)::DownCast(CC1);
476         gp_Circ2d c1(CCC1->Circ2d());
477         GccEnt_QualifiedCirc Qc1(c1,Qualified1.Qualifier());
478         Geom2dGcc_Circ2d2TanOnGeo CircGeo(Qc1,Point->Pnt2d(),OnCurve,Tolerance);
479         WellDone = CircGeo.IsDone();
480         if (WellDone)
481         {
482           NbrSol = CircGeo.NbSolutions();
483           for(Standard_Integer i=1; i<=NbrSol; i++) {
484             CircGeo.WhichQualifier(i,qualifier1(i),qualifier2(i));
485           }
486           Results(CircGeo);
487         }
488       }
489       else {
490         Handle(Geom2d_Line) LLL1 = Handle(Geom2d_Line)::DownCast(CC1);
491         gp_Lin2d l1(LLL1->Lin2d());
492         GccEnt_QualifiedLin Ql1(l1,Qualified1.Qualifier());
493         Geom2dGcc_Circ2d2TanOnGeo CircGeo(Ql1,Point->Pnt2d(),OnCurve,Tolerance);
494         WellDone = CircGeo.IsDone();
495         if (WellDone)
496         {
497           NbrSol = CircGeo.NbSolutions();
498           for(Standard_Integer i=1; i<=NbrSol; i++) {
499             CircGeo.WhichQualifier(i,qualifier1(i),qualifier2(i));
500           }
501           Results(CircGeo);
502         }
503       }
504     }
505   }                                   
506   else {
507     Geom2dGcc_QCurve Qc1(C1,Qualified1.Qualifier());
508     if ((Type3 == GeomAbs_Circle || Type3 == GeomAbs_Line)) {
509       if (Type3 == GeomAbs_Circle) {
510         Handle(Geom2d_Circle) CCon = Handle(Geom2d_Circle)::DownCast(Con);
511         Geom2dGcc_Circ2d2TanOnIter Circ(Qc1,Point->Pnt2d(),CCon->Circ2d(),
512                                    Param1,ParamOn,Tolerance);
513         WellDone = Circ.IsDone();
514         if (WellDone)
515         {
516           NbrSol = 1;
517           cirsol(1)   = Circ.ThisSolution();
518           if (Circ.IsTheSame1()) { TheSame1(1) = 1; }
519           else {TheSame1(1) = 0; }
520           Circ.WhichQualifier(qualifier1(1),qualifier2(1));
521           Circ.Tangency1(par1sol(1),pararg1(1),pnttg1sol(1));
522           Circ.Tangency2(par2sol(1),pararg2(1),pnttg2sol(1));
523         }
524       }
525       else {
526         Handle(Geom2d_Line) LLon = Handle(Geom2d_Line)::DownCast(Con);
527         Geom2dGcc_Circ2d2TanOnIter Circ(Qc1,Point->Pnt2d(),LLon->Lin2d(),
528                                        Param1,ParamOn,Tolerance);
529         WellDone = Circ.IsDone();
530         if (WellDone)
531         {
532           NbrSol = 1;
533           cirsol(1)   = Circ.ThisSolution();
534           if (Circ.IsTheSame1()) { TheSame1(1) = 1; }
535           else {TheSame1(1) = 0; }
536           Circ.WhichQualifier(qualifier1(1),qualifier2(1));
537           Circ.Tangency1(par1sol(1),pararg1(1),pnttg1sol(1));
538           Circ.Tangency2(par2sol(1),pararg2(1),pnttg2sol(1));
539         }
540       }
541     }
542     else {
543       Geom2dGcc_Circ2d2TanOnIter Circ(Qc1,Point->Pnt2d(),OnCurve,
544                                  Param1,ParamOn,Tolerance);
545       WellDone = Circ.IsDone();
546       if (WellDone)
547       {
548         NbrSol = 1;
549         cirsol(1)   = Circ.ThisSolution();
550         if (Circ.IsTheSame1()) { TheSame1(1) = 1; }
551         else {TheSame1(1) = 0; }
552         if (Circ.IsTheSame2()) { TheSame2(1) = 1; }
553         else {TheSame2(1) = 0; }
554         Circ.WhichQualifier(qualifier1(1),qualifier2(1));
555         Circ.Tangency1(par1sol(1),pararg1(1),pnttg1sol(1));
556         Circ.Tangency2(par2sol(1),pararg2(1),pnttg2sol(1));
557       }
558     }
559   }
560 }
561
562 Geom2dGcc_Circ2d2TanOn::
563    Geom2dGcc_Circ2d2TanOn (const Handle(Geom2d_Point)&        Point1     , 
564                            const Handle(Geom2d_Point)&        Point2     , 
565                            const Geom2dAdaptor_Curve&         OnCurve    ,
566                            const Standard_Real                Tolerance  ):
567   cirsol(1,8)   ,
568   qualifier1(1,8),
569   qualifier2(1,8),
570   TheSame1(1,8) ,
571   TheSame2(1,8) ,
572   pnttg1sol(1,8),
573   pnttg2sol(1,8),
574   pntcen(1,8)   ,
575   par1sol(1,8)  ,
576   par2sol(1,8)  ,
577   pararg1(1,8)  ,
578   pararg2(1,8)  ,
579   parcen3(1,8)  
580
581 {
582   GeomAbs_CurveType Type3 = OnCurve.GetType();
583   Handle(Geom2d_Curve) Con = OnCurve.Curve();
584
585 //=============================================================================
586 //                            Appel a GccAna.                                 +
587 //=============================================================================
588
589   Invert = Standard_False;
590   NbrSol = 0;
591   if (Type3 == GeomAbs_Line || Type3 == GeomAbs_Circle) {
592     gp_Pnt2d pnt1(Point1->Pnt2d());
593     gp_Pnt2d pnt2(Point2->Pnt2d());
594     if (Type3 == GeomAbs_Circle) {
595       Handle(Geom2d_Circle) CCon = Handle(Geom2d_Circle)::DownCast(Con);
596       GccAna_Circ2d2TanOn CircAna(pnt1,pnt2,CCon->Circ2d(),Tolerance);
597       WellDone = CircAna.IsDone();
598       if (WellDone)
599       {
600         NbrSol = CircAna.NbSolutions();
601         for(Standard_Integer i=1; i<=NbrSol; i++) {
602           CircAna.WhichQualifier(i,qualifier1(i),qualifier2(i));
603         }
604         Results(CircAna);
605       }
606     }
607     else {
608       Handle(Geom2d_Line) LLon = Handle(Geom2d_Line)::DownCast(Con);
609       GccAna_Circ2d2TanOn CircAna(pnt1,pnt2,LLon->Lin2d(),Tolerance);
610       WellDone = CircAna.IsDone();
611       if (WellDone)
612       {
613         NbrSol = CircAna.NbSolutions();
614         for(Standard_Integer i=1; i<=NbrSol; i++) {
615           CircAna.WhichQualifier(i,qualifier1(i),qualifier2(i));
616         }
617         Results(CircAna);
618       }
619     }
620   }
621
622 //=============================================================================
623 //                            Appel a GccGeo.                                 +
624 //=============================================================================
625
626   else {
627     Geom2dGcc_Circ2d2TanOnGeo CircGeo(Point1->Pnt2d(),Point2->Pnt2d(),
628                                      OnCurve,Tolerance);
629     WellDone = CircGeo.IsDone();
630     if (WellDone)
631     {
632       NbrSol = CircGeo.NbSolutions();
633       for(Standard_Integer i=1; i<=NbrSol; i++) {
634         CircGeo.WhichQualifier(i,qualifier1(i),qualifier2(i));
635       }
636       Results(CircGeo);
637     }
638   }
639 }
640
641 void Geom2dGcc_Circ2d2TanOn::Results(const GccAna_Circ2d2TanOn& Circ)
642 {
643   for (Standard_Integer j = 1; j <= NbrSol; j++) {
644     cirsol(j)   = Circ.ThisSolution(j);
645     if (Circ.IsTheSame1(j)) { TheSame1(j) = 1; }
646     else {TheSame1(j) = 0; }
647     if (Circ.IsTheSame2(j)) { TheSame2(j) = 1; }
648     else {TheSame2(j) = 0; }
649     Circ.WhichQualifier(j,qualifier1(j),qualifier2(j));
650     Circ.Tangency1(j,par1sol(j),pararg1(j),pnttg1sol(j));
651     Circ.Tangency2(j,par2sol(j),pararg2(j),pnttg2sol(j));
652     Circ.CenterOn3(j,parcen3(j),pntcen(j));
653   }
654 }
655
656 void Geom2dGcc_Circ2d2TanOn::Results(const Geom2dGcc_Circ2d2TanOnGeo& Circ)
657 {
658   for (Standard_Integer j = 1; j <= NbrSol; j++) {
659     cirsol(j)   = Circ.ThisSolution(j);
660     if (Circ.IsTheSame1(j)) { TheSame1(j) = 1; }
661     else {TheSame1(j) = 0; }
662     if (Circ.IsTheSame2(j)) { TheSame2(j) = 1; }
663     else {TheSame2(j) = 0; }
664     Circ.WhichQualifier(j,qualifier1(j),qualifier2(j));
665     Circ.Tangency1(j,par1sol(j),pararg1(j),pnttg1sol(j));
666     Circ.Tangency2(j,par2sol(j),pararg2(j),pnttg2sol(j));
667     Circ.CenterOn3(j,parcen3(j),pntcen(j));
668   }
669 }
670
671 Standard_Boolean Geom2dGcc_Circ2d2TanOn::
672    IsDone () const { return WellDone; }
673
674 Standard_Integer Geom2dGcc_Circ2d2TanOn::
675   NbSolutions () const 
676
677   return NbrSol;
678 }
679
680 gp_Circ2d Geom2dGcc_Circ2d2TanOn::
681   ThisSolution (const Standard_Integer Index) const 
682 {
683   if (!WellDone) { StdFail_NotDone::Raise(); }
684   if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
685   return cirsol(Index);
686 }
687
688 void Geom2dGcc_Circ2d2TanOn::
689   WhichQualifier (const Standard_Integer Index   ,
690                         GccEnt_Position& Qualif1 ,
691                         GccEnt_Position& Qualif2) const
692 {
693   if (!WellDone) { StdFail_NotDone::Raise(); }
694   else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
695   else {
696     if (Invert) {
697       Qualif1 = qualifier2(Index);
698       Qualif2 = qualifier1(Index);
699     }
700     else {
701       Qualif1 = qualifier1(Index);
702       Qualif2 = qualifier2(Index);
703     }
704   }
705 }
706
707 void Geom2dGcc_Circ2d2TanOn::
708   Tangency1 (const Standard_Integer Index,
709                    Standard_Real&   ParSol,
710                    Standard_Real&   ParArg,
711                    gp_Pnt2d&        PntSol) const
712 {
713   if (!WellDone) { StdFail_NotDone::Raise(); }
714   else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
715   else {
716     if (Invert) {
717       if (TheSame2(Index) == 0) {
718         ParSol = par2sol(Index);
719         ParArg = pararg2(Index);
720         PntSol = pnttg2sol(Index);
721       }
722       else { StdFail_NotDone::Raise(); }
723     }
724     else {
725       if (TheSame1(Index) == 0) {
726         ParSol = par1sol(Index);
727         ParArg = pararg1(Index);
728         PntSol = pnttg1sol(Index);
729       }
730       else { StdFail_NotDone::Raise(); }
731     }
732   }
733 }
734
735 void Geom2dGcc_Circ2d2TanOn::
736    Tangency2 (const Standard_Integer Index,
737               Standard_Real& ParSol,
738               Standard_Real& ParArg,
739               gp_Pnt2d& PntSol) const
740 {
741   if (!WellDone) { StdFail_NotDone::Raise(); }
742   else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
743   else {
744     if (!Invert) {
745       if (TheSame2(Index) == 0) {
746         ParSol = par2sol(Index);
747         ParArg = pararg2(Index);
748         PntSol = pnttg2sol(Index);
749       }
750       else { StdFail_NotDone::Raise(); }
751     }
752     else {
753       if (TheSame1(Index) == 0) {
754         ParSol = par1sol(Index);
755         ParArg = pararg1(Index);
756         PntSol = pnttg1sol(Index);
757       }
758       else { StdFail_NotDone::Raise(); }
759     }
760   }
761 }
762
763 void Geom2dGcc_Circ2d2TanOn::
764    CenterOn3 (const Standard_Integer Index,
765               Standard_Real& ParArg,
766               gp_Pnt2d& PntSol) const
767 {
768   if (!WellDone) { StdFail_NotDone::Raise(); }
769   else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
770   else {
771     ParArg = parcen3(Index);
772     PntSol = pntcen(Index);
773   }
774 }
775
776 Standard_Boolean Geom2dGcc_Circ2d2TanOn::
777    IsTheSame1 (const Standard_Integer Index) const
778 {
779   if (!WellDone) { StdFail_NotDone::Raise(); }
780   if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
781   if (Invert) {
782     if (TheSame2(Index) == 0) { return Standard_False; }
783     else { return Standard_True; }
784   }
785   else {
786     if (TheSame1(Index) == 0) { return Standard_False; }
787     else { return Standard_True; }
788   }
789 }
790
791 Standard_Boolean Geom2dGcc_Circ2d2TanOn::
792    IsTheSame2 (const Standard_Integer Index) const
793 {
794   if (!WellDone) { StdFail_NotDone::Raise(); }
795   if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
796   if (!Invert) {
797     if (TheSame2(Index) == 0) { return Standard_False; }
798     else { return Standard_True; }
799     }
800   else {
801     if (TheSame1(Index) == 0) { return Standard_False; }
802     else { return Standard_True; }
803   }
804 //  return Standard_True;
805 }