1 // Copyright (c) 1995-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
4 // This file is part of Open CASCADE Technology software library.
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.
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
15 //========================================================================
16 // circulaire tangent a un element de type : - Cercle. +
19 // centre sur un deuxieme element de type : - Cercle. +
21 // de rayon donne : Radius. +
22 //========================================================================
24 #include <Adaptor2d_OffsetCurve.hxx>
26 #include <GccEnt_BadQualifier.hxx>
27 #include <GccEnt_QualifiedCirc.hxx>
28 #include <GccEnt_QualifiedLin.hxx>
29 #include <Geom2dAdaptor_Curve.hxx>
30 #include <Geom2dAdaptor_Curve.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>
47 static const Standard_Integer aNbSolMAX = 8;
49 //=========================================================================
50 // Cercle tangent : a un cercle Qualified1 (C1). +
51 // centre : sur une droite OnLine. +
52 // de rayon : Radius. +
54 // On initialise le tableau de solutions cirsol ainsi que tous les +
56 // On elimine en fonction du qualifieur les cas ne presentant pas de +
58 // On resoud l equation du second degre indiquant que le point de centre +
59 // recherche (xc,yc) est a une distance Radius du cercle C1 et +
60 // sur la droite OnLine. +
61 // Les solutions sont representees par les cercles : +
62 // - de centre Pntcen(xc,yc) +
63 // - de rayon Radius. +
64 //=========================================================================
65 Geom2dGcc_Circ2dTanOnRadGeo::
66 Geom2dGcc_Circ2dTanOnRadGeo (const Geom2dGcc_QCurve& Qualified1,
67 const gp_Lin2d& OnLine ,
68 const Standard_Real Radius ,
69 const Standard_Real Tolerance ):
71 //=========================================================================
72 // Initialisation des champs. +
73 //=========================================================================
76 qualifier1(1,aNbSolMAX) ,
77 TheSame1(1,aNbSolMAX) ,
78 pnttg1sol(1,aNbSolMAX) ,
79 pntcen3(1,aNbSolMAX) ,
80 par1sol(1,aNbSolMAX) ,
81 pararg1(1,aNbSolMAX) ,
85 //=========================================================================
87 //=========================================================================
89 gp_Dir2d dirx(1.0,0.0);
90 Standard_Real Tol = Abs(Tolerance);
91 Standard_Real thefirst = -100000.;
92 Standard_Real thelast = 100000.;
93 Standard_Real firstparam;
94 Standard_Real lastparam;
95 WellDone = Standard_False;
97 if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() ||
98 Qualified1.IsOutside() || Qualified1.IsUnqualified())) {
99 throw GccEnt_BadQualifier();
102 Standard_Integer nbrcote1 = 0;
103 TColStd_Array1OfReal Coef(1,2);
104 Geom2dAdaptor_Curve Cu1 = Qualified1.Qualified();
106 if (Radius < 0.0) { throw Standard_NegativeValue(); }
108 if (Qualified1.IsEnclosed()) {
109 // ===========================
113 else if(Qualified1.IsOutside()) {
114 // ===============================
118 else if(Qualified1.IsUnqualified()) {
119 // ===================================
125 Geom2dInt_TheIntConicCurveOfGInter Intp;
126 for (Standard_Integer jcote1 = 1 ; jcote1 <= nbrcote1 ; jcote1++) {
127 Handle(Geom2dAdaptor_Curve) HCu1 = new Geom2dAdaptor_Curve(Cu1);
128 //Adaptor2d_OffsetCurve C2(HCu1,Coef(jcote1));
129 Adaptor2d_OffsetCurve C2(HCu1, -Coef(jcote1));
130 firstparam = Max(C2.FirstParameter(),thefirst);
131 lastparam = Min(C2.LastParameter(),thelast);
132 IntRes2d_Domain D2(C2.Value(firstparam), firstparam, Tol,
133 C2.Value(lastparam), lastparam, Tol);
134 Intp.Perform(OnLine,D1,C2,D2,Tol,Tol);
136 if (!Intp.IsEmpty()) {
137 for (Standard_Integer i = 1 ; i <= Intp.NbPoints() && NbrSol < aNbSolMAX; i++) {
139 gp_Pnt2d Center(Intp.Point(i).Value());
140 cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
141 // =======================================================
142 qualifier1(NbrSol) = Qualified1.Qualifier();
143 TheSame1(NbrSol) = 0;
144 pararg1(NbrSol) = Intp.Point(i).ParamOnSecond();
145 parcen3(NbrSol) = Intp.Point(i).ParamOnFirst();
146 par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
148 pnttg1sol(NbrSol) = gp_Pnt2d(Geom2dGcc_CurveTool::Value(Cu1,pararg1(NbrSol)));
149 pntcen3(NbrSol) = Center;
152 WellDone = Standard_True;
158 //=========================================================================
159 // Cercle tangent : a un cercle Qualified1 (C1). +
160 // centre : sur une droite OnLine. +
161 // de rayon : Radius. +
163 // On initialise le tableau de solutions cirsol ainsi que tous les +
165 // On elimine en fonction du qualifieur les cas ne presentant pas de +
167 // On resoud l equation du second degre indiquant que le point de centre +
168 // recherche (xc,yc) est a une distance Radius du cercle C1 et +
169 // sur la droite OnLine. +
170 // Les solutions sont representees par les cercles : +
171 // - de centre Pntcen(xc,yc) +
172 // - de rayon Radius. +
173 //=========================================================================
175 Geom2dGcc_Circ2dTanOnRadGeo::
176 Geom2dGcc_Circ2dTanOnRadGeo (const Geom2dGcc_QCurve& Qualified1,
177 const gp_Circ2d& OnCirc ,
178 const Standard_Real Radius ,
179 const Standard_Real Tolerance ):
181 //=========================================================================
182 // Initialisation des champs. +
183 //=========================================================================
185 cirsol(1,aNbSolMAX) ,
186 qualifier1(1,aNbSolMAX) ,
187 TheSame1(1,aNbSolMAX) ,
188 pnttg1sol(1,aNbSolMAX) ,
189 pntcen3(1,aNbSolMAX) ,
190 par1sol(1,aNbSolMAX) ,
191 pararg1(1,aNbSolMAX) ,
195 //=========================================================================
197 //=========================================================================
199 gp_Dir2d dirx(1.0,0.0);
200 Standard_Real thefirst = -100000.;
201 Standard_Real thelast = 100000.;
202 Standard_Real firstparam;
203 Standard_Real lastparam;
204 Standard_Real Tol = Abs(Tolerance);
205 Standard_Integer nbrcote1=0;
206 WellDone = Standard_False;
208 if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() ||
209 Qualified1.IsOutside() || Qualified1.IsUnqualified())) {
210 throw GccEnt_BadQualifier();
213 TColStd_Array1OfReal cote1(1,2);
214 Geom2dAdaptor_Curve Cu1 = Qualified1.Qualified();
217 throw Standard_NegativeValue();
220 if (Qualified1.IsEnclosed()) {
221 // ===========================
225 else if(Qualified1.IsOutside()) {
226 // ===============================
230 else if(Qualified1.IsUnqualified()) {
231 // ===================================
236 IntRes2d_Domain D1(ElCLib::Value(0.,OnCirc), 0.,Tol,
237 ElCLib::Value(2.*M_PI,OnCirc),2.*M_PI,Tol);
238 D1.SetEquivalentParameters(0.,2.*M_PI);
239 Geom2dInt_TheIntConicCurveOfGInter Intp;
240 for (Standard_Integer jcote1 = 1 ; jcote1 <= nbrcote1 ; jcote1++) {
241 Handle(Geom2dAdaptor_Curve) HCu1 = new Geom2dAdaptor_Curve(Cu1);
242 //Adaptor2d_OffsetCurve C2(HCu1,cote1(jcote1));
243 Adaptor2d_OffsetCurve C2(HCu1, -cote1(jcote1));
244 firstparam = Max(C2.FirstParameter(),thefirst);
245 lastparam = Min(C2.LastParameter(),thelast);
246 IntRes2d_Domain D2(C2.Value(firstparam),firstparam,Tol,
247 C2.Value(lastparam),lastparam,Tol);
248 Intp.Perform(OnCirc,D1,C2,D2,Tol,Tol);
250 if (!Intp.IsEmpty()) {
251 for (Standard_Integer i = 1 ; i <= Intp.NbPoints() && NbrSol < aNbSolMAX; i++) {
253 gp_Pnt2d Center(Intp.Point(i).Value());
254 cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
255 // =======================================================
256 qualifier1(NbrSol) = Qualified1.Qualifier();
257 TheSame1(NbrSol) = 0;
258 pararg1(NbrSol) = Intp.Point(i).ParamOnSecond();
259 parcen3(NbrSol) = Intp.Point(i).ParamOnFirst();
260 par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
262 pnttg1sol(NbrSol) = gp_Pnt2d(Geom2dGcc_CurveTool::Value(Cu1,pararg1(NbrSol)));
263 pntcen3(NbrSol) = Center;
266 WellDone = Standard_True;
272 //=========================================================================
273 // Cercle tangent : a un cercle Qualified1 (C1). +
274 // centre : sur une droite OnLine. +
275 // de rayon : Radius. +
277 // On initialise le tableau de solutions cirsol ainsi que tous les +
279 // On elimine en fonction du qualifieur les cas ne presentant pas de +
281 // On resoud l equation du second degre indiquant que le point de centre +
282 // recherche (xc,yc) est a une distance Radius du cercle C1 et +
283 // sur la droite OnLine. +
284 // Les solutions sont representees par les cercles : +
285 // - de centre Pntcen(xc,yc) +
286 // - de rayon Radius. +
287 //=========================================================================
289 Geom2dGcc_Circ2dTanOnRadGeo::
290 Geom2dGcc_Circ2dTanOnRadGeo (const GccEnt_QualifiedCirc& Qualified1,
291 const Geom2dAdaptor_Curve& OnCurv ,
292 const Standard_Real Radius ,
293 const Standard_Real Tolerance ):
295 //=========================================================================
296 // Initialisation des champs. +
297 //=========================================================================
299 cirsol(1,aNbSolMAX) ,
300 qualifier1(1,aNbSolMAX) ,
301 TheSame1(1,aNbSolMAX) ,
302 pnttg1sol(1,aNbSolMAX) ,
303 pntcen3(1,aNbSolMAX) ,
304 par1sol(1,aNbSolMAX) ,
305 pararg1(1,aNbSolMAX) ,
309 //=========================================================================
311 //=========================================================================
313 gp_Dir2d dirx(1.0,0.0);
314 Standard_Real thefirst = -100000.;
315 Standard_Real thelast = 100000.;
316 Standard_Real firstparam;
317 Standard_Real lastparam;
318 Standard_Real Tol = Abs(Tolerance);
319 Standard_Integer nbrcote1=0;
320 WellDone = Standard_False;
322 if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() ||
323 Qualified1.IsOutside() || Qualified1.IsUnqualified())) {
324 throw GccEnt_BadQualifier();
327 TColStd_Array1OfReal cote1(1,2);
328 gp_Circ2d C1 = Qualified1.Qualified();
329 gp_Pnt2d center1(C1.Location());
330 Standard_Real R1 = C1.Radius();
333 throw Standard_NegativeValue();
336 if (Qualified1.IsEnclosed()) {
337 // ===========================
341 else if(Qualified1.IsOutside()) {
342 // ===============================
346 else if(Qualified1.IsUnqualified()) {
347 // ===================================
352 Geom2dInt_TheIntConicCurveOfGInter Intp;
353 for (Standard_Integer jcote1 = 1 ; jcote1 <= nbrcote1 ; jcote1++) {
354 gp_Circ2d Circ(C1.XAxis(),R1 + cote1(jcote1));
355 IntRes2d_Domain D1(ElCLib::Value(0.,Circ), 0.,Tol,
356 ElCLib::Value(2.*M_PI,Circ),2.*M_PI,Tol);
357 D1.SetEquivalentParameters(0.,2.*M_PI);
358 firstparam = Max(Geom2dGcc_CurveTool::FirstParameter(OnCurv),thefirst);
359 lastparam = Min(Geom2dGcc_CurveTool::LastParameter(OnCurv),thelast);
360 IntRes2d_Domain D2(Geom2dGcc_CurveTool::Value(OnCurv,firstparam),firstparam,Tol,
361 Geom2dGcc_CurveTool::Value(OnCurv,lastparam),lastparam,Tol);
362 Intp.Perform(Circ,D1,OnCurv,D2,Tol,Tol);
364 if (!Intp.IsEmpty()) {
365 for (Standard_Integer i = 1 ; i <= Intp.NbPoints() && NbrSol < aNbSolMAX; i++) {
367 gp_Pnt2d Center(Intp.Point(i).Value());
368 cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
369 // =======================================================
370 Standard_Real distcc1 = Center.Distance(center1);
371 if (!Qualified1.IsUnqualified()) {
372 qualifier1(NbrSol) = Qualified1.Qualifier();
374 else if (Abs(distcc1+Radius-R1) < Tol) {
375 qualifier1(NbrSol) = GccEnt_enclosed;
377 else if (Abs(distcc1-R1-Radius) < Tol) {
378 qualifier1(NbrSol) = GccEnt_outside;
380 else { qualifier1(NbrSol) = GccEnt_enclosing; }
381 TheSame1(NbrSol) = 0;
382 pararg1(NbrSol) = Intp.Point(i).ParamOnFirst();
383 parcen3(NbrSol) = Intp.Point(i).ParamOnSecond();
384 par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
386 pnttg1sol(NbrSol) = ElCLib::Value(pararg1(NbrSol),C1);
387 pntcen3(NbrSol) = Center;
390 WellDone = Standard_True;
396 //=========================================================================
397 // Cercle tangent : a un cercle Qualified1 (C1). +
398 // centre : sur une droite OnLine. +
399 // de rayon : Radius. +
401 // On initialise le tableau de solutions cirsol ainsi que tous les +
403 // On elimine en fonction du qualifieur les cas ne presentant pas de +
405 // On resoud l equation du second degre indiquant que le point de centre +
406 // recherche (xc,yc) est a une distance Radius du cercle C1 et +
407 // sur la droite OnLine. +
408 // Les solutions sont representees par les cercles : +
409 // - de centre Pntcen(xc,yc) +
410 // - de rayon Radius. +
411 //=========================================================================
413 Geom2dGcc_Circ2dTanOnRadGeo::
414 Geom2dGcc_Circ2dTanOnRadGeo (const GccEnt_QualifiedLin& Qualified1,
415 const Geom2dAdaptor_Curve& OnCurv ,
416 const Standard_Real Radius ,
417 const Standard_Real Tolerance ):
419 //=========================================================================
420 // Initialisation des champs. +
421 //=========================================================================
423 cirsol(1,aNbSolMAX) ,
424 qualifier1(1,aNbSolMAX) ,
425 TheSame1(1,aNbSolMAX) ,
426 pnttg1sol(1,aNbSolMAX) ,
427 pntcen3(1,aNbSolMAX) ,
428 par1sol(1,aNbSolMAX) ,
429 pararg1(1,aNbSolMAX) ,
433 //=========================================================================
435 //=========================================================================
437 gp_Dir2d dirx(1.0,0.0);
438 Standard_Real thefirst = -100000.;
439 Standard_Real thelast = 100000.;
440 Standard_Real firstparam;
441 Standard_Real lastparam;
442 Standard_Real Tol = Abs(Tolerance);
443 WellDone = Standard_False;
445 if (!(Qualified1.IsEnclosed() ||
446 Qualified1.IsOutside() || Qualified1.IsUnqualified())) {
447 throw GccEnt_BadQualifier();
450 Standard_Integer nbrcote1=0;
451 TColStd_Array1OfReal cote1(1,2);
452 gp_Lin2d L1 = Qualified1.Qualified();
453 gp_Pnt2d origin1(L1.Location());
454 gp_Dir2d dir1(L1.Direction());
455 gp_Dir2d norm1(-dir1.Y(),dir1.X());
458 throw Standard_NegativeValue();
461 if (Qualified1.IsEnclosed()) {
462 // ===========================
466 else if(Qualified1.IsOutside()) {
467 // ===============================
471 else if(Qualified1.IsUnqualified()) {
472 // ===================================
477 Geom2dInt_TheIntConicCurveOfGInter Intp;
478 for (Standard_Integer jcote1 = 1 ; jcote1 <= nbrcote1 ; jcote1++) {
479 gp_Pnt2d Point(dir1.XY()+cote1(jcote1)*norm1.XY());
480 gp_Lin2d Line(Point,dir1); // ligne avec deport.
482 firstparam = Max(Geom2dGcc_CurveTool::FirstParameter(OnCurv),thefirst);
483 lastparam = Min(Geom2dGcc_CurveTool::LastParameter(OnCurv),thelast);
484 IntRes2d_Domain D2(Geom2dGcc_CurveTool::Value(OnCurv,firstparam),firstparam,Tol,
485 Geom2dGcc_CurveTool::Value(OnCurv,lastparam),lastparam,Tol);
486 Intp.Perform(Line,D1,OnCurv,D2,Tol,Tol);
488 if (!Intp.IsEmpty()) {
489 for (Standard_Integer i = 1 ; i <= Intp.NbPoints() && NbrSol < aNbSolMAX; i++) {
491 gp_Pnt2d Center(Intp.Point(i).Value());
492 cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
493 // =======================================================
494 gp_Dir2d dc1(origin1.XY()-Center.XY());
495 if (!Qualified1.IsUnqualified()) {
496 qualifier1(NbrSol) = Qualified1.Qualifier();
498 else if (dc1.Dot(norm1) > 0.0) {
499 qualifier1(NbrSol) = GccEnt_outside;
501 else { qualifier1(NbrSol) = GccEnt_enclosed; }
502 TheSame1(NbrSol) = 0;
503 pararg1(NbrSol) = Intp.Point(i).ParamOnFirst();
504 parcen3(NbrSol) = Intp.Point(i).ParamOnSecond();
505 par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
507 pnttg1sol(NbrSol) = ElCLib::Value(pararg1(NbrSol),L1);
508 pntcen3(NbrSol) = Center;
511 WellDone = Standard_True;
517 //=========================================================================
518 // Cercle tangent : a un cercle Qualified1 (C1). +
519 // centre : sur une droite OnLine. +
520 // de rayon : Radius. +
522 // On initialise le tableau de solutions cirsol ainsi que tous les +
524 // On elimine en fonction du qualifieur les cas ne presentant pas de +
526 // On resoud l equation du second degre indiquant que le point de centre +
527 // recherche (xc,yc) est a une distance Radius du cercle C1 et +
528 // sur la droite OnLine. +
529 // Les solutions sont representees par les cercles : +
530 // - de centre Pntcen(xc,yc) +
531 // - de rayon Radius. +
532 //=========================================================================
534 Geom2dGcc_Circ2dTanOnRadGeo::
535 Geom2dGcc_Circ2dTanOnRadGeo (const Geom2dGcc_QCurve& Qualified1,
536 const Geom2dAdaptor_Curve& OnCurv ,
537 const Standard_Real Radius ,
538 const Standard_Real Tolerance ):
540 //=========================================================================
541 // Initialisation des champs. +
542 //=========================================================================
544 cirsol(1,aNbSolMAX) ,
545 qualifier1(1,aNbSolMAX) ,
546 TheSame1(1,aNbSolMAX) ,
547 pnttg1sol(1,aNbSolMAX) ,
548 pntcen3(1,aNbSolMAX) ,
549 par1sol(1,aNbSolMAX) ,
550 pararg1(1,aNbSolMAX) ,
554 //=========================================================================
556 //=========================================================================
558 gp_Dir2d dirx(1.0,0.0);
559 Standard_Real thefirst = -100000.;
560 Standard_Real thelast = 100000.;
561 Standard_Real firstparam;
562 Standard_Real lastparam;
563 Standard_Real Tol = Abs(Tolerance);
564 Standard_Integer nbrcote1=0;
565 WellDone = Standard_False;
567 if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() ||
568 Qualified1.IsOutside() || Qualified1.IsUnqualified())) {
569 throw GccEnt_BadQualifier();
572 TColStd_Array1OfReal cote1(1,2);
573 Geom2dAdaptor_Curve Cu1 = Qualified1.Qualified();
576 throw Standard_NegativeValue();
579 if (Qualified1.IsEnclosed()) {
580 // ===========================
584 else if(Qualified1.IsOutside()) {
585 // ===============================
589 else if(Qualified1.IsUnqualified()) {
590 // ===================================
595 Geom2dInt_GInter Intp;
596 for (Standard_Integer jcote1 = 1 ; jcote1 <= nbrcote1 ; jcote1++) {
597 Handle(Geom2dAdaptor_Curve) HCu1 = new Geom2dAdaptor_Curve(Cu1);
598 //Adaptor2d_OffsetCurve C1(HCu1,cote1(jcote1));
599 Adaptor2d_OffsetCurve C1(HCu1, -cote1(jcote1));
600 firstparam = Max(C1.FirstParameter(),thefirst);
601 lastparam = Min(C1.LastParameter(),thelast);
602 IntRes2d_Domain D1(C1.Value(firstparam), firstparam, Tol,
603 C1.Value(lastparam), lastparam, Tol);
604 Handle(Geom2dAdaptor_Curve) HOnCurv = new Geom2dAdaptor_Curve(OnCurv);
605 Adaptor2d_OffsetCurve C2(HOnCurv);
606 firstparam = Max(C2.FirstParameter(),thefirst);
607 lastparam = Min(C2.LastParameter(),thelast);
608 IntRes2d_Domain D2(C2.Value(firstparam), firstparam, Tol,
609 C2.Value(lastparam), lastparam, Tol);
610 Intp.Perform(C1,D1,C2,D2,Tol,Tol);
612 if (!Intp.IsEmpty()) {
613 for (Standard_Integer i = 1 ; i <= Intp.NbPoints() && NbrSol < aNbSolMAX; i++) {
615 gp_Pnt2d Center(Intp.Point(i).Value());
616 cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
617 // =======================================================
618 qualifier1(NbrSol) = Qualified1.Qualifier();
619 TheSame1(NbrSol) = 0;
620 pararg1(NbrSol) = Intp.Point(i).ParamOnFirst();
621 parcen3(NbrSol) = Intp.Point(i).ParamOnSecond();
622 par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
624 pnttg1sol(NbrSol) = gp_Pnt2d(Geom2dGcc_CurveTool::Value(Cu1,pararg1(NbrSol)));
625 pntcen3(NbrSol) = Center;
628 WellDone = Standard_True;
634 //=========================================================================
635 // Cercle tangent : a un cercle Qualified1 (C1). +
636 // centre : sur une droite OnLine. +
637 // de rayon : Radius. +
639 // On initialise le tableau de solutions cirsol ainsi que tous les +
641 // On elimine en fonction du qualifieur les cas ne presentant pas de +
643 // On resoud l equation du second degre indiquant que le point de centre +
644 // recherche (xc,yc) est a une distance Radius du cercle C1 et +
645 // sur la droite OnLine. +
646 // Les solutions sont representees par les cercles : +
647 // - de centre Pntcen(xc,yc) +
648 // - de rayon Radius. +
649 //=========================================================================
651 Geom2dGcc_Circ2dTanOnRadGeo::
652 Geom2dGcc_Circ2dTanOnRadGeo (const gp_Pnt2d& Point1 ,
653 const Geom2dAdaptor_Curve& OnCurv ,
654 const Standard_Real Radius ,
655 const Standard_Real Tolerance ):
657 //=========================================================================
658 // Initialisation des champs. +
659 //=========================================================================
661 cirsol(1,aNbSolMAX) ,
662 qualifier1(1,aNbSolMAX) ,
663 TheSame1(1,aNbSolMAX) ,
664 pnttg1sol(1,aNbSolMAX) ,
665 pntcen3(1,aNbSolMAX) ,
666 par1sol(1,aNbSolMAX) ,
667 pararg1(1,aNbSolMAX) ,
671 //=========================================================================
673 //=========================================================================
675 gp_Dir2d dirx(1.0,0.0);
676 Standard_Real thefirst = -100000.;
677 Standard_Real thelast = 100000.;
678 Standard_Real firstparam;
679 Standard_Real lastparam;
680 Standard_Real Tol = Abs(Tolerance);
681 WellDone = Standard_False;
685 throw Standard_NegativeValue();
688 // gp_Dir2d Dir(-y1dir,x1dir);
689 gp_Circ2d Circ(gp_Ax2d(Point1,gp_Dir2d(1.,0.)),Radius);
690 IntRes2d_Domain D1(ElCLib::Value(0.,Circ), 0.,Tol,
691 ElCLib::Value(2.*M_PI,Circ),2*M_PI,Tol);
692 D1.SetEquivalentParameters(0.,2.*M_PI);
693 firstparam = Max(Geom2dGcc_CurveTool::FirstParameter(OnCurv),thefirst);
694 lastparam = Min(Geom2dGcc_CurveTool::LastParameter(OnCurv),thelast);
695 IntRes2d_Domain D2(Geom2dGcc_CurveTool::Value(OnCurv,firstparam),firstparam,Tol,
696 Geom2dGcc_CurveTool::Value(OnCurv,lastparam),lastparam,Tol);
697 Geom2dInt_TheIntConicCurveOfGInter Intp(Circ,D1,OnCurv,D2,Tol,Tol);
699 if (!Intp.IsEmpty()) {
700 for (Standard_Integer i = 1 ; i <= Intp.NbPoints() && NbrSol < aNbSolMAX; i++) {
702 gp_Pnt2d Center(Intp.Point(i).Value());
703 cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
704 // =======================================================
705 qualifier1(NbrSol) = GccEnt_noqualifier;
706 TheSame1(NbrSol) = 0;
707 pararg1(NbrSol) = Intp.Point(i).ParamOnFirst();
708 parcen3(NbrSol) = Intp.Point(i).ParamOnSecond();
709 par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
711 pnttg1sol(NbrSol) = Point1;
712 pntcen3(NbrSol) = Center;
714 WellDone = Standard_True;
720 //=========================================================================
722 Standard_Boolean Geom2dGcc_Circ2dTanOnRadGeo::
723 IsDone () const { return WellDone; }
725 Standard_Integer Geom2dGcc_Circ2dTanOnRadGeo::
726 NbSolutions () const { return NbrSol; }
728 gp_Circ2d Geom2dGcc_Circ2dTanOnRadGeo::
729 ThisSolution (const Standard_Integer Index) const
732 if (Index > NbrSol || Index <= 0)
733 throw Standard_OutOfRange();
735 return cirsol(Index);
738 void Geom2dGcc_Circ2dTanOnRadGeo::
739 WhichQualifier(const Standard_Integer Index ,
740 GccEnt_Position& Qualif1 ) const
742 if (!WellDone) { throw StdFail_NotDone(); }
743 else if (Index <= 0 ||Index > NbrSol) { throw Standard_OutOfRange(); }
745 Qualif1 = qualifier1(Index);
749 void Geom2dGcc_Circ2dTanOnRadGeo::
750 Tangency1 (const Standard_Integer Index,
751 Standard_Real& ParSol,
752 Standard_Real& ParArg,
753 gp_Pnt2d& PntSol) const{
755 throw StdFail_NotDone();
757 else if (Index <= 0 ||Index > NbrSol) {
758 throw Standard_OutOfRange();
761 ParSol = par1sol(Index);
762 ParArg = pararg1(Index);
763 PntSol = gp_Pnt2d(pnttg1sol(Index));
767 void Geom2dGcc_Circ2dTanOnRadGeo::
768 CenterOn3 (const Standard_Integer Index,
769 Standard_Real& ParArg,
770 gp_Pnt2d& PntSol) const {
772 throw StdFail_NotDone();
774 else if (Index <= 0 ||Index > NbrSol) {
775 throw Standard_OutOfRange();
778 ParArg = parcen3(Index);
779 PntSol = pnttg1sol(Index);
783 Standard_Boolean Geom2dGcc_Circ2dTanOnRadGeo::
784 IsTheSame1 (const Standard_Integer Index) const
786 if (!WellDone) throw StdFail_NotDone();
787 if (Index <= 0 ||Index > NbrSol) throw Standard_OutOfRange();
789 if (TheSame1(Index) == 0)
790 return Standard_False;
792 return Standard_True;