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