0024773: Convertation of the generic classes to the non-generic. Part 7
[occt.git] / src / GccGeo / GccGeo_Circ2dTanOnRad.gxx
1 // Copyright (c) 1995-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15 //========================================================================
16 //       circulaire tangent a un element de type :  - Cercle.            +
17 //                                                  - Ligne.             +
18 //                                                  - Point.             +
19 //                  centre sur un deuxieme element de type :  - Cercle.  +
20 //                                                            - Ligne.   +
21 //                  de rayon donne : Radius.                             +
22 //========================================================================
23
24 #include <ElCLib.hxx>
25 #include <math_DirectPolynomialRoots.hxx>
26 #include <TColStd_Array1OfReal.hxx>
27 #include <Standard_NegativeValue.hxx>
28 #include <gp_Dir2d.hxx>
29 #include <Standard_OutOfRange.hxx>
30 #include <StdFail_NotDone.hxx>
31 #include <GccEnt_BadQualifier.hxx>
32 #include <IntRes2d_Domain.hxx>
33 #include <IntRes2d_IntersectionPoint.hxx>
34
35 //=========================================================================
36 //  Cercle tangent  :  a un cercle Qualified1 (C1).                       +
37 //         centre   :  sur une droite OnLine.                             +
38 //         de rayon :  Radius.                                            +
39 //                                                                        + 
40 //  On initialise le tableau de solutions cirsol ainsi que tous les       +
41 //  champs.                                                               +
42 //  On elimine en fonction du qualifieur les cas ne presentant pas de     +
43 //  solutions.                                                            +
44 //  On resoud l equation du second degre indiquant que le point de centre +
45 //  recherche (xc,yc) est a une distance Radius du cercle C1 et           +
46 //                        sur la droite OnLine.                           +
47 //  Les solutions sont representees par les cercles :                     +
48 //                   - de centre Pntcen(xc,yc)                            +
49 //                   - de rayon Radius.                                   +
50 //=========================================================================
51
52 GccGeo_Circ2dTanOnRad::
53    GccGeo_Circ2dTanOnRad (const TheQCurve&    Qualified1, 
54                           const gp_Lin2d&     OnLine    ,
55                           const Standard_Real Radius    ,
56                           const Standard_Real Tolerance ):
57
58 //=========================================================================
59 // Initialisation des champs.                                             +
60 //=========================================================================
61
62    cirsol(1,8)     ,
63    qualifier1(1,8) ,
64    TheSame1(1,8)   ,
65    pnttg1sol(1,8)  ,
66    pntcen3(1,8)    ,
67    par1sol(1,8)    ,
68    pararg1(1,8)    ,
69    parcen3(1,8)    
70 {
71
72 //=========================================================================
73 // Traitement.                                                            +
74 //=========================================================================
75
76    gp_Dir2d dirx(1.0,0.0);
77    Standard_Real Tol = Abs(Tolerance);
78    Standard_Real thefirst = -100000.;
79    Standard_Real thelast  =  100000.;
80    Standard_Real firstparam;
81    Standard_Real lastparam;
82    WellDone = Standard_False;
83    NbrSol = 0;
84    if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() || 
85          Qualified1.IsOutside() || Qualified1.IsUnqualified())) {
86      GccEnt_BadQualifier::Raise();
87      return;
88    }
89    Standard_Integer nbrcote1 = 0;
90    TColStd_Array1OfReal Coef(1,2);
91    TheCurve Cu1 = Qualified1.Qualified();
92
93    if (Radius < 0.0) { Standard_NegativeValue::Raise(); }
94    else {
95      if (Qualified1.IsEnclosed()) {
96 //    ===========================
97        nbrcote1 = 1;
98        Coef(1) = Radius;
99      }
100      else if(Qualified1.IsOutside()) {
101 //   ===============================
102        nbrcote1 = 1;
103        Coef(1) = -Radius;
104      }
105      else if(Qualified1.IsUnqualified()) {
106 //   ===================================
107        nbrcote1 = 2;
108        Coef(1) = Radius;
109        Coef(2) = -Radius;
110      }
111      IntRes2d_Domain D1;
112      TheIntConicCurve Intp;
113      for (Standard_Integer jcote1 = 1 ; jcote1 <= nbrcote1 ; jcote1++) {
114        Handle(TheHParGenCurve) HCu1 = new TheHParGenCurve(Cu1);
115        TheParGenCurve C2(HCu1,Coef(jcote1));
116        firstparam = Max(TheCurvePGTool::FirstParameter(C2),thefirst);
117        lastparam  = Min(TheCurvePGTool::LastParameter(C2),thelast);
118        IntRes2d_Domain D2(TheCurvePGTool::Value(C2,firstparam),firstparam,Tol,
119                           TheCurvePGTool::Value(C2,lastparam),lastparam,Tol);
120        Intp.Perform(OnLine,D1,C2,D2,Tol,Tol);
121        if (Intp.IsDone()) {
122          if (!Intp.IsEmpty()) {
123            for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++) {
124              NbrSol++;
125              gp_Pnt2d Center(Intp.Point(i).Value());
126              cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
127 //           =======================================================
128              qualifier1(NbrSol) = Qualified1.Qualifier();
129              TheSame1(NbrSol) = 0;
130              pararg1(NbrSol) = Intp.Point(i).ParamOnSecond();
131              parcen3(NbrSol) = Intp.Point(i).ParamOnFirst();
132              par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
133                                               pnttg1sol(NbrSol));
134              pnttg1sol(NbrSol) = gp_Pnt2d(TheTool::Value(Cu1,pararg1(NbrSol)));
135              pntcen3(NbrSol) = Center;
136            }
137          }
138          WellDone = Standard_True;
139        }
140      }
141    }
142  }
143
144 //=========================================================================
145 //  Cercle tangent  :  a un cercle Qualified1 (C1).                       +
146 //         centre   :  sur une droite OnLine.                             +
147 //         de rayon :  Radius.                                            +
148 //                                                                        + 
149 //  On initialise le tableau de solutions cirsol ainsi que tous les       +
150 //  champs.                                                               +
151 //  On elimine en fonction du qualifieur les cas ne presentant pas de     +
152 //  solutions.                                                            +
153 //  On resoud l equation du second degre indiquant que le point de centre +
154 //  recherche (xc,yc) est a une distance Radius du cercle C1 et           +
155 //                        sur la droite OnLine.                           +
156 //  Les solutions sont representees par les cercles :                     +
157 //                   - de centre Pntcen(xc,yc)                            +
158 //                   - de rayon Radius.                                   +
159 //=========================================================================
160
161 GccGeo_Circ2dTanOnRad::
162    GccGeo_Circ2dTanOnRad (const TheQCurve&    Qualified1,
163                           const gp_Circ2d&    OnCirc    , 
164                           const Standard_Real Radius    ,
165                           const Standard_Real Tolerance ):
166
167 //=========================================================================
168 // Initialisation des champs.                                             +
169 //=========================================================================
170
171    cirsol(1,8)     ,
172    qualifier1(1,8) ,
173    TheSame1(1,8)   ,
174    pnttg1sol(1,8)  ,
175    pntcen3(1,8)    ,
176    par1sol(1,8)    ,
177    pararg1(1,8)    ,
178    parcen3(1,8)    
179 {
180
181 //=========================================================================
182 // Traitement.                                                            +
183 //=========================================================================
184
185    gp_Dir2d dirx(1.0,0.0);
186    Standard_Real thefirst = -100000.;
187    Standard_Real thelast  =  100000.;
188    Standard_Real firstparam;
189    Standard_Real lastparam;
190    Standard_Real Tol = Abs(Tolerance);
191    Standard_Integer nbrcote1=0;
192    WellDone = Standard_False;
193    NbrSol = 0;
194    if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() || 
195          Qualified1.IsOutside() || Qualified1.IsUnqualified())) {
196      GccEnt_BadQualifier::Raise();
197      return;
198    }
199    TColStd_Array1OfReal cote1(1,2);
200    TheCurve Cu1 = Qualified1.Qualified();
201
202    if (Radius < 0.0) {
203      Standard_NegativeValue::Raise();
204    }
205    else {
206      if (Qualified1.IsEnclosed()) {
207 //    ===========================
208        nbrcote1 = 1;
209        cote1(1) = Radius;
210      }
211      else if(Qualified1.IsOutside()) {
212 //   ===============================
213        nbrcote1 = 1;
214        cote1(1) = -Radius;
215      }
216      else if(Qualified1.IsUnqualified()) {
217 //   ===================================
218        nbrcote1 = 2;
219        cote1(1) = Radius;
220        cote1(2) = -Radius;
221      }
222      IntRes2d_Domain D1(ElCLib::Value(0.,OnCirc),   0.,Tol,
223                         ElCLib::Value(2.*M_PI,OnCirc),2.*M_PI,Tol);
224      D1.SetEquivalentParameters(0.,2.*M_PI);
225      TheIntConicCurve Intp;
226      for (Standard_Integer jcote1 = 1 ; jcote1 <= nbrcote1 ; jcote1++) {
227        Handle(TheHParGenCurve) HCu1 = new TheHParGenCurve(Cu1);
228        TheParGenCurve C2(HCu1,cote1(jcote1));
229        firstparam = Max(TheCurvePGTool::FirstParameter(C2),thefirst);
230        lastparam  = Min(TheCurvePGTool::LastParameter(C2),thelast);
231        IntRes2d_Domain D2(TheCurvePGTool::Value(C2,firstparam),firstparam,Tol,
232                           TheCurvePGTool::Value(C2,lastparam),lastparam,Tol);
233        Intp.Perform(OnCirc,D1,C2,D2,Tol,Tol);
234        if (Intp.IsDone()) {
235          if (!Intp.IsEmpty()) {
236            for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++) {
237              NbrSol++;
238              gp_Pnt2d Center(Intp.Point(i).Value());
239              cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
240 //           =======================================================
241              qualifier1(NbrSol) = Qualified1.Qualifier();
242              TheSame1(NbrSol) = 0;
243              pararg1(NbrSol) = Intp.Point(i).ParamOnSecond();
244              parcen3(NbrSol) = Intp.Point(i).ParamOnFirst();
245              par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
246                                               pnttg1sol(NbrSol));
247              pnttg1sol(NbrSol) = gp_Pnt2d(TheTool::Value(Cu1,pararg1(NbrSol)));
248              pntcen3(NbrSol) = Center;
249            }
250          }
251          WellDone = Standard_True;
252        }
253      }
254    }
255  }
256
257 //=========================================================================
258 //  Cercle tangent  :  a un cercle Qualified1 (C1).                       +
259 //         centre   :  sur une droite OnLine.                             +
260 //         de rayon :  Radius.                                            +
261 //                                                                        + 
262 //  On initialise le tableau de solutions cirsol ainsi que tous les       +
263 //  champs.                                                               +
264 //  On elimine en fonction du qualifieur les cas ne presentant pas de     +
265 //  solutions.                                                            +
266 //  On resoud l equation du second degre indiquant que le point de centre +
267 //  recherche (xc,yc) est a une distance Radius du cercle C1 et           +
268 //                        sur la droite OnLine.                           +
269 //  Les solutions sont representees par les cercles :                     +
270 //                   - de centre Pntcen(xc,yc)                            +
271 //                   - de rayon Radius.                                   +
272 //=========================================================================
273
274 GccGeo_Circ2dTanOnRad::
275    GccGeo_Circ2dTanOnRad (const GccEnt_QualifiedCirc& Qualified1,
276                           const TheCurve&             OnCurv    ,
277                           const Standard_Real         Radius    ,
278                           const Standard_Real         Tolerance ):
279
280 //=========================================================================
281 // Initialisation des champs.                                             +
282 //=========================================================================
283
284    cirsol(1,8)     ,
285    qualifier1(1,8) ,
286    TheSame1(1,8)   ,
287    pnttg1sol(1,8)  ,
288    pntcen3(1,8)    ,
289    par1sol(1,8)    ,
290    pararg1(1,8)    ,
291    parcen3(1,8)    
292 {
293
294 //=========================================================================
295 // Traitement.                                                            +
296 //=========================================================================
297
298    gp_Dir2d dirx(1.0,0.0);
299    Standard_Real thefirst = -100000.;
300    Standard_Real thelast  =  100000.;
301    Standard_Real firstparam;
302    Standard_Real lastparam;
303    Standard_Real Tol = Abs(Tolerance);
304    Standard_Integer nbrcote1=0;
305    WellDone = Standard_False;
306    NbrSol = 0;
307    if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() || 
308          Qualified1.IsOutside() || Qualified1.IsUnqualified())) {
309      GccEnt_BadQualifier::Raise();
310      return;
311    }
312    TColStd_Array1OfReal cote1(1,2);
313    gp_Circ2d C1 = Qualified1.Qualified();
314    gp_Pnt2d center1(C1.Location());
315    Standard_Real R1 = C1.Radius();
316
317    if (Radius < 0.0) {
318      Standard_NegativeValue::Raise();
319    }
320    else {
321      if (Qualified1.IsEnclosed()) {
322 //    ===========================
323        nbrcote1 = 1;
324        cote1(1) = Radius;
325      }
326      else if(Qualified1.IsOutside()) {
327 //   ===============================
328        nbrcote1 = 1;
329        cote1(1) = -Radius;
330      }
331      else if(Qualified1.IsUnqualified()) {
332 //   ===================================
333        nbrcote1 = 2;
334        cote1(1) = Radius;
335        cote1(2) = -Radius;
336      }
337      TheIntConicCurve Intp;
338      for (Standard_Integer jcote1 = 1 ; jcote1 <= nbrcote1 ; jcote1++) {
339        gp_Circ2d Circ(C1.XAxis(),R1 + cote1(jcote1));
340        IntRes2d_Domain D1(ElCLib::Value(0.,Circ),   0.,Tol,
341                           ElCLib::Value(2.*M_PI,Circ),2.*M_PI,Tol);
342        D1.SetEquivalentParameters(0.,2.*M_PI);
343        firstparam = Max(TheTool::FirstParameter(OnCurv),thefirst);
344        lastparam  = Min(TheTool::LastParameter(OnCurv),thelast);
345        IntRes2d_Domain D2(TheTool::Value(OnCurv,firstparam),firstparam,Tol,
346                           TheTool::Value(OnCurv,lastparam),lastparam,Tol);
347        Intp.Perform(Circ,D1,OnCurv,D2,Tol,Tol);
348        if (Intp.IsDone()) {
349          if (!Intp.IsEmpty()) {
350            for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++) {
351              NbrSol++;
352              gp_Pnt2d Center(Intp.Point(i).Value());
353              cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
354 //           =======================================================
355              Standard_Real distcc1 = Center.Distance(center1);
356              if (!Qualified1.IsUnqualified()) { 
357                qualifier1(NbrSol) = Qualified1.Qualifier();
358              }
359              else if (Abs(distcc1+Radius-R1) < Tol) {
360                qualifier1(NbrSol) = GccEnt_enclosed;
361              }
362              else if (Abs(distcc1-R1-Radius) < Tol) {
363                qualifier1(NbrSol) = GccEnt_outside;
364              }
365              else { qualifier1(NbrSol) = GccEnt_enclosing; }
366              TheSame1(NbrSol) = 0;
367              pararg1(NbrSol) = Intp.Point(i).ParamOnFirst();
368              parcen3(NbrSol) = Intp.Point(i).ParamOnSecond();
369              par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
370                                                     pnttg1sol(NbrSol));
371              pnttg1sol(NbrSol) = ElCLib::Value(pararg1(NbrSol),C1);
372              pntcen3(NbrSol) = Center;
373            }
374          }
375          WellDone = Standard_True;
376        }
377      }
378    }
379  }
380
381 //=========================================================================
382 //  Cercle tangent  :  a un cercle Qualified1 (C1).                       +
383 //         centre   :  sur une droite OnLine.                             +
384 //         de rayon :  Radius.                                            +
385 //                                                                        + 
386 //  On initialise le tableau de solutions cirsol ainsi que tous les       +
387 //  champs.                                                               +
388 //  On elimine en fonction du qualifieur les cas ne presentant pas de     +
389 //  solutions.                                                            +
390 //  On resoud l equation du second degre indiquant que le point de centre +
391 //  recherche (xc,yc) est a une distance Radius du cercle C1 et           +
392 //                        sur la droite OnLine.                           +
393 //  Les solutions sont representees par les cercles :                     +
394 //                   - de centre Pntcen(xc,yc)                            +
395 //                   - de rayon Radius.                                   +
396 //=========================================================================
397
398 GccGeo_Circ2dTanOnRad::
399    GccGeo_Circ2dTanOnRad (const GccEnt_QualifiedLin& Qualified1,
400                           const TheCurve&            OnCurv    ,
401                           const Standard_Real        Radius    ,
402                           const Standard_Real        Tolerance ):
403
404 //=========================================================================
405 // Initialisation des champs.                                             +
406 //=========================================================================
407
408    cirsol(1,8)     ,
409    qualifier1(1,8) ,
410    TheSame1(1,8)   ,
411    pnttg1sol(1,8)  ,
412    pntcen3(1,8)    ,
413    par1sol(1,8)    ,
414    pararg1(1,8)    ,
415    parcen3(1,8)    
416 {
417
418 //=========================================================================
419 // Traitement.                                                            +
420 //=========================================================================
421
422    gp_Dir2d dirx(1.0,0.0);
423    Standard_Real thefirst = -100000.;
424    Standard_Real thelast  =  100000.;
425    Standard_Real firstparam;
426    Standard_Real lastparam;
427    Standard_Real Tol = Abs(Tolerance);
428    WellDone = Standard_False;
429    NbrSol = 0;
430    if (!(Qualified1.IsEnclosed() ||
431          Qualified1.IsOutside() || Qualified1.IsUnqualified())) {
432      GccEnt_BadQualifier::Raise();
433      return;
434    }
435    Standard_Integer nbrcote1=0;
436    TColStd_Array1OfReal cote1(1,2);
437    gp_Lin2d L1 = Qualified1.Qualified();
438    gp_Pnt2d origin1(L1.Location());
439    gp_Dir2d dir1(L1.Direction());
440    gp_Dir2d norm1(-dir1.Y(),dir1.X());
441
442    if (Radius < 0.0) {
443      Standard_NegativeValue::Raise();
444    }
445    else {
446      if (Qualified1.IsEnclosed()) {
447 //    ===========================
448        nbrcote1 = 1;
449        cote1(1) = Radius;
450      }
451      else if(Qualified1.IsOutside()) {
452 //   ===============================
453        nbrcote1 = 1;
454        cote1(1) = -Radius;
455      }
456      else if(Qualified1.IsUnqualified()) {
457 //   ===================================
458        nbrcote1 = 2;
459        cote1(1) = Radius;
460        cote1(2) = -Radius;
461      }
462      TheIntConicCurve Intp;
463      for (Standard_Integer jcote1 = 1 ; jcote1 <= nbrcote1 ; jcote1++) {
464        gp_Pnt2d Point(dir1.XY()+cote1(jcote1)*norm1.XY());
465        gp_Lin2d Line(Point,dir1); // ligne avec deport.
466        IntRes2d_Domain D1;
467        firstparam = Max(TheTool::FirstParameter(OnCurv),thefirst);
468        lastparam  = Min(TheTool::LastParameter(OnCurv),thelast);
469        IntRes2d_Domain D2(TheTool::Value(OnCurv,firstparam),firstparam,Tol,
470                           TheTool::Value(OnCurv,lastparam),lastparam,Tol);
471        Intp.Perform(Line,D1,OnCurv,D2,Tol,Tol);
472        if (Intp.IsDone()) {
473          if (!Intp.IsEmpty()) {
474            for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++) {
475              NbrSol++;
476              gp_Pnt2d Center(Intp.Point(i).Value());
477              cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
478 //           =======================================================
479              gp_Dir2d dc1(origin1.XY()-Center.XY());
480              if (!Qualified1.IsUnqualified()) { 
481                qualifier1(NbrSol) = Qualified1.Qualifier();
482              }
483              else if (dc1.Dot(norm1) > 0.0) {   
484                qualifier1(NbrSol) = GccEnt_outside; 
485              }
486              else { qualifier1(NbrSol) = GccEnt_enclosed; }
487              TheSame1(NbrSol) = 0;
488              pararg1(NbrSol) = Intp.Point(i).ParamOnFirst();
489              parcen3(NbrSol) = Intp.Point(i).ParamOnSecond();
490              par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
491                                               pnttg1sol(NbrSol));
492              pnttg1sol(NbrSol) = ElCLib::Value(pararg1(NbrSol),L1);
493              pntcen3(NbrSol) = Center;
494            }
495          }
496          WellDone = Standard_True;
497        }
498      }
499    }
500  }
501
502 //=========================================================================
503 //  Cercle tangent  :  a un cercle Qualified1 (C1).                       +
504 //         centre   :  sur une droite OnLine.                             +
505 //         de rayon :  Radius.                                            +
506 //                                                                        + 
507 //  On initialise le tableau de solutions cirsol ainsi que tous les       +
508 //  champs.                                                               +
509 //  On elimine en fonction du qualifieur les cas ne presentant pas de     +
510 //  solutions.                                                            +
511 //  On resoud l equation du second degre indiquant que le point de centre +
512 //  recherche (xc,yc) est a une distance Radius du cercle C1 et           +
513 //                        sur la droite OnLine.                           +
514 //  Les solutions sont representees par les cercles :                     +
515 //                   - de centre Pntcen(xc,yc)                            +
516 //                   - de rayon Radius.                                   +
517 //=========================================================================
518
519 GccGeo_Circ2dTanOnRad::
520    GccGeo_Circ2dTanOnRad (const TheQCurve&    Qualified1,
521                           const TheCurve&     OnCurv    ,
522                           const Standard_Real Radius    ,
523                           const Standard_Real Tolerance ):
524
525 //=========================================================================
526 // Initialisation des champs.                                             +
527 //=========================================================================
528
529    cirsol(1,8)     ,
530    qualifier1(1,8) ,
531    TheSame1(1,8)   ,
532    pnttg1sol(1,8)  ,
533    pntcen3(1,8)    ,
534    par1sol(1,8)    ,
535    pararg1(1,8)    ,
536    parcen3(1,8)    
537 {
538
539 //=========================================================================
540 // Traitement.                                                            +
541 //=========================================================================
542
543    gp_Dir2d dirx(1.0,0.0);
544    Standard_Real thefirst = -100000.;
545    Standard_Real thelast  =  100000.;
546    Standard_Real firstparam;
547    Standard_Real lastparam;
548    Standard_Real Tol = Abs(Tolerance);
549    Standard_Integer nbrcote1=0;
550    WellDone = Standard_False;
551    NbrSol = 0;
552    if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() || 
553          Qualified1.IsOutside() || Qualified1.IsUnqualified())) {
554      GccEnt_BadQualifier::Raise();
555      return;
556    }
557    TColStd_Array1OfReal cote1(1,2);
558    TheCurve Cu1 = Qualified1.Qualified();
559
560    if (Radius < 0.0) {
561      Standard_NegativeValue::Raise();
562    }
563    else {
564      if (Qualified1.IsEnclosed()) {
565 //    ===========================
566        nbrcote1 = 1;
567        cote1(1) = Radius;
568      }
569      else if(Qualified1.IsOutside()) {
570 //   ===============================
571        nbrcote1 = 1;
572        cote1(1) = -Radius;
573      }
574      else if(Qualified1.IsUnqualified()) {
575 //   ===================================
576        nbrcote1 = 2;
577        cote1(1) = Radius;
578        cote1(2) = -Radius;
579      }
580      TheIntCurveCurve Intp;
581      for (Standard_Integer jcote1 = 1 ; jcote1 <= nbrcote1 ; jcote1++) {
582        Handle(TheHParGenCurve) HCu1 = new TheHParGenCurve(Cu1);
583        TheParGenCurve C1(HCu1,cote1(jcote1));
584        firstparam = Max(TheCurvePGTool::FirstParameter(C1),thefirst);
585        lastparam  = Min(TheCurvePGTool::LastParameter(C1),thelast);
586        IntRes2d_Domain D1(TheCurvePGTool::Value(C1,firstparam),firstparam,Tol,
587                           TheCurvePGTool::Value(C1,lastparam),lastparam,Tol);
588        Handle(TheHParGenCurve) HOnCurv = new TheHParGenCurve(OnCurv);
589        TheParGenCurve C2(HOnCurv);
590        firstparam = Max(TheCurvePGTool::FirstParameter(C2),thefirst);
591        lastparam  = Min(TheCurvePGTool::LastParameter(C2),thelast);
592        IntRes2d_Domain D2(TheCurvePGTool::Value(C2,firstparam),firstparam,Tol,
593                           TheCurvePGTool::Value(C2,lastparam),lastparam,Tol);
594        Intp.Perform(C1,D1,C2,D2,Tol,Tol);
595        if (Intp.IsDone()) {
596          if (!Intp.IsEmpty()) {
597            for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++) {
598              NbrSol++;
599              gp_Pnt2d Center(Intp.Point(i).Value());
600              cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
601 //           =======================================================
602              qualifier1(NbrSol) = Qualified1.Qualifier();
603              TheSame1(NbrSol) = 0;
604              pararg1(NbrSol) = Intp.Point(i).ParamOnFirst();
605              parcen3(NbrSol) = Intp.Point(i).ParamOnSecond();
606              par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
607                                               pnttg1sol(NbrSol));
608              pnttg1sol(NbrSol) = gp_Pnt2d(TheTool::Value(Cu1,pararg1(NbrSol)));
609              pntcen3(NbrSol) = Center;
610            }
611          }
612          WellDone = Standard_True;
613        }
614      }
615    }
616  }
617
618 //=========================================================================
619 //  Cercle tangent  :  a un cercle Qualified1 (C1).                       +
620 //         centre   :  sur une droite OnLine.                             +
621 //         de rayon :  Radius.                                            +
622 //                                                                        + 
623 //  On initialise le tableau de solutions cirsol ainsi que tous les       +
624 //  champs.                                                               +
625 //  On elimine en fonction du qualifieur les cas ne presentant pas de     +
626 //  solutions.                                                            +
627 //  On resoud l equation du second degre indiquant que le point de centre +
628 //  recherche (xc,yc) est a une distance Radius du cercle C1 et           +
629 //                        sur la droite OnLine.                           +
630 //  Les solutions sont representees par les cercles :                     +
631 //                   - de centre Pntcen(xc,yc)                            +
632 //                   - de rayon Radius.                                   +
633 //=========================================================================
634
635 GccGeo_Circ2dTanOnRad::
636    GccGeo_Circ2dTanOnRad (const gp_Pnt2d&     Point1    ,
637                           const TheCurve&     OnCurv    ,
638                           const Standard_Real Radius    ,
639                           const Standard_Real Tolerance ):
640
641 //=========================================================================
642 // Initialisation des champs.                                             +
643 //=========================================================================
644
645    cirsol(1,8)     ,
646    qualifier1(1,8) ,
647    TheSame1(1,8)   ,
648    pnttg1sol(1,8)  ,
649    pntcen3(1,8)    ,
650    par1sol(1,8)    ,
651    pararg1(1,8)    ,
652    parcen3(1,8)    
653 {
654
655 //=========================================================================
656 // Traitement.                                                            +
657 //=========================================================================
658
659    gp_Dir2d dirx(1.0,0.0);
660    Standard_Real thefirst = -100000.;
661    Standard_Real thelast  =  100000.;
662    Standard_Real firstparam;
663    Standard_Real lastparam;
664    Standard_Real Tol = Abs(Tolerance);
665    WellDone = Standard_False;
666    NbrSol = 0;
667
668    if (Radius < 0.0) {
669      Standard_NegativeValue::Raise();
670    }
671    else {
672 //     gp_Dir2d Dir(-y1dir,x1dir);
673      gp_Circ2d Circ(gp_Ax2d(Point1,gp_Dir2d(1.,0.)),Radius);
674      IntRes2d_Domain D1(ElCLib::Value(0.,Circ),   0.,Tol,
675                         ElCLib::Value(2.*M_PI,Circ),2*M_PI,Tol);
676      D1.SetEquivalentParameters(0.,2.*M_PI);
677      firstparam = Max(TheTool::FirstParameter(OnCurv),thefirst);
678      lastparam  = Min(TheTool::LastParameter(OnCurv),thelast);
679      IntRes2d_Domain D2(TheTool::Value(OnCurv,firstparam),firstparam,Tol,
680                         TheTool::Value(OnCurv,lastparam),lastparam,Tol);
681      TheIntConicCurve Intp(Circ,D1,OnCurv,D2,Tol,Tol);
682      if (Intp.IsDone()) {
683        if (!Intp.IsEmpty()) {
684          for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++) {
685            NbrSol++;
686            gp_Pnt2d Center(Intp.Point(i).Value());
687            cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
688 //         =======================================================
689            qualifier1(NbrSol) = GccEnt_noqualifier;
690            TheSame1(NbrSol) = 0;
691            pararg1(NbrSol) = Intp.Point(i).ParamOnFirst();
692            parcen3(NbrSol) = Intp.Point(i).ParamOnSecond();
693            par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
694                                             pnttg1sol(NbrSol));
695            pnttg1sol(NbrSol) = Point1;
696            pntcen3(NbrSol) = Center;
697          }
698          WellDone = Standard_True;
699        }
700      }
701    }
702  }
703
704 //=========================================================================
705
706 Standard_Boolean GccGeo_Circ2dTanOnRad::
707    IsDone () const { return WellDone; }
708
709 Standard_Integer GccGeo_Circ2dTanOnRad::
710    NbSolutions () const { return NbrSol; }
711
712 gp_Circ2d GccGeo_Circ2dTanOnRad::
713    ThisSolution (const Standard_Integer Index) const 
714 {
715   
716   if (Index > NbrSol || Index <= 0)
717     Standard_OutOfRange::Raise();
718   
719   return cirsol(Index);
720 }
721
722 void GccGeo_Circ2dTanOnRad::
723   WhichQualifier(const Standard_Integer Index   ,
724                        GccEnt_Position& Qualif1 ) const
725 {
726   if (!WellDone) { StdFail_NotDone::Raise(); }
727   else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
728   else {
729     Qualif1 = qualifier1(Index);
730   }
731 }
732
733 void GccGeo_Circ2dTanOnRad::
734    Tangency1 (const Standard_Integer Index,
735                  Standard_Real&   ParSol,
736                  Standard_Real&   ParArg,
737               gp_Pnt2d& PntSol) const{
738    if (!WellDone) {
739      StdFail_NotDone::Raise();
740    }
741    else if (Index <= 0 ||Index > NbrSol) {
742      Standard_OutOfRange::Raise();
743    }
744    else {
745      ParSol = par1sol(Index);
746      ParArg = pararg1(Index);
747      PntSol = gp_Pnt2d(pnttg1sol(Index));
748    }
749  }
750
751 void GccGeo_Circ2dTanOnRad::
752    CenterOn3 (const Standard_Integer Index,
753                     Standard_Real&   ParArg, 
754                     gp_Pnt2d&        PntSol) const {
755    if (!WellDone) {
756      StdFail_NotDone::Raise();
757    }
758    else if (Index <= 0 ||Index > NbrSol) {
759      Standard_OutOfRange::Raise();
760    }
761    else {
762      ParArg = parcen3(Index);
763      PntSol = pnttg1sol(Index);
764    }
765  }
766
767 Standard_Boolean GccGeo_Circ2dTanOnRad::
768    IsTheSame1 (const Standard_Integer Index) const
769 {
770   if (!WellDone) StdFail_NotDone::Raise();
771   if (Index <= 0 ||Index > NbrSol) Standard_OutOfRange::Raise();
772   
773   if (TheSame1(Index) == 0) 
774     return Standard_False;
775   
776   return Standard_True;
777 }