0024773: Convertation of the generic classes to the non-generic. Part 7
[occt.git] / src / Geom2dGcc / Geom2dGcc_Circ2d2TanOnGeo.cxx
1 // Created on: 1991-12-13
2 // Created by: Remi GILET
3 // Copyright (c) 1991-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 //   Creation d un cercle tangent a deux elements : Droite.               +
19 //                                                  Cercle.               +
20 //                                                  Point.                +
21 //                                                  Courbes.              +
22 //                        centre sur un troisieme : Droite.               +
23 //                                                  Cercle.               +
24 //                                                  Courbes.              +
25 //=========================================================================
26
27 #include <Geom2dGcc_Circ2d2TanOnGeo.ixx>
28
29 #include <ElCLib.hxx>
30 #include <GccAna_Circ2dBisec.hxx>
31 #include <GccAna_CircLin2dBisec.hxx>
32 #include <GccAna_Lin2dBisec.hxx>
33 #include <GccAna_CircPnt2dBisec.hxx>
34 #include <GccAna_LinPnt2dBisec.hxx>
35 #include <GccAna_Pnt2dBisec.hxx>
36
37 #include <GccInt_BHyper.hxx>
38 #include <IntRes2d_IntersectionPoint.hxx>
39
40 #include <Standard_OutOfRange.hxx>
41 #include <StdFail_NotDone.hxx>
42
43 #include <Adaptor3d_OffsetCurve.hxx>
44 #include <Geom2dAdaptor_HCurve.hxx>
45 #include <Geom2dGcc_CurveToolGeo.hxx>
46 #include <Geom2dInt_TheIntConicCurveOfGInter.hxx>
47
48 Geom2dGcc_Circ2d2TanOnGeo::
49 Geom2dGcc_Circ2d2TanOnGeo (const GccEnt_QualifiedCirc&     Qualified1 ,
50                            const GccEnt_QualifiedCirc&     Qualified2 ,
51                            const Geom2dAdaptor_Curve&      OnCurv     ,
52                            const Standard_Real             Tolerance  ):
53   cirsol(1,8)    ,
54   qualifier1(1,8),
55   qualifier2(1,8),
56   TheSame1(1,8)  ,
57   TheSame2(1,8)  ,
58   pnttg1sol(1,8) ,
59   pnttg2sol(1,8) ,
60   pntcen(1,8)    ,
61   par1sol(1,8)   ,
62   par2sol(1,8)   ,
63   pararg1(1,8)   ,
64   pararg2(1,8)   ,
65   parcen3(1,8)   
66 {
67   WellDone = Standard_False;
68   Standard_Real thefirst = -100000.;
69   Standard_Real thelast  =  100000.;
70   Standard_Real firstparam;
71   Standard_Real lastparam;
72   Standard_Real Tol = Abs(Tolerance);
73   NbrSol = 0;
74   TColStd_Array1OfReal Rbid(1,2);
75   TColStd_Array1OfReal RBid(1,2);
76   TColStd_Array1OfReal Radius(1,2);
77   if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() || 
78     Qualified1.IsOutside() || Qualified1.IsUnqualified()) ||
79     !(Qualified2.IsEnclosed() || Qualified2.IsEnclosing() || 
80     Qualified2.IsOutside() || Qualified2.IsUnqualified())) {
81       GccEnt_BadQualifier::Raise();
82       return;
83   }
84   gp_Circ2d C1 = Qualified1.Qualified();
85   gp_Circ2d C2 = Qualified2.Qualified();
86   Standard_Real R1 = C1.Radius();
87   Standard_Real R2 = C2.Radius();
88   gp_Dir2d dirx(1.,0.);
89   gp_Pnt2d center1(C1.Location());
90   gp_Pnt2d center2(C2.Location());
91   GccAna_Circ2dBisec Bis(C1,C2);
92   if (Bis.IsDone()) {
93     Geom2dInt_TheIntConicCurveOfGInter Intp;
94     Standard_Integer nbsolution = Bis.NbSolutions();
95     Handle(Geom2dAdaptor_HCurve) HCu2 = new Geom2dAdaptor_HCurve(OnCurv); 
96     Adaptor3d_OffsetCurve Cu2(HCu2,0.);
97     firstparam = Max(Geom2dGcc_CurveToolGeo::FirstParameter(Cu2),thefirst);
98     lastparam  = Min(Geom2dGcc_CurveToolGeo::LastParameter(Cu2),thelast);
99     IntRes2d_Domain D2(Geom2dGcc_CurveToolGeo::Value(Cu2,firstparam),firstparam,Tol,
100       Geom2dGcc_CurveToolGeo::Value(Cu2,lastparam),lastparam,Tol);
101     Standard_Real Tol1 = Abs(Tolerance);
102     Standard_Real Tol2 = Tol1;
103     for (Standard_Integer i = 1 ; i <=  nbsolution; i++) {
104       Handle(GccInt_Bisec) Sol = Bis.ThisSolution(i);
105       GccInt_IType type = Sol->ArcType();
106       switch (type) {
107       case GccInt_Cir:
108         {
109           gp_Circ2d Circ(Sol->Circle());
110           IntRes2d_Domain D1(ElCLib::Value(0.,Circ),   0.,Tol1,
111             ElCLib::Value(2.*M_PI,Circ),2.*M_PI,Tol2);
112           D1.SetEquivalentParameters(0.,2.*M_PI);
113           Intp.Perform(Circ,D1,Cu2,D2,Tol1,Tol2);
114         }
115         break;
116       case GccInt_Ell:
117         {
118           gp_Elips2d Elips(Sol->Ellipse());
119           IntRes2d_Domain D1(ElCLib::Value(0.,Elips),   0.,Tol1,
120             ElCLib::Value(2.*M_PI,Elips),2.*M_PI,Tol2);
121           D1.SetEquivalentParameters(0.,2.*M_PI);
122           Intp.Perform(Elips,D1,Cu2,D2,Tol1,Tol2);
123         }
124         break;
125       case GccInt_Hpr:
126         {
127           gp_Hypr2d Hypr(Sol->Hyperbola());
128           IntRes2d_Domain D1(ElCLib::Value(-4.,Hypr),-4.,Tol1,
129             ElCLib::Value(4.,Hypr),4.,Tol2);
130           Intp.Perform(Hypr,D1,Cu2,D2,Tol1,Tol2);
131         }
132         break;
133       case GccInt_Lin:
134         {
135           gp_Lin2d Line(Sol->Line());
136           IntRes2d_Domain D1;
137           Intp.Perform(Line,D1,Cu2,D2,Tol1,Tol2);
138         }
139         break;
140       default:
141         {
142           Standard_ConstructionError::Raise();
143         }
144       }
145       if (Intp.IsDone()) {
146         if ((!Intp.IsEmpty())) {
147           for (Standard_Integer j = 1 ; j <= Intp.NbPoints() ; j++) {
148             gp_Pnt2d Center(Intp.Point(j).Value());
149             Standard_Real dist1 = Center.Distance(C1.Location());
150             Standard_Real dist2 = Center.Distance(C2.Location());
151             Standard_Integer nbsol = 0;
152             Standard_Integer nnsol = 0;
153             R1 = C1.Radius();
154             R2 = C2.Radius();
155             if (Qualified1.IsEnclosed()) {
156               if (dist1-R1 < Tol) { 
157                 nbsol = 1;
158                 Rbid(1) = Abs(R1-dist1);
159               }
160             }
161             else if (Qualified1.IsOutside()) {
162               if (R1-dist1 < Tol) { 
163                 nbsol = 1;
164                 Rbid(1) = Abs(dist1-R1);
165               }
166             }
167             else if (Qualified1.IsEnclosing()) {
168               nbsol = 1;
169               Rbid(1) = dist1+R1;
170             }
171             else if (Qualified1.IsUnqualified()) {
172               nbsol = 2;
173               Rbid(1) = dist1+R1;
174               Rbid(1) = Abs(dist1-R1);
175             }
176             if (Qualified2.IsEnclosed() && nbsol != 0) {
177               if (dist2-R2 < Tol) {
178                 RBid(1) = Abs(R2-dist2);
179               }
180             }
181             else if (Qualified2.IsOutside() && nbsol != 0) {
182               if (R2-dist2 < Tol) {
183                 RBid(1) = Abs(R2-dist2);
184               }
185             }
186             else if (Qualified2.IsEnclosing() && nbsol != 0) {
187               RBid(1) = dist2+R2;
188             }
189             else if (Qualified2.IsUnqualified() && nbsol != 0) {
190               RBid(1) = dist2+R2;
191               RBid(2) = Abs(R2-dist2);
192             }
193             for (Standard_Integer isol = 1; isol <= nbsol ; isol++) {
194               for (Standard_Integer jsol = 1; jsol <= nbsol ; jsol++) {
195                 if (Abs(Rbid(isol)-RBid(jsol)) <= Tol) {
196                   nnsol++;
197                   Radius(nnsol) = (RBid(jsol)+Rbid(isol))/2.;
198                 }
199               }
200             }
201             if (nnsol > 0) {
202               for (Standard_Integer k = 1 ; k <= nnsol ; k++) {
203                 NbrSol++;
204                 cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius(k));
205                 //              ==========================================================
206                 Standard_Real distcc1 = Center.Distance(center1);
207                 Standard_Real distcc2 = Center.Distance(center2);
208                 if (!Qualified1.IsUnqualified()) { 
209                   qualifier1(NbrSol) = Qualified1.Qualifier();
210                 }
211                 else if (Abs(distcc1+Radius(i)-R1) < Tol) {
212                   qualifier1(NbrSol) = GccEnt_enclosed;
213                 }
214                 else if (Abs(distcc1-R1-Radius(i)) < Tol) {
215                   qualifier1(NbrSol) = GccEnt_outside;
216                 }
217                 else { qualifier1(NbrSol) = GccEnt_enclosing; }
218                 if (!Qualified2.IsUnqualified()) { 
219                   qualifier2(NbrSol) = Qualified2.Qualifier();
220                 }
221                 else if (Abs(distcc2+Radius(i)-R2) < Tol) {
222                   qualifier2(NbrSol) = GccEnt_enclosed;
223                 }
224                 else if (Abs(distcc2-R2-Radius(i)) < Tol) {
225                   qualifier2(NbrSol) = GccEnt_outside;
226                 }
227                 else { qualifier2(NbrSol) = GccEnt_enclosing; }
228                 if (dist1 <= Tol && Abs(Radius(k)-C1.Radius()) <= Tol) {
229                   TheSame1(NbrSol) = 1;
230                 }
231                 else {
232                   TheSame1(NbrSol) = 0;
233                   gp_Dir2d dc1(C1.Location().XY()-Center.XY());
234                   pnttg1sol(NbrSol)=gp_Pnt2d(Center.XY()+Radius(k)*dc1.XY());
235                   par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
236                     pnttg1sol(NbrSol));
237                   pararg1(NbrSol)=ElCLib::Parameter(C1,pnttg1sol(NbrSol));
238                 }
239                 if (dist2 <= Tol && Abs(Radius(k)-C2.Radius()) <= Tol) {
240                   TheSame2(NbrSol) = 1;
241                 }
242                 else {
243                   TheSame2(NbrSol) = 0;
244                   gp_Dir2d dc2(C2.Location().XY()-Center.XY());
245                   pnttg2sol(NbrSol)=gp_Pnt2d(Center.XY()+Radius(k)*dc2.XY());
246                   par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
247                     pnttg2sol(NbrSol));
248                   pararg2(NbrSol)=ElCLib::Parameter(C2,pnttg2sol(NbrSol));
249                 }
250                 pntcen(NbrSol) = Center;
251                 parcen3(NbrSol) = Intp.Point(j).ParamOnSecond();
252               }
253               WellDone = Standard_True;
254             }
255           }
256         }
257       }
258     }
259   }
260 }
261
262 //=========================================================================
263 //   Creation d un cercle tangent a un Cercle C1 et a une Droite L2.      +
264 //                        centre sur une courbe OnCurv.                   +
265 //  Nous calculons les bissectrices a C1 et L2 qui nous donnent           +
266 //  l ensemble des lieux possibles des centres de tous les cercles        +
267 //  tangents a C1 et L2.                                                  +
268 //  Nous intersectons ces bissectrices avec la courbe OnCurv ce qui nous  +
269 //  donne les points parmis lesquels nous allons choisir les solutions.   +
270 //  Les choix s effectuent a partir des Qualifieurs qualifiant C1 et L2.  +
271 //=========================================================================
272
273 Geom2dGcc_Circ2d2TanOnGeo::
274 Geom2dGcc_Circ2d2TanOnGeo (const GccEnt_QualifiedCirc&     Qualified1 , 
275                            const GccEnt_QualifiedLin&      Qualified2 , 
276                            const Geom2dAdaptor_Curve&                 OnCurv     ,
277                            const Standard_Real             Tolerance  ):
278 cirsol(1,8)    ,
279 qualifier1(1,8),
280 qualifier2(1,8),
281 TheSame1(1,8)  ,
282 TheSame2(1,8)  ,
283 pnttg1sol(1,8) ,
284 pnttg2sol(1,8) ,
285 pntcen(1,8)    ,
286 par1sol(1,8)   ,
287 par2sol(1,8)   ,
288 pararg1(1,8)   ,
289 pararg2(1,8)   ,
290 parcen3(1,8)   
291 {
292
293   WellDone = Standard_False;
294   Standard_Real thefirst = -100000.;
295   Standard_Real thelast  =  100000.;
296   Standard_Real firstparam;
297   Standard_Real lastparam;
298   NbrSol = 0;
299   Standard_Real Tol = Abs(Tolerance);
300   Standard_Real Radius;
301   if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() || 
302     Qualified1.IsOutside() || Qualified1.IsUnqualified()) ||
303     !(Qualified2.IsEnclosed() ||
304     Qualified2.IsOutside() || Qualified2.IsUnqualified())) {
305       GccEnt_BadQualifier::Raise();
306       return;
307   }
308   gp_Dir2d dirx(1.,0.);
309   gp_Circ2d C1 = Qualified1.Qualified();
310   gp_Lin2d L2 = Qualified2.Qualified();
311   Standard_Real R1 = C1.Radius();
312   gp_Pnt2d center1(C1.Location());
313   gp_Pnt2d origin2(L2.Location());
314   gp_Dir2d dir2(L2.Direction());
315   gp_Dir2d normL2(-dir2.Y(),dir2.X());
316
317   GccAna_CircLin2dBisec Bis(C1,L2);
318   if (Bis.IsDone()) {
319     Standard_Real Tol1 = Abs(Tolerance);
320     Standard_Real Tol2 = Tol1;
321     Geom2dInt_TheIntConicCurveOfGInter Intp;
322     Standard_Integer nbsolution = Bis.NbSolutions();
323     Handle(Geom2dAdaptor_HCurve) HCu2 = new Geom2dAdaptor_HCurve(OnCurv); 
324     Adaptor3d_OffsetCurve C2(HCu2,0.);
325     firstparam = Max(Geom2dGcc_CurveToolGeo::FirstParameter(C2),thefirst);
326     lastparam  = Min(Geom2dGcc_CurveToolGeo::LastParameter(C2),thelast);
327     IntRes2d_Domain D2(Geom2dGcc_CurveToolGeo::Value(C2,firstparam),firstparam,Tol,
328       Geom2dGcc_CurveToolGeo::Value(C2,lastparam),lastparam,Tol);
329     for (Standard_Integer i = 1 ; i <=  nbsolution; i++) {
330       Handle(GccInt_Bisec) Sol = Bis.ThisSolution(i);
331       GccInt_IType type = Sol->ArcType();
332       switch (type) {
333       case GccInt_Lin:
334         {
335           gp_Lin2d Line(Sol->Line());
336           IntRes2d_Domain D1;
337           Intp.Perform(Line,D1,C2,D2,Tol1,Tol2);
338         }
339         break;
340       case GccInt_Par:
341         {
342           gp_Parab2d Parab(Sol->Parabola());
343           IntRes2d_Domain D1(ElCLib::Value(-40,Parab),-40,Tol1,
344             ElCLib::Value(40,Parab),40,Tol1);
345           Intp.Perform(Parab,D1,C2,D2,Tol1,Tol2);
346         }
347         break;
348       default:
349         {
350           Standard_ConstructionError::Raise();
351         }
352       }
353       if (Intp.IsDone()) {
354         if (!Intp.IsEmpty()) {
355           for (Standard_Integer j = 1 ; j <= Intp.NbPoints() ; j++) {
356             gp_Pnt2d Center(Intp.Point(j).Value());
357             Standard_Real dist1 = Center.Distance(center1);
358             //      Standard_Integer nbsol = 1;
359             Standard_Boolean ok = Standard_False;
360             if (Qualified1.IsEnclosed()) {
361               if (dist1-R1 < Tol) { ok = Standard_True; }
362             }
363             else if (Qualified1.IsOutside()) {
364               if (R1-dist1 < Tol) { ok = Standard_True; }
365             }
366             else if (Qualified1.IsEnclosing() || Qualified1.IsUnqualified()) {
367               ok = Standard_True;
368             }
369             Radius = L2.Distance(Center);
370             if (Qualified2.IsEnclosed() && ok) {
371               ok = Standard_False;
372               if ((((origin2.X()-Center.X())*(-dir2.Y()))+
373                 ((origin2.Y()-Center.Y())*(dir2.X())))<=0){
374                   ok = Standard_True;
375               }
376             }
377             else if (Qualified2.IsOutside() && ok) {
378               ok = Standard_False;
379               if ((((origin2.X()-Center.X())*(-dir2.Y()))+
380                 ((origin2.Y()-Center.Y())*(dir2.X())))>=0){
381                   ok = Standard_True;
382               }
383             }
384             if (Qualified1.IsEnclosing()&&dist1>Radius) { ok=Standard_False; }
385             if (ok) {
386               NbrSol++;
387               cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
388               //            =======================================================
389 #ifdef DEB
390               gp_Dir2d dc1(center1.XY()-Center.XY());
391 #endif
392               gp_Dir2d dc2(origin2.XY()-Center.XY());
393               Standard_Real distcc1 = Center.Distance(center1);
394               if (!Qualified1.IsUnqualified()) { 
395                 qualifier1(NbrSol) = Qualified1.Qualifier();
396               }
397               else if (Abs(distcc1+Radius-R1) < Tol) {
398                 qualifier1(NbrSol) = GccEnt_enclosed;
399               }
400               else if (Abs(distcc1-R1-Radius) < Tol) {
401                 qualifier1(NbrSol) = GccEnt_outside;
402               }
403               else { qualifier1(NbrSol) = GccEnt_enclosing; }
404               if (!Qualified2.IsUnqualified()) { 
405                 qualifier2(NbrSol) = Qualified2.Qualifier();
406               }
407               else if (dc2.Dot(normL2) > 0.0) {
408                 qualifier2(NbrSol) = GccEnt_outside;
409               }
410               else { qualifier2(NbrSol) = GccEnt_enclosed; }
411               if (dist1 <= Tol && Abs(Radius-C1.Radius()) <= Tol) {
412                 TheSame1(NbrSol) = 1;
413               }
414               else {
415                 TheSame1(NbrSol) = 0;
416                 gp_Dir2d dc1(center1.XY()-Center.XY());
417                 pnttg1sol(NbrSol)=gp_Pnt2d(Center.XY()+Radius*dc1.XY());
418                 par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
419                   pnttg1sol(NbrSol));
420                 pararg1(NbrSol)=ElCLib::Parameter(C1,pnttg1sol(NbrSol));
421               }
422               TheSame2(NbrSol) = 0;
423               Standard_Real sign = dc2.Dot(gp_Dir2d(-dir2.Y(),dir2.X()));
424               dc2 = gp_Dir2d(sign*gp_XY(-dir2.Y(),dir2.X()));
425               pnttg2sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius*dc2.XY());
426               par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
427                 pnttg2sol(NbrSol));
428               pararg2(NbrSol)=ElCLib::Parameter(L2,pnttg2sol(NbrSol));
429               pntcen(NbrSol) = Center;
430               parcen3(NbrSol) = Intp.Point(j).ParamOnSecond();
431             }
432           }
433         }
434         WellDone = Standard_True;
435       }
436     }
437   }
438 }
439
440 //=========================================================================
441 //   Creation d un cercle tant a deux Droites L1 et L2.                +
442 //                        centre sur une courbe OnCurv.                   +
443 //  Nous calculons les bissectrices a L1 et L2 qui nous donnent           +
444 //  l ensemble des lieux possibles des centres de tous les cercles        +
445 //  tants a L1 et L2.                                                  +
446 //  Nous intersectons ces bissectrices avec la courbe OnCurv ce qui nous  +
447 //  donne les points parmis lesquels nous allons choisir les solutions.   +
448 //  Les choix s effectuent a partir des Qualifieurs qualifiant L1 et L2.  +
449 //=========================================================================
450
451 Geom2dGcc_Circ2d2TanOnGeo::
452 Geom2dGcc_Circ2d2TanOnGeo (const GccEnt_QualifiedLin&      Qualified1 , 
453                            const GccEnt_QualifiedLin&      Qualified2 , 
454                            const Geom2dAdaptor_Curve&                 OnCurv     ,
455                            const Standard_Real             Tolerance  ):
456 cirsol(1,8)    ,
457 qualifier1(1,8),
458 qualifier2(1,8),
459 TheSame1(1,8)  ,
460 TheSame2(1,8)  ,
461 pnttg1sol(1,8) ,
462 pnttg2sol(1,8) ,
463 pntcen(1,8)    ,
464 par1sol(1,8)   ,
465 par2sol(1,8)   ,
466 pararg1(1,8)   ,
467 pararg2(1,8)   ,
468 parcen3(1,8)   
469 {
470
471   WellDone = Standard_False;
472   Standard_Real thefirst = -100000.;
473   Standard_Real thelast  =  100000.;
474   Standard_Real firstparam;
475   Standard_Real lastparam;
476   NbrSol = 0;
477   if (!(Qualified1.IsEnclosed() || 
478     Qualified1.IsOutside() || Qualified1.IsUnqualified()) ||
479     !(Qualified2.IsEnclosed() ||
480     Qualified2.IsOutside() || Qualified2.IsUnqualified())) {
481       GccEnt_BadQualifier::Raise();
482       return;
483   }
484   Standard_Real Tol = Abs(Tolerance);
485   Standard_Real Radius=0;
486   gp_Dir2d dirx(1.,0.);
487   gp_Lin2d L1 = Qualified1.Qualified();
488   gp_Lin2d L2 = Qualified2.Qualified();
489   gp_Dir2d dir1(L1.Direction());
490   gp_Dir2d dir2(L2.Direction());
491   gp_Dir2d Dnor1(-dir1.Y(),dir1.X());
492   gp_Dir2d Dnor2(-dir2.Y(),dir2.X());
493   gp_Pnt2d origin1(L1.Location());
494   gp_Pnt2d origin2(L2.Location());
495   GccAna_Lin2dBisec Bis(L1,L2);
496   if (Bis.IsDone()) {
497     Standard_Real Tol1 = Abs(Tolerance);
498     Standard_Real Tol2 = Tol1;
499     Geom2dInt_TheIntConicCurveOfGInter Intp;
500     Standard_Integer nbsolution = Bis.NbSolutions();
501     Handle(Geom2dAdaptor_HCurve) HCu2 = new Geom2dAdaptor_HCurve(OnCurv); 
502     Adaptor3d_OffsetCurve C2(HCu2,0.);
503     firstparam = Max(Geom2dGcc_CurveToolGeo::FirstParameter(C2),thefirst);
504     lastparam  = Min(Geom2dGcc_CurveToolGeo::LastParameter(C2),thelast);
505     IntRes2d_Domain D2(Geom2dGcc_CurveToolGeo::Value(C2,firstparam),firstparam,Tol,
506       Geom2dGcc_CurveToolGeo::Value(C2,lastparam),lastparam,Tol);
507     IntRes2d_Domain D1;
508     for (Standard_Integer i = 1 ; i <=  nbsolution; i++) {
509       Intp.Perform(Bis.ThisSolution(i),D1,C2,D2,Tol1,Tol2);
510       if (Intp.IsDone()) {
511         if ((!Intp.IsEmpty())) {
512           for (Standard_Integer j = 1 ; j <= Intp.NbPoints() ; j++) {
513             gp_Pnt2d Center(Intp.Point(j).Value());
514             Standard_Real dist1 = L1.Distance(Center);
515             Standard_Real dist2 = L2.Distance(Center);
516             //      Standard_Integer nbsol = 1;
517             Standard_Boolean ok = Standard_False;
518             if (Qualified1.IsEnclosed()) {
519               if ((((origin1.X()-Center.X())*(-dir1.Y()))+
520                 ((origin1.Y()-Center.Y())*(dir1.X())))<=0){
521                   ok = Standard_True;
522               }
523             }
524             else if (Qualified1.IsOutside()) {
525               if ((((origin1.X()-Center.X())*(-dir1.Y()))+
526                 ((origin1.Y()-Center.Y())*(dir1.X())))>=0){
527                   ok = Standard_True;
528               }
529             }
530             else if (Qualified1.IsUnqualified()) { ok = Standard_True; }
531             if (Qualified2.IsEnclosed() && ok) {
532               ok = Standard_False;
533               if ((((origin2.X()-Center.X())*(-dir2.Y()))+
534                 ((origin2.Y()-Center.Y())*(dir2.X())))<=0){
535                   ok = Standard_True;
536                   Radius = (dist1+dist2)/2.;
537               }
538             }
539             else if (Qualified2.IsOutside() && ok) {
540               ok = Standard_False;
541               if ((((origin2.X()-Center.X())*(-dir2.Y()))+
542                 ((origin2.Y()-Center.Y())*(dir2.X())))>=0){
543                   ok = Standard_True;
544                   Radius = (dist1+dist2)/2.;
545               }
546             }
547             else if (Qualified2.IsUnqualified() && ok) {
548               Radius = (dist1+dist2)/2.;
549             }
550             if (ok) {
551               NbrSol++;
552               cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
553               //            =======================================================
554               gp_Dir2d dc1(origin1.XY()-Center.XY());
555               gp_Dir2d dc2(origin2.XY()-Center.XY());
556               if (!Qualified1.IsUnqualified()) { 
557                 qualifier1(NbrSol) = Qualified1.Qualifier();
558               }
559               else if (dc1.Dot(Dnor1) > 0.0) {
560                 qualifier1(NbrSol) = GccEnt_outside;
561               }
562               else { qualifier1(NbrSol) = GccEnt_enclosed; }
563               if (!Qualified2.IsUnqualified()) { 
564                 qualifier2(NbrSol) = Qualified2.Qualifier();
565               }
566               else if (dc2.Dot(Dnor2) > 0.0) {
567                 qualifier2(NbrSol) = GccEnt_outside;
568               }
569               else { qualifier2(NbrSol) = GccEnt_enclosed; }
570               TheSame1(NbrSol) = 0;
571               TheSame2(NbrSol) = 0;
572               Standard_Real sign = dc1.Dot(Dnor1);
573               dc1 = gp_Dir2d(sign*gp_XY(-dir1.Y(),dir1.X()));
574               pnttg1sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius*dc1.XY());
575               par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
576                 pnttg1sol(NbrSol));
577               pararg1(NbrSol)=ElCLib::Parameter(L1,pnttg1sol(NbrSol));
578               sign = dc2.Dot(gp_Dir2d(-dir2.Y(),dir2.X()));
579               dc2 = gp_Dir2d(sign*gp_XY(-dir2.Y(),dir2.X()));
580               pnttg2sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius*dc2.XY());
581               par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
582                 pnttg2sol(NbrSol));
583               pararg2(NbrSol)=ElCLib::Parameter(L2,pnttg2sol(NbrSol));
584               pntcen(NbrSol) = Center;
585               parcen3(NbrSol) = Intp.Point(j).ParamOnSecond();
586             }
587           }
588         }
589         WellDone = Standard_True;
590       }
591     }
592   }
593 }
594
595 //=========================================================================
596 //   Creation d un cercle tant a un Cercle C1, passant par un point P2 +
597 //                        centre sur une courbe OnCurv.                   +
598 //  Nous calculons les bissectrices a C1 et Point2 qui nous donnent       +
599 //  l ensemble des lieux possibles des centres de tous les cercles        +
600 //  tants a C1 et Point2.                                              +
601 //  Nous intersectons ces bissectrices avec la courbe OnCurv ce qui nous  +
602 //  donne les points parmis lesquels nous allons choisir les solutions.   +
603 //  Les choix s effectuent a partir des Qualifieurs qualifiant C1.        +
604 //=========================================================================
605
606 Geom2dGcc_Circ2d2TanOnGeo::
607 Geom2dGcc_Circ2d2TanOnGeo (const GccEnt_QualifiedCirc&     Qualified1 , 
608                            const gp_Pnt2d&                 Point2     , 
609                            const Geom2dAdaptor_Curve&                 OnCurv     ,
610                            const Standard_Real             Tolerance  ):
611 cirsol(1,8)    ,
612 qualifier1(1,8),
613 qualifier2(1,8),
614 TheSame1(1,8)  ,
615 TheSame2(1,8)  ,
616 pnttg1sol(1,8) ,
617 pnttg2sol(1,8) ,
618 pntcen(1,8)    ,
619 par1sol(1,8)   ,
620 par2sol(1,8)   ,
621 pararg1(1,8)   ,
622 pararg2(1,8)   ,
623 parcen3(1,8)   
624 {
625
626   WellDone = Standard_False;
627   Standard_Real thefirst = -100000.;
628   Standard_Real thelast  =  100000.;
629   Standard_Real firstparam;
630   Standard_Real lastparam;
631   NbrSol = 0;
632   if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() || 
633     Qualified1.IsOutside() || Qualified1.IsUnqualified())) {
634       GccEnt_BadQualifier::Raise();
635       return;
636   }
637   Standard_Real Tol = Abs(Tolerance);
638   Standard_Real Radius;
639   gp_Dir2d dirx(1.,0.);
640   gp_Circ2d C1 = Qualified1.Qualified();
641   Standard_Real R1 = C1.Radius();
642   gp_Pnt2d center1(C1.Location());
643   GccAna_CircPnt2dBisec Bis(C1,Point2);
644   if (Bis.IsDone()) {
645     Standard_Real Tol1 = Abs(Tolerance);
646     Standard_Real Tol2 = Tol1;
647     Geom2dInt_TheIntConicCurveOfGInter Intp;
648     Standard_Integer nbsolution = Bis.NbSolutions();
649     Handle(Geom2dAdaptor_HCurve) HCu2 = new Geom2dAdaptor_HCurve(OnCurv); 
650     Adaptor3d_OffsetCurve C2(HCu2,0.);
651     firstparam = Max(Geom2dGcc_CurveToolGeo::FirstParameter(C2),thefirst);
652     lastparam  = Min(Geom2dGcc_CurveToolGeo::LastParameter(C2),thelast);
653     IntRes2d_Domain D2(Geom2dGcc_CurveToolGeo::Value(C2,firstparam),firstparam,Tol,
654       Geom2dGcc_CurveToolGeo::Value(C2,lastparam),lastparam,Tol);
655     for (Standard_Integer i = 1 ; i <=  nbsolution; i++) {
656       Handle(GccInt_Bisec) Sol = Bis.ThisSolution(i);
657       GccInt_IType type = Sol->ArcType();
658       switch (type) {
659       case GccInt_Cir:
660         {
661           gp_Circ2d Circ(Sol->Circle());
662           IntRes2d_Domain D1(ElCLib::Value(0.,Circ),   0.,Tol1,
663             ElCLib::Value(2.*M_PI,Circ),2.*M_PI,Tol2);
664           D1.SetEquivalentParameters(0.,2.*M_PI);
665           Intp.Perform(Circ,D1,C2,D2,Tol1,Tol2);
666         }
667         break;
668       case GccInt_Lin:
669         {
670           gp_Lin2d Line(Sol->Line());
671           IntRes2d_Domain D1;
672           Intp.Perform(Line,D1,C2,D2,Tol1,Tol2);
673         }
674         break;
675       case GccInt_Ell:
676         {
677           gp_Elips2d Elips(Sol->Ellipse());
678           IntRes2d_Domain D1(ElCLib::Value(0.,Elips),   0.,Tol1,
679             ElCLib::Value(2.*M_PI,Elips),2.*M_PI,Tol2);
680           D1.SetEquivalentParameters(0.,2.*M_PI);
681           Intp.Perform(Elips,D1,C2,D2,Tol1,Tol2);
682         }
683         break;
684       case GccInt_Hpr:
685         {
686           gp_Hypr2d Hypr(Sol->Hyperbola());
687           IntRes2d_Domain D1(ElCLib::Value(-4.,Hypr),-4.,Tol1,
688             ElCLib::Value(4.,Hypr),4.,Tol2);
689           Intp.Perform(Hypr,D1,C2,D2,Tol1,Tol2);
690         }
691         break;
692       default:
693         {
694           Standard_ConstructionError::Raise();
695         }
696       }
697       if (Intp.IsDone()) {
698         if ((!Intp.IsEmpty())) {
699           for (Standard_Integer j = 1 ; j <= Intp.NbPoints() ; j++) {
700             gp_Pnt2d Center(Intp.Point(j).Value());
701             Radius = Center.Distance(Point2);
702             Standard_Real dist1 = center1.Distance(Center);
703             //      Standard_Integer nbsol = 1;
704             Standard_Boolean ok = Standard_False;
705             if (Qualified1.IsEnclosed()) {
706               if (dist1-R1 <= Tol) { ok = Standard_True; }
707             }
708             else if (Qualified1.IsOutside()) {
709               if (R1-dist1 <= Tol) { ok = Standard_True; }
710             }
711             else if (Qualified1.IsEnclosing()) { ok = Standard_True; }
712             else if (Qualified1.IsUnqualified()) { ok = Standard_True; }
713             if (ok) {
714               NbrSol++;
715               cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
716               //            =======================================================
717               Standard_Real distcc1 = Center.Distance(center1);
718               if (!Qualified1.IsUnqualified()) { 
719                 qualifier1(NbrSol) = Qualified1.Qualifier();
720               }
721               else if (Abs(distcc1+Radius-R1) < Tol) {
722                 qualifier1(NbrSol) = GccEnt_enclosed;
723               }
724               else if (Abs(distcc1-R1-Radius) < Tol) {
725                 qualifier1(NbrSol) = GccEnt_outside;
726               }
727               else { qualifier1(NbrSol) = GccEnt_enclosing; }
728               qualifier2(NbrSol) = GccEnt_noqualifier;
729               if (dist1 <= Tol && Abs(Radius-R1) <= Tol) {
730                 TheSame1(NbrSol) = 1;
731               }
732               else {
733                 TheSame1(NbrSol) = 0;
734                 gp_Dir2d dc1(center1.XY()-Center.XY());
735                 pnttg1sol(NbrSol)=gp_Pnt2d(Center.XY()+Radius*dc1.XY());
736                 par1sol(NbrSol) = 0.;
737                 par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
738                   pnttg1sol(NbrSol));
739                 pararg1(NbrSol)=ElCLib::Parameter(C1,pnttg1sol(NbrSol));
740               }
741               TheSame2(NbrSol) = 0;
742               pnttg2sol(NbrSol) = Point2;
743               pntcen(NbrSol) = Center;
744               parcen3(NbrSol) = Intp.Point(j).ParamOnSecond();
745               pararg2(NbrSol) = 0.;
746               par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
747                 pnttg2sol(NbrSol));
748             }
749           }
750         }
751         WellDone = Standard_True;
752       }
753     }
754   }
755 }
756
757 //=========================================================================
758 //   Creation d un cercle tant a une ligne L1, passant par un point P2 +
759 //                        centre sur une courbe OnCurv.                   +
760 //  Nous calculons les bissectrices a L1 et Point2 qui nous donnent       +
761 //  l ensemble des lieux possibles des centres de tous les cercles        +
762 //  tants a L1 et passant par Point2.                                  +
763 //  Nous intersectons ces bissectrices avec la courbe OnCurv ce qui nous  +
764 //  donne les points parmis lesquels nous allons choisir les solutions.   +
765 //  Les choix s effectuent a partir des Qualifieurs qualifiant L1.        +
766 //=========================================================================
767
768 Geom2dGcc_Circ2d2TanOnGeo::
769 Geom2dGcc_Circ2d2TanOnGeo (const GccEnt_QualifiedLin&      Qualified1 , 
770                            const gp_Pnt2d&                 Point2     , 
771                            const Geom2dAdaptor_Curve&                 OnCurv     ,
772                            const Standard_Real             Tolerance  ):
773 cirsol(1,8)    ,
774 qualifier1(1,8),
775 qualifier2(1,8),
776 TheSame1(1,8)  ,
777 TheSame2(1,8)  ,
778 pnttg1sol(1,8) ,
779 pnttg2sol(1,8) ,
780 pntcen(1,8)    ,
781 par1sol(1,8)   ,
782 par2sol(1,8)   ,
783 pararg1(1,8)   ,
784 pararg2(1,8)   ,
785 parcen3(1,8)   
786 {
787
788   WellDone = Standard_False;
789   Standard_Real thefirst = -100000.;
790   Standard_Real thelast  =  100000.;
791   Standard_Real firstparam;
792   Standard_Real lastparam;
793   Standard_Real Tol = Abs(Tolerance);
794   NbrSol = 0;
795   if (!(Qualified1.IsEnclosed() ||
796     Qualified1.IsOutside() || Qualified1.IsUnqualified())) {
797       GccEnt_BadQualifier::Raise();
798       return;
799   }
800   gp_Dir2d dirx(1.,0.);
801   gp_Lin2d L1 = Qualified1.Qualified();
802   gp_Pnt2d origin1(L1.Location());
803   gp_Dir2d dir1(L1.Direction());
804   gp_Dir2d normal(-dir1.Y(),dir1.X());
805   GccAna_LinPnt2dBisec Bis(L1,Point2);
806   if (Bis.IsDone()) {
807     Standard_Real Tol1 = Abs(Tolerance);
808     Standard_Real Tol2 = Tol1;
809     Geom2dInt_TheIntConicCurveOfGInter Intp;
810     Handle(Geom2dAdaptor_HCurve) HCu2 = new Geom2dAdaptor_HCurve(OnCurv); 
811     Adaptor3d_OffsetCurve C2(HCu2,0.);
812     firstparam = Max(Geom2dGcc_CurveToolGeo::FirstParameter(C2),thefirst);
813     lastparam  = Min(Geom2dGcc_CurveToolGeo::LastParameter(C2),thelast);
814     IntRes2d_Domain D2(Geom2dGcc_CurveToolGeo::Value(C2,firstparam),firstparam,Tol,
815       Geom2dGcc_CurveToolGeo::Value(C2,lastparam),lastparam,Tol);
816     Handle(GccInt_Bisec) Sol = Bis.ThisSolution();
817     GccInt_IType type = Sol->ArcType();
818     switch (type) {
819     case GccInt_Lin:
820       {
821         gp_Lin2d Line(Sol->Line());
822         IntRes2d_Domain D1;
823         Intp.Perform(Line,D1,C2,D2,Tol1,Tol2);
824       }
825       break;
826     case GccInt_Par:
827       {
828         gp_Parab2d Parab(Sol->Parabola());
829         IntRes2d_Domain D1(ElCLib::Value(-40,Parab),-40,Tol1,
830           ElCLib::Value(40,Parab),40,Tol1);
831         Intp.Perform(Parab,D1,C2,D2,Tol1,Tol2);
832       }
833       break;
834     default:
835       {
836         Standard_ConstructionError::Raise();
837       }
838     }
839     if (Intp.IsDone()) {
840       if ((!Intp.IsEmpty())) {
841         for (Standard_Integer j = 1 ; j <= Intp.NbPoints() ; j++) {
842           gp_Pnt2d Center(Intp.Point(j).Value());
843           Standard_Real Radius = L1.Distance(Center);
844           //      Standard_Integer nbsol = 1;
845           Standard_Boolean ok = Standard_False;
846           if (Qualified1.IsEnclosed()) {
847             if ((((origin1.X()-Center.X())*(-dir1.Y()))+
848               ((origin1.Y()-Center.Y())*(dir1.X())))<=0){
849                 ok = Standard_True;
850             }
851           }
852           else if (Qualified1.IsOutside()) {
853             if ((((origin1.X()-Center.X())*(-dir1.Y()))+
854               ((origin1.Y()-Center.Y())*(dir1.X())))>=0){
855                 ok = Standard_True;
856             }
857           }
858           else if (Qualified1.IsUnqualified()) { ok = Standard_True; }
859           if (ok) {
860             NbrSol++;
861             cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
862             //          =======================================================
863             qualifier2(NbrSol) = GccEnt_noqualifier;
864             gp_Dir2d dc2(origin1.XY()-Center.XY());
865             if (!Qualified1.IsUnqualified()) { 
866               qualifier1(NbrSol) = Qualified1.Qualifier();
867             }
868             else if (dc2.Dot(normal) > 0.0) {
869               qualifier1(NbrSol) = GccEnt_outside;
870             }
871             else { qualifier1(NbrSol) = GccEnt_enclosed; }
872             TheSame1(NbrSol) = 0;
873             TheSame2(NbrSol) = 0;
874             gp_Dir2d dc1(origin1.XY()-Center.XY());
875             Standard_Real sign = dc1.Dot(gp_Dir2d(-dir1.Y(),dir1.X()));
876             dc1=gp_Dir2d(sign*gp_XY(-dir1.Y(),dir1.X()));
877             pnttg1sol(NbrSol) = gp_Pnt2d(Center.XY()+Radius*dc1.XY());
878             par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
879               pnttg1sol(NbrSol));
880             pararg1(NbrSol)=ElCLib::Parameter(L1,pnttg1sol(NbrSol));
881             pnttg2sol(NbrSol) = Point2;
882             par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
883               pnttg2sol(NbrSol));
884             pararg2(NbrSol) = 0.;
885             pntcen(NbrSol) = Center;
886             parcen3(NbrSol) = Intp.Point(j).ParamOnSecond();
887           }
888         }
889       }
890       WellDone = Standard_True;
891     }
892   }
893 }
894
895 //=========================================================================
896 //   Creation d un cercle passant par deux point Point1 et Point2         +
897 //                        centre sur une courbe OnCurv.                   +
898 //  Nous calculons les bissectrices a Point1 et Point2 qui nous donnent   +
899 //  l ensemble des lieux possibles des centres de tous les cercles        +
900 //  passant par Point1 et Point2.                                         +
901 //  Nous intersectons ces bissectrices avec la courbe OnCurv ce qui nous  +
902 //  donne les points parmis lesquels nous allons choisir les solutions.   +
903 //=========================================================================
904
905 Geom2dGcc_Circ2d2TanOnGeo::
906 Geom2dGcc_Circ2d2TanOnGeo (const gp_Pnt2d&               Point1    ,
907                            const gp_Pnt2d&               Point2    ,
908                            const Geom2dAdaptor_Curve&               OnCurv    ,
909                            const Standard_Real           Tolerance ):
910 cirsol(1,8)    ,
911 qualifier1(1,8),
912 qualifier2(1,8),
913 TheSame1(1,8)  ,
914 TheSame2(1,8)  ,
915 pnttg1sol(1,8) ,
916 pnttg2sol(1,8) ,
917 pntcen(1,8)    ,
918 par1sol(1,8)   ,
919 par2sol(1,8)   ,
920 pararg1(1,8)   ,
921 pararg2(1,8)   ,
922 parcen3(1,8)   
923 {
924
925   WellDone = Standard_False;
926   Standard_Real thefirst = -100000.;
927   Standard_Real thelast  =  100000.;
928   Standard_Real firstparam;
929   Standard_Real lastparam;
930   Standard_Real Tol = Abs(Tolerance);
931   NbrSol = 0;
932   gp_Dir2d dirx(1.,0.);
933   GccAna_Pnt2dBisec Bis(Point1,Point2);
934   if (Bis.IsDone()) {
935     Standard_Real Tol1 = Abs(Tolerance);
936     Standard_Real Tol2 = Tol1;
937     Geom2dInt_TheIntConicCurveOfGInter Intp;
938     Handle(Geom2dAdaptor_HCurve) HCu2 = new Geom2dAdaptor_HCurve(OnCurv); 
939     Adaptor3d_OffsetCurve Cu2(HCu2,0.);
940     firstparam = Max(Geom2dGcc_CurveToolGeo::FirstParameter(Cu2),thefirst);
941     lastparam  = Min(Geom2dGcc_CurveToolGeo::LastParameter(Cu2),thelast);
942     IntRes2d_Domain D2(Geom2dGcc_CurveToolGeo::Value(Cu2,firstparam),firstparam,Tol,
943       Geom2dGcc_CurveToolGeo::Value(Cu2,lastparam),lastparam,Tol);
944     IntRes2d_Domain D1;
945     if (Bis.HasSolution()) {
946       Intp.Perform(Bis.ThisSolution(),D1,Cu2,D2,Tol1,Tol2);
947       if (Intp.IsDone()) {
948         if ((!Intp.IsEmpty())) {
949           for (Standard_Integer j = 1 ; j <= Intp.NbPoints() ; j++) {
950             gp_Pnt2d Center(Intp.Point(j).Value());
951             Standard_Real Radius = Point2.Distance(Center);
952             NbrSol++;
953             cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
954             //           =======================================================
955             qualifier1(NbrSol) = GccEnt_noqualifier;
956             qualifier2(NbrSol) = GccEnt_noqualifier;
957             TheSame1(NbrSol) = 0;
958             TheSame2(NbrSol) = 0;
959             pntcen(NbrSol) = Center;
960             pnttg1sol(NbrSol) = Point1;
961             pnttg2sol(NbrSol) = Point2;
962             pararg1(NbrSol) = 0.;
963             pararg2(NbrSol) = 0.;
964             par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
965               pnttg1sol(NbrSol));
966             par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
967               pnttg2sol(NbrSol));
968             parcen3(NbrSol) = Intp.Point(j).ParamOnSecond();
969           }
970         }
971         WellDone = Standard_True;
972       }
973     }
974   }
975 }
976
977 Standard_Boolean Geom2dGcc_Circ2d2TanOnGeo::
978 IsDone () const { return WellDone; }
979
980 Standard_Integer Geom2dGcc_Circ2d2TanOnGeo::
981 NbSolutions () const{ return NbrSol; }
982
983 gp_Circ2d Geom2dGcc_Circ2d2TanOnGeo::
984 ThisSolution (const Standard_Integer Index) const
985 {
986   if (!WellDone) { StdFail_NotDone::Raise(); }
987   if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
988
989   return cirsol(Index);
990 }
991
992 void Geom2dGcc_Circ2d2TanOnGeo::
993 WhichQualifier(const Standard_Integer Index   ,
994                GccEnt_Position& Qualif1 ,
995                GccEnt_Position& Qualif2 ) const
996 {
997   if (!WellDone) { StdFail_NotDone::Raise(); }
998   else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
999   else {
1000     Qualif1 = qualifier1(Index);
1001     Qualif2 = qualifier2(Index);
1002   }
1003 }
1004
1005 void Geom2dGcc_Circ2d2TanOnGeo:: 
1006 Tangency1 (const Standard_Integer    Index          , 
1007            Standard_Real&      ParSol         ,
1008            Standard_Real&      ParArg         ,
1009            gp_Pnt2d&           PntSol         ) const{
1010              if (!WellDone) { StdFail_NotDone::Raise(); }
1011              else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
1012              else {
1013                if (TheSame1(Index) == 0) {
1014                  ParSol = par1sol(Index);
1015                  ParArg = pararg1(Index);
1016                  PntSol = gp_Pnt2d(pnttg1sol(Index));
1017                }
1018                else { StdFail_NotDone::Raise(); }
1019              }
1020 }
1021
1022 void Geom2dGcc_Circ2d2TanOnGeo:: 
1023 Tangency2 (const Standard_Integer    Index          , 
1024            Standard_Real&      ParSol         ,
1025            Standard_Real&      ParArg         ,
1026            gp_Pnt2d&           PntSol         ) const{
1027              if (!WellDone) { StdFail_NotDone::Raise(); }
1028              else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
1029              else {
1030                if (TheSame2(Index) == 0) {
1031                  ParSol = par2sol(Index);
1032                  ParArg = pararg2(Index);
1033                  PntSol = gp_Pnt2d(pnttg2sol(Index));
1034                }
1035                else { StdFail_NotDone::Raise(); }
1036              }
1037 }
1038
1039 void Geom2dGcc_Circ2d2TanOnGeo::
1040 CenterOn3 (const Standard_Integer    Index          ,
1041            Standard_Real&      ParArg         ,
1042            gp_Pnt2d&           PntSol         ) const{
1043              if (!WellDone) { StdFail_NotDone::Raise(); }
1044              else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
1045              else {
1046                ParArg = parcen3(Index);
1047                PntSol = gp_Pnt2d(pntcen(Index));
1048              }
1049 }
1050
1051 Standard_Boolean Geom2dGcc_Circ2d2TanOnGeo::
1052 IsTheSame1 (const Standard_Integer Index) const
1053 {
1054   if (!WellDone) StdFail_NotDone::Raise();
1055   if (Index <= 0 ||Index > NbrSol) Standard_OutOfRange::Raise();
1056
1057   if (TheSame1(Index) == 0) 
1058     return Standard_False;
1059
1060   return Standard_True;
1061 }
1062
1063
1064 Standard_Boolean Geom2dGcc_Circ2d2TanOnGeo::
1065 IsTheSame2 (const Standard_Integer Index) const
1066 {
1067   if (!WellDone) StdFail_NotDone::Raise();
1068   if (Index <= 0 ||Index > NbrSol) Standard_OutOfRange::Raise();
1069
1070   if (TheSame2(Index) == 0)
1071     return Standard_False;
1072
1073   return Standard_True;
1074 }