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