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