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