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_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>
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_HCurve) HCu1 = new Geom2dAdaptor_HCurve(Cu1);
128 Adaptor2d_OffsetCurve C2(HCu1,Coef(jcote1));
129 firstparam = Max(C2.FirstParameter(),thefirst);
130 lastparam = Min(C2.LastParameter(),thelast);
131 IntRes2d_Domain D2(C2.Value(firstparam), firstparam, Tol,
132 C2.Value(lastparam), lastparam, Tol);
133 Intp.Perform(OnLine,D1,C2,D2,Tol,Tol);
135 if (!Intp.IsEmpty()) {
136 for (Standard_Integer i = 1 ; i <= Intp.NbPoints() && NbrSol < aNbSolMAX; i++) {
138 gp_Pnt2d Center(Intp.Point(i).Value());
139 cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
140 // =======================================================
141 qualifier1(NbrSol) = Qualified1.Qualifier();
142 TheSame1(NbrSol) = 0;
143 pararg1(NbrSol) = Intp.Point(i).ParamOnSecond();
144 parcen3(NbrSol) = Intp.Point(i).ParamOnFirst();
145 par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
147 pnttg1sol(NbrSol) = gp_Pnt2d(Geom2dGcc_CurveTool::Value(Cu1,pararg1(NbrSol)));
148 pntcen3(NbrSol) = Center;
151 WellDone = Standard_True;
157 //=========================================================================
158 // Cercle tangent : a un cercle Qualified1 (C1). +
159 // centre : sur une droite OnLine. +
160 // de rayon : Radius. +
162 // On initialise le tableau de solutions cirsol ainsi que tous les +
164 // On elimine en fonction du qualifieur les cas ne presentant pas de +
166 // On resoud l equation du second degre indiquant que le point de centre +
167 // recherche (xc,yc) est a une distance Radius du cercle C1 et +
168 // sur la droite OnLine. +
169 // Les solutions sont representees par les cercles : +
170 // - de centre Pntcen(xc,yc) +
171 // - de rayon Radius. +
172 //=========================================================================
174 Geom2dGcc_Circ2dTanOnRadGeo::
175 Geom2dGcc_Circ2dTanOnRadGeo (const Geom2dGcc_QCurve& Qualified1,
176 const gp_Circ2d& OnCirc ,
177 const Standard_Real Radius ,
178 const Standard_Real Tolerance ):
180 //=========================================================================
181 // Initialisation des champs. +
182 //=========================================================================
184 cirsol(1,aNbSolMAX) ,
185 qualifier1(1,aNbSolMAX) ,
186 TheSame1(1,aNbSolMAX) ,
187 pnttg1sol(1,aNbSolMAX) ,
188 pntcen3(1,aNbSolMAX) ,
189 par1sol(1,aNbSolMAX) ,
190 pararg1(1,aNbSolMAX) ,
194 //=========================================================================
196 //=========================================================================
198 gp_Dir2d dirx(1.0,0.0);
199 Standard_Real thefirst = -100000.;
200 Standard_Real thelast = 100000.;
201 Standard_Real firstparam;
202 Standard_Real lastparam;
203 Standard_Real Tol = Abs(Tolerance);
204 Standard_Integer nbrcote1=0;
205 WellDone = Standard_False;
207 if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() ||
208 Qualified1.IsOutside() || Qualified1.IsUnqualified())) {
209 throw GccEnt_BadQualifier();
212 TColStd_Array1OfReal cote1(1,2);
213 Geom2dAdaptor_Curve Cu1 = Qualified1.Qualified();
216 throw Standard_NegativeValue();
219 if (Qualified1.IsEnclosed()) {
220 // ===========================
224 else if(Qualified1.IsOutside()) {
225 // ===============================
229 else if(Qualified1.IsUnqualified()) {
230 // ===================================
235 IntRes2d_Domain D1(ElCLib::Value(0.,OnCirc), 0.,Tol,
236 ElCLib::Value(2.*M_PI,OnCirc),2.*M_PI,Tol);
237 D1.SetEquivalentParameters(0.,2.*M_PI);
238 Geom2dInt_TheIntConicCurveOfGInter Intp;
239 for (Standard_Integer jcote1 = 1 ; jcote1 <= nbrcote1 ; jcote1++) {
240 Handle(Geom2dAdaptor_HCurve) HCu1 = new Geom2dAdaptor_HCurve(Cu1);
241 Adaptor2d_OffsetCurve C2(HCu1,cote1(jcote1));
242 firstparam = Max(C2.FirstParameter(),thefirst);
243 lastparam = Min(C2.LastParameter(),thelast);
244 IntRes2d_Domain D2(C2.Value(firstparam),firstparam,Tol,
245 C2.Value(lastparam),lastparam,Tol);
246 Intp.Perform(OnCirc,D1,C2,D2,Tol,Tol);
248 if (!Intp.IsEmpty()) {
249 for (Standard_Integer i = 1 ; i <= Intp.NbPoints() && NbrSol < aNbSolMAX; i++) {
251 gp_Pnt2d Center(Intp.Point(i).Value());
252 cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
253 // =======================================================
254 qualifier1(NbrSol) = Qualified1.Qualifier();
255 TheSame1(NbrSol) = 0;
256 pararg1(NbrSol) = Intp.Point(i).ParamOnSecond();
257 parcen3(NbrSol) = Intp.Point(i).ParamOnFirst();
258 par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
260 pnttg1sol(NbrSol) = gp_Pnt2d(Geom2dGcc_CurveTool::Value(Cu1,pararg1(NbrSol)));
261 pntcen3(NbrSol) = Center;
264 WellDone = Standard_True;
270 //=========================================================================
271 // Cercle tangent : a un cercle Qualified1 (C1). +
272 // centre : sur une droite OnLine. +
273 // de rayon : Radius. +
275 // On initialise le tableau de solutions cirsol ainsi que tous les +
277 // On elimine en fonction du qualifieur les cas ne presentant pas de +
279 // On resoud l equation du second degre indiquant que le point de centre +
280 // recherche (xc,yc) est a une distance Radius du cercle C1 et +
281 // sur la droite OnLine. +
282 // Les solutions sont representees par les cercles : +
283 // - de centre Pntcen(xc,yc) +
284 // - de rayon Radius. +
285 //=========================================================================
287 Geom2dGcc_Circ2dTanOnRadGeo::
288 Geom2dGcc_Circ2dTanOnRadGeo (const GccEnt_QualifiedCirc& Qualified1,
289 const Geom2dAdaptor_Curve& OnCurv ,
290 const Standard_Real Radius ,
291 const Standard_Real Tolerance ):
293 //=========================================================================
294 // Initialisation des champs. +
295 //=========================================================================
297 cirsol(1,aNbSolMAX) ,
298 qualifier1(1,aNbSolMAX) ,
299 TheSame1(1,aNbSolMAX) ,
300 pnttg1sol(1,aNbSolMAX) ,
301 pntcen3(1,aNbSolMAX) ,
302 par1sol(1,aNbSolMAX) ,
303 pararg1(1,aNbSolMAX) ,
307 //=========================================================================
309 //=========================================================================
311 gp_Dir2d dirx(1.0,0.0);
312 Standard_Real thefirst = -100000.;
313 Standard_Real thelast = 100000.;
314 Standard_Real firstparam;
315 Standard_Real lastparam;
316 Standard_Real Tol = Abs(Tolerance);
317 Standard_Integer nbrcote1=0;
318 WellDone = Standard_False;
320 if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() ||
321 Qualified1.IsOutside() || Qualified1.IsUnqualified())) {
322 throw GccEnt_BadQualifier();
325 TColStd_Array1OfReal cote1(1,2);
326 gp_Circ2d C1 = Qualified1.Qualified();
327 gp_Pnt2d center1(C1.Location());
328 Standard_Real R1 = C1.Radius();
331 throw Standard_NegativeValue();
334 if (Qualified1.IsEnclosed()) {
335 // ===========================
339 else if(Qualified1.IsOutside()) {
340 // ===============================
344 else if(Qualified1.IsUnqualified()) {
345 // ===================================
350 Geom2dInt_TheIntConicCurveOfGInter Intp;
351 for (Standard_Integer jcote1 = 1 ; jcote1 <= nbrcote1 ; jcote1++) {
352 gp_Circ2d Circ(C1.XAxis(),R1 + cote1(jcote1));
353 IntRes2d_Domain D1(ElCLib::Value(0.,Circ), 0.,Tol,
354 ElCLib::Value(2.*M_PI,Circ),2.*M_PI,Tol);
355 D1.SetEquivalentParameters(0.,2.*M_PI);
356 firstparam = Max(Geom2dGcc_CurveTool::FirstParameter(OnCurv),thefirst);
357 lastparam = Min(Geom2dGcc_CurveTool::LastParameter(OnCurv),thelast);
358 IntRes2d_Domain D2(Geom2dGcc_CurveTool::Value(OnCurv,firstparam),firstparam,Tol,
359 Geom2dGcc_CurveTool::Value(OnCurv,lastparam),lastparam,Tol);
360 Intp.Perform(Circ,D1,OnCurv,D2,Tol,Tol);
362 if (!Intp.IsEmpty()) {
363 for (Standard_Integer i = 1 ; i <= Intp.NbPoints() && NbrSol < aNbSolMAX; i++) {
365 gp_Pnt2d Center(Intp.Point(i).Value());
366 cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
367 // =======================================================
368 Standard_Real distcc1 = Center.Distance(center1);
369 if (!Qualified1.IsUnqualified()) {
370 qualifier1(NbrSol) = Qualified1.Qualifier();
372 else if (Abs(distcc1+Radius-R1) < Tol) {
373 qualifier1(NbrSol) = GccEnt_enclosed;
375 else if (Abs(distcc1-R1-Radius) < Tol) {
376 qualifier1(NbrSol) = GccEnt_outside;
378 else { qualifier1(NbrSol) = GccEnt_enclosing; }
379 TheSame1(NbrSol) = 0;
380 pararg1(NbrSol) = Intp.Point(i).ParamOnFirst();
381 parcen3(NbrSol) = Intp.Point(i).ParamOnSecond();
382 par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
384 pnttg1sol(NbrSol) = ElCLib::Value(pararg1(NbrSol),C1);
385 pntcen3(NbrSol) = Center;
388 WellDone = Standard_True;
394 //=========================================================================
395 // Cercle tangent : a un cercle Qualified1 (C1). +
396 // centre : sur une droite OnLine. +
397 // de rayon : Radius. +
399 // On initialise le tableau de solutions cirsol ainsi que tous les +
401 // On elimine en fonction du qualifieur les cas ne presentant pas de +
403 // On resoud l equation du second degre indiquant que le point de centre +
404 // recherche (xc,yc) est a une distance Radius du cercle C1 et +
405 // sur la droite OnLine. +
406 // Les solutions sont representees par les cercles : +
407 // - de centre Pntcen(xc,yc) +
408 // - de rayon Radius. +
409 //=========================================================================
411 Geom2dGcc_Circ2dTanOnRadGeo::
412 Geom2dGcc_Circ2dTanOnRadGeo (const GccEnt_QualifiedLin& Qualified1,
413 const Geom2dAdaptor_Curve& OnCurv ,
414 const Standard_Real Radius ,
415 const Standard_Real Tolerance ):
417 //=========================================================================
418 // Initialisation des champs. +
419 //=========================================================================
421 cirsol(1,aNbSolMAX) ,
422 qualifier1(1,aNbSolMAX) ,
423 TheSame1(1,aNbSolMAX) ,
424 pnttg1sol(1,aNbSolMAX) ,
425 pntcen3(1,aNbSolMAX) ,
426 par1sol(1,aNbSolMAX) ,
427 pararg1(1,aNbSolMAX) ,
431 //=========================================================================
433 //=========================================================================
435 gp_Dir2d dirx(1.0,0.0);
436 Standard_Real thefirst = -100000.;
437 Standard_Real thelast = 100000.;
438 Standard_Real firstparam;
439 Standard_Real lastparam;
440 Standard_Real Tol = Abs(Tolerance);
441 WellDone = Standard_False;
443 if (!(Qualified1.IsEnclosed() ||
444 Qualified1.IsOutside() || Qualified1.IsUnqualified())) {
445 throw GccEnt_BadQualifier();
448 Standard_Integer nbrcote1=0;
449 TColStd_Array1OfReal cote1(1,2);
450 gp_Lin2d L1 = Qualified1.Qualified();
451 gp_Pnt2d origin1(L1.Location());
452 gp_Dir2d dir1(L1.Direction());
453 gp_Dir2d norm1(-dir1.Y(),dir1.X());
456 throw Standard_NegativeValue();
459 if (Qualified1.IsEnclosed()) {
460 // ===========================
464 else if(Qualified1.IsOutside()) {
465 // ===============================
469 else if(Qualified1.IsUnqualified()) {
470 // ===================================
475 Geom2dInt_TheIntConicCurveOfGInter Intp;
476 for (Standard_Integer jcote1 = 1 ; jcote1 <= nbrcote1 ; jcote1++) {
477 gp_Pnt2d Point(dir1.XY()+cote1(jcote1)*norm1.XY());
478 gp_Lin2d Line(Point,dir1); // ligne avec deport.
480 firstparam = Max(Geom2dGcc_CurveTool::FirstParameter(OnCurv),thefirst);
481 lastparam = Min(Geom2dGcc_CurveTool::LastParameter(OnCurv),thelast);
482 IntRes2d_Domain D2(Geom2dGcc_CurveTool::Value(OnCurv,firstparam),firstparam,Tol,
483 Geom2dGcc_CurveTool::Value(OnCurv,lastparam),lastparam,Tol);
484 Intp.Perform(Line,D1,OnCurv,D2,Tol,Tol);
486 if (!Intp.IsEmpty()) {
487 for (Standard_Integer i = 1 ; i <= Intp.NbPoints() && NbrSol < aNbSolMAX; i++) {
489 gp_Pnt2d Center(Intp.Point(i).Value());
490 cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
491 // =======================================================
492 gp_Dir2d dc1(origin1.XY()-Center.XY());
493 if (!Qualified1.IsUnqualified()) {
494 qualifier1(NbrSol) = Qualified1.Qualifier();
496 else if (dc1.Dot(norm1) > 0.0) {
497 qualifier1(NbrSol) = GccEnt_outside;
499 else { qualifier1(NbrSol) = GccEnt_enclosed; }
500 TheSame1(NbrSol) = 0;
501 pararg1(NbrSol) = Intp.Point(i).ParamOnFirst();
502 parcen3(NbrSol) = Intp.Point(i).ParamOnSecond();
503 par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
505 pnttg1sol(NbrSol) = ElCLib::Value(pararg1(NbrSol),L1);
506 pntcen3(NbrSol) = Center;
509 WellDone = Standard_True;
515 //=========================================================================
516 // Cercle tangent : a un cercle Qualified1 (C1). +
517 // centre : sur une droite OnLine. +
518 // de rayon : Radius. +
520 // On initialise le tableau de solutions cirsol ainsi que tous les +
522 // On elimine en fonction du qualifieur les cas ne presentant pas de +
524 // On resoud l equation du second degre indiquant que le point de centre +
525 // recherche (xc,yc) est a une distance Radius du cercle C1 et +
526 // sur la droite OnLine. +
527 // Les solutions sont representees par les cercles : +
528 // - de centre Pntcen(xc,yc) +
529 // - de rayon Radius. +
530 //=========================================================================
532 Geom2dGcc_Circ2dTanOnRadGeo::
533 Geom2dGcc_Circ2dTanOnRadGeo (const Geom2dGcc_QCurve& Qualified1,
534 const Geom2dAdaptor_Curve& OnCurv ,
535 const Standard_Real Radius ,
536 const Standard_Real Tolerance ):
538 //=========================================================================
539 // Initialisation des champs. +
540 //=========================================================================
542 cirsol(1,aNbSolMAX) ,
543 qualifier1(1,aNbSolMAX) ,
544 TheSame1(1,aNbSolMAX) ,
545 pnttg1sol(1,aNbSolMAX) ,
546 pntcen3(1,aNbSolMAX) ,
547 par1sol(1,aNbSolMAX) ,
548 pararg1(1,aNbSolMAX) ,
552 //=========================================================================
554 //=========================================================================
556 gp_Dir2d dirx(1.0,0.0);
557 Standard_Real thefirst = -100000.;
558 Standard_Real thelast = 100000.;
559 Standard_Real firstparam;
560 Standard_Real lastparam;
561 Standard_Real Tol = Abs(Tolerance);
562 Standard_Integer nbrcote1=0;
563 WellDone = Standard_False;
565 if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() ||
566 Qualified1.IsOutside() || Qualified1.IsUnqualified())) {
567 throw GccEnt_BadQualifier();
570 TColStd_Array1OfReal cote1(1,2);
571 Geom2dAdaptor_Curve Cu1 = Qualified1.Qualified();
574 throw Standard_NegativeValue();
577 if (Qualified1.IsEnclosed()) {
578 // ===========================
582 else if(Qualified1.IsOutside()) {
583 // ===============================
587 else if(Qualified1.IsUnqualified()) {
588 // ===================================
593 Geom2dInt_GInter Intp;
594 for (Standard_Integer jcote1 = 1 ; jcote1 <= nbrcote1 ; jcote1++) {
595 Handle(Geom2dAdaptor_HCurve) HCu1 = new Geom2dAdaptor_HCurve(Cu1);
596 Adaptor2d_OffsetCurve C1(HCu1,cote1(jcote1));
597 firstparam = Max(C1.FirstParameter(),thefirst);
598 lastparam = Min(C1.LastParameter(),thelast);
599 IntRes2d_Domain D1(C1.Value(firstparam), firstparam, Tol,
600 C1.Value(lastparam), lastparam, Tol);
601 Handle(Geom2dAdaptor_HCurve) HOnCurv = new Geom2dAdaptor_HCurve(OnCurv);
602 Adaptor2d_OffsetCurve C2(HOnCurv);
603 firstparam = Max(C2.FirstParameter(),thefirst);
604 lastparam = Min(C2.LastParameter(),thelast);
605 IntRes2d_Domain D2(C2.Value(firstparam), firstparam, Tol,
606 C2.Value(lastparam), lastparam, Tol);
607 Intp.Perform(C1,D1,C2,D2,Tol,Tol);
609 if (!Intp.IsEmpty()) {
610 for (Standard_Integer i = 1 ; i <= Intp.NbPoints() && NbrSol < aNbSolMAX; i++) {
612 gp_Pnt2d Center(Intp.Point(i).Value());
613 cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
614 // =======================================================
615 qualifier1(NbrSol) = Qualified1.Qualifier();
616 TheSame1(NbrSol) = 0;
617 pararg1(NbrSol) = Intp.Point(i).ParamOnFirst();
618 parcen3(NbrSol) = Intp.Point(i).ParamOnSecond();
619 par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
621 pnttg1sol(NbrSol) = gp_Pnt2d(Geom2dGcc_CurveTool::Value(Cu1,pararg1(NbrSol)));
622 pntcen3(NbrSol) = Center;
625 WellDone = Standard_True;
631 //=========================================================================
632 // Cercle tangent : a un cercle Qualified1 (C1). +
633 // centre : sur une droite OnLine. +
634 // de rayon : Radius. +
636 // On initialise le tableau de solutions cirsol ainsi que tous les +
638 // On elimine en fonction du qualifieur les cas ne presentant pas de +
640 // On resoud l equation du second degre indiquant que le point de centre +
641 // recherche (xc,yc) est a une distance Radius du cercle C1 et +
642 // sur la droite OnLine. +
643 // Les solutions sont representees par les cercles : +
644 // - de centre Pntcen(xc,yc) +
645 // - de rayon Radius. +
646 //=========================================================================
648 Geom2dGcc_Circ2dTanOnRadGeo::
649 Geom2dGcc_Circ2dTanOnRadGeo (const gp_Pnt2d& Point1 ,
650 const Geom2dAdaptor_Curve& OnCurv ,
651 const Standard_Real Radius ,
652 const Standard_Real Tolerance ):
654 //=========================================================================
655 // Initialisation des champs. +
656 //=========================================================================
658 cirsol(1,aNbSolMAX) ,
659 qualifier1(1,aNbSolMAX) ,
660 TheSame1(1,aNbSolMAX) ,
661 pnttg1sol(1,aNbSolMAX) ,
662 pntcen3(1,aNbSolMAX) ,
663 par1sol(1,aNbSolMAX) ,
664 pararg1(1,aNbSolMAX) ,
668 //=========================================================================
670 //=========================================================================
672 gp_Dir2d dirx(1.0,0.0);
673 Standard_Real thefirst = -100000.;
674 Standard_Real thelast = 100000.;
675 Standard_Real firstparam;
676 Standard_Real lastparam;
677 Standard_Real Tol = Abs(Tolerance);
678 WellDone = Standard_False;
682 throw Standard_NegativeValue();
685 // gp_Dir2d Dir(-y1dir,x1dir);
686 gp_Circ2d Circ(gp_Ax2d(Point1,gp_Dir2d(1.,0.)),Radius);
687 IntRes2d_Domain D1(ElCLib::Value(0.,Circ), 0.,Tol,
688 ElCLib::Value(2.*M_PI,Circ),2*M_PI,Tol);
689 D1.SetEquivalentParameters(0.,2.*M_PI);
690 firstparam = Max(Geom2dGcc_CurveTool::FirstParameter(OnCurv),thefirst);
691 lastparam = Min(Geom2dGcc_CurveTool::LastParameter(OnCurv),thelast);
692 IntRes2d_Domain D2(Geom2dGcc_CurveTool::Value(OnCurv,firstparam),firstparam,Tol,
693 Geom2dGcc_CurveTool::Value(OnCurv,lastparam),lastparam,Tol);
694 Geom2dInt_TheIntConicCurveOfGInter Intp(Circ,D1,OnCurv,D2,Tol,Tol);
696 if (!Intp.IsEmpty()) {
697 for (Standard_Integer i = 1 ; i <= Intp.NbPoints() && NbrSol < aNbSolMAX; i++) {
699 gp_Pnt2d Center(Intp.Point(i).Value());
700 cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
701 // =======================================================
702 qualifier1(NbrSol) = GccEnt_noqualifier;
703 TheSame1(NbrSol) = 0;
704 pararg1(NbrSol) = Intp.Point(i).ParamOnFirst();
705 parcen3(NbrSol) = Intp.Point(i).ParamOnSecond();
706 par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
708 pnttg1sol(NbrSol) = Point1;
709 pntcen3(NbrSol) = Center;
711 WellDone = Standard_True;
717 //=========================================================================
719 Standard_Boolean Geom2dGcc_Circ2dTanOnRadGeo::
720 IsDone () const { return WellDone; }
722 Standard_Integer Geom2dGcc_Circ2dTanOnRadGeo::
723 NbSolutions () const { return NbrSol; }
725 gp_Circ2d Geom2dGcc_Circ2dTanOnRadGeo::
726 ThisSolution (const Standard_Integer Index) const
729 if (Index > NbrSol || Index <= 0)
730 throw Standard_OutOfRange();
732 return cirsol(Index);
735 void Geom2dGcc_Circ2dTanOnRadGeo::
736 WhichQualifier(const Standard_Integer Index ,
737 GccEnt_Position& Qualif1 ) const
739 if (!WellDone) { throw StdFail_NotDone(); }
740 else if (Index <= 0 ||Index > NbrSol) { throw Standard_OutOfRange(); }
742 Qualif1 = qualifier1(Index);
746 void Geom2dGcc_Circ2dTanOnRadGeo::
747 Tangency1 (const Standard_Integer Index,
748 Standard_Real& ParSol,
749 Standard_Real& ParArg,
750 gp_Pnt2d& PntSol) const{
752 throw StdFail_NotDone();
754 else if (Index <= 0 ||Index > NbrSol) {
755 throw Standard_OutOfRange();
758 ParSol = par1sol(Index);
759 ParArg = pararg1(Index);
760 PntSol = gp_Pnt2d(pnttg1sol(Index));
764 void Geom2dGcc_Circ2dTanOnRadGeo::
765 CenterOn3 (const Standard_Integer Index,
766 Standard_Real& ParArg,
767 gp_Pnt2d& PntSol) const {
769 throw StdFail_NotDone();
771 else if (Index <= 0 ||Index > NbrSol) {
772 throw Standard_OutOfRange();
775 ParArg = parcen3(Index);
776 PntSol = pnttg1sol(Index);
780 Standard_Boolean Geom2dGcc_Circ2dTanOnRadGeo::
781 IsTheSame1 (const Standard_Integer Index) const
783 if (!WellDone) throw StdFail_NotDone();
784 if (Index <= 0 ||Index > NbrSol) throw Standard_OutOfRange();
786 if (TheSame1(Index) == 0)
787 return Standard_False;
789 return Standard_True;