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 #include <Geom2dGcc_Circ2d2TanRadGeo.ixx>
18 #include <gp_Ax2d.hxx>
19 #include <gp_Circ2d.hxx>
20 #include <gp_Lin2d.hxx>
21 #include <Standard_NegativeValue.hxx>
22 #include <Standard_OutOfRange.hxx>
23 #include <StdFail_NotDone.hxx>
24 #include <TColStd_Array1OfReal.hxx>
25 #include <GccEnt_BadQualifier.hxx>
26 #include <IntRes2d_Domain.hxx>
27 #include <IntRes2d_IntersectionPoint.hxx>
29 #include <Geom2dGcc_CurveTool.hxx>
30 #include <Adaptor3d_OffsetCurve.hxx>
31 #include <Geom2dAdaptor_HCurve.hxx>
32 #include <Geom2dGcc_CurveToolGeo.hxx>
33 #include <Geom2dInt_GInter.hxx>
35 // circulaire tant a une courbe et une droite ,de rayon donne
36 //==============================================================
38 //========================================================================
39 // On initialise WellDone a false. +
40 // On recupere la courbe Cu2 et la droite L1. +
41 // On sort en erreur dans les cas ou la construction est impossible. +
42 // On fait la parallele a Cu2 dans le bon sens. +
43 // On fait la parallele a L1 dans le bon sens. +
44 // On intersecte les paralleles ==> point de centre de la solution. +
45 // On cree la solution qu on ajoute aux solutions deja trouvees. +
46 // On remplit les champs. +
47 //========================================================================
49 Geom2dGcc_Circ2d2TanRadGeo::
50 Geom2dGcc_Circ2d2TanRadGeo (const GccEnt_QualifiedLin& Qualified1,
51 const Geom2dGcc_QCurve& Qualified2,
52 const Standard_Real Radius ,
53 const Standard_Real Tolerance ):
55 //========================================================================
56 // initialisation des champs. +
57 //========================================================================
72 //========================================================================
74 //========================================================================
76 Standard_Real Tol = Abs(Tolerance);
77 Standard_Real thefirst = -100000.;
78 Standard_Real thelast = 100000.;
79 Standard_Real firstparam;
80 Standard_Real lastparam;
82 TColStd_Array1OfReal cote1(1,2);
83 TColStd_Array1OfReal cote2(1,2);
84 Standard_Integer nbrcote1=0;
85 Standard_Integer nbrcote2=0;
86 WellDone = Standard_False;
88 if (!(Qualified1.IsEnclosed() ||
89 Qualified1.IsOutside() || Qualified1.IsUnqualified()) ||
90 !(Qualified2.IsEnclosed() || Qualified2.IsEnclosing() ||
91 Qualified2.IsOutside() || Qualified2.IsUnqualified())) {
93 GccEnt_BadQualifier::Raise();
96 gp_Lin2d L1 = Qualified1.Qualified();
97 Standard_Real x1dir = (L1.Direction()).X();
98 Standard_Real y1dir = (L1.Direction()).Y();
99 Standard_Real lxloc = (L1.Location()).X();
100 Standard_Real lyloc = (L1.Location()).Y();
101 gp_Pnt2d origin1(lxloc,lyloc);
102 gp_Dir2d normL1(-y1dir,x1dir);
103 Geom2dAdaptor_Curve Cu2= Qualified2.Qualified();
104 if (Radius < 0.0) { Standard_NegativeValue::Raise(); }
106 if (Qualified1.IsEnclosed() && Qualified2.IsEnclosed()) {
107 // =======================================================
113 else if(Qualified1.IsEnclosed() && Qualified2.IsOutside()) {
114 // ==========================================================
120 else if (Qualified1.IsOutside() && Qualified2.IsEnclosed()) {
121 // ===========================================================
127 else if(Qualified1.IsOutside() && Qualified2.IsOutside()) {
128 // =========================================================
134 if(Qualified1.IsEnclosed() && Qualified2.IsUnqualified()) {
135 // =========================================================
142 if(Qualified1.IsUnqualified() && Qualified2.IsEnclosed()) {
143 // =========================================================
150 else if(Qualified1.IsOutside() && Qualified2.IsUnqualified()) {
151 // =============================================================
158 if(Qualified1.IsUnqualified() && Qualified2.IsOutside()) {
159 // ========================================================
166 else if(Qualified1.IsUnqualified() && Qualified2.IsUnqualified()) {
167 // =================================================================
175 gp_Dir2d Dir(-y1dir,x1dir);
176 for (Standard_Integer jcote1 = 1 ; jcote1 <= nbrcote1 ; jcote1++) {
177 gp_Pnt2d Point(L1.Location().XY()+cote1(jcote1)*Dir.XY());
178 gp_Lin2d Line(Point,L1.Direction()); // ligne avec deport.
180 for (Standard_Integer jcote2 = 1 ; jcote2 <= nbrcote2 ; jcote2++) {
181 Handle(Geom2dAdaptor_HCurve) HCu2 = new Geom2dAdaptor_HCurve(Cu2);
182 Adaptor3d_OffsetCurve C2(HCu2,cote2(jcote2));
183 firstparam = Max(Geom2dGcc_CurveToolGeo::FirstParameter(C2),thefirst);
184 lastparam = Min(Geom2dGcc_CurveToolGeo::LastParameter(C2),thelast);
185 IntRes2d_Domain D2(Geom2dGcc_CurveToolGeo::Value(C2,firstparam),firstparam,Tol,
186 Geom2dGcc_CurveToolGeo::Value(C2,lastparam),lastparam,Tol);
187 Geom2dInt_TheIntConicCurveOfGInter Intp(Line,D1,C2,D2,Tol,Tol);
189 if (!Intp.IsEmpty()) {
190 for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++) {
192 gp_Pnt2d Center(Intp.Point(i).Value());
193 cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
194 // =======================================================
195 gp_Dir2d dc1(origin1.XY()-Center.XY());
196 qualifier2(NbrSol) = Qualified2.Qualifier();
197 if (!Qualified1.IsUnqualified()) {
198 qualifier1(NbrSol) = Qualified1.Qualifier();
200 else if (dc1.Dot(normL1) > 0.0) {
201 qualifier1(NbrSol) = GccEnt_outside;
203 else { qualifier1(NbrSol) = GccEnt_enclosed; }
204 TheSame1(NbrSol) = 0;
205 TheSame2(NbrSol) = 0;
206 pararg1(NbrSol) = Intp.Point(i).ParamOnFirst();
207 pararg2(NbrSol) = Intp.Point(i).ParamOnSecond();
208 pnttg1sol(NbrSol) = ElCLib::Value(pararg1(NbrSol),L1);
209 pnttg2sol(NbrSol) = Geom2dGcc_CurveTool::Value(Cu2,pararg2(NbrSol));
210 par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
212 par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
216 WellDone = Standard_True;
223 // circulaire tant a une courbe et un cercle ,de rayon donne
224 //=============================================================
226 //========================================================================
227 // On initialise WellDone a false. +
228 // On recupere la courbe Cu2 et le cercle C1. +
229 // On sort en erreur dans les cas ou la construction est impossible. +
230 // On fait la parallele a Cu2 dans le bon sens. +
231 // On fait la parallele a C1 dans le bon sens. +
232 // On intersecte les paralleles ==> point de centre de la solution. +
233 // On cree la solution qu on ajoute aux solutions deja trouvees. +
234 // On remplit les champs. +
235 //========================================================================
237 Geom2dGcc_Circ2d2TanRadGeo::
238 Geom2dGcc_Circ2d2TanRadGeo (const GccEnt_QualifiedCirc& Qualified1,
239 const Geom2dGcc_QCurve& Qualified2,
240 const Standard_Real Radius ,
241 const Standard_Real Tolerance ):
243 //========================================================================
244 // initialisation des champs. +
245 //========================================================================
260 //========================================================================
262 //========================================================================
264 Standard_Real Tol = Abs(Tolerance);
265 Standard_Real thefirst = -100000.;
266 Standard_Real thelast = 100000.;
267 Standard_Real firstparam;
268 Standard_Real lastparam;
269 gp_Dir2d dirx(1.,0.);
270 TColStd_Array1OfReal cote1(1,2);
271 TColStd_Array1OfReal cote2(1,2);
272 Standard_Integer nbrcote1=0;
273 Standard_Integer nbrcote2=0;
274 WellDone = Standard_False;
276 if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() ||
277 Qualified1.IsOutside() || Qualified1.IsUnqualified()) ||
278 !(Qualified2.IsEnclosed() || Qualified2.IsEnclosing() ||
279 Qualified2.IsOutside() || Qualified2.IsUnqualified())) {
280 GccEnt_BadQualifier::Raise();
283 gp_Circ2d C1 = Qualified1.Qualified();
284 gp_Pnt2d center1(C1.Location());
285 Geom2dAdaptor_Curve Cu2 = Qualified2.Qualified();
286 if (Radius < 0.0) { Standard_NegativeValue::Raise(); }
288 if (Qualified1.IsEnclosed() && Qualified2.IsEnclosed()) {
289 // =======================================================
295 else if(Qualified1.IsEnclosed() && Qualified2.IsOutside()) {
296 // ==========================================================
302 else if (Qualified1.IsOutside() && Qualified2.IsEnclosed()) {
303 // ===========================================================
309 else if(Qualified1.IsOutside() && Qualified2.IsOutside()) {
310 // =========================================================
316 if(Qualified1.IsEnclosed() && Qualified2.IsUnqualified()) {
317 // =========================================================
324 if(Qualified1.IsUnqualified() && Qualified2.IsEnclosed()) {
325 // =========================================================
332 else if(Qualified1.IsOutside() && Qualified2.IsUnqualified()) {
333 // =============================================================
340 if(Qualified1.IsUnqualified() && Qualified2.IsOutside()) {
341 // ========================================================
348 else if(Qualified1.IsUnqualified() && Qualified2.IsUnqualified()) {
349 // =================================================================
357 Standard_Real R1 = C1.Radius();
358 Geom2dInt_TheIntConicCurveOfGInter Intp;
359 for (Standard_Integer jcote1 = 1 ; jcote1 <= nbrcote1 ; jcote1++) {
360 gp_Circ2d Circ(C1.XAxis(),R1+cote1(jcote1));
361 IntRes2d_Domain D1(ElCLib::Value(0.,Circ), 0.,Tol,
362 ElCLib::Value(2.*M_PI,Circ),2.*M_PI,Tol);
363 D1.SetEquivalentParameters(0.,2.*M_PI);
364 for (Standard_Integer jcote2 = 1 ; jcote2 <= nbrcote2 ; jcote2++) {
365 Handle(Geom2dAdaptor_HCurve) HCu2 = new Geom2dAdaptor_HCurve(Cu2);
366 Adaptor3d_OffsetCurve C2(HCu2,cote2(jcote2));
367 firstparam = Max(Geom2dGcc_CurveToolGeo::FirstParameter(C2),thefirst);
368 lastparam = Min(Geom2dGcc_CurveToolGeo::LastParameter(C2),thelast);
369 IntRes2d_Domain D2(Geom2dGcc_CurveToolGeo::Value(C2,firstparam),firstparam,Tol,
370 Geom2dGcc_CurveToolGeo::Value(C2,lastparam),lastparam,Tol);
371 Intp.Perform(Circ,D1,C2,D2,Tol,Tol);
373 if (!Intp.IsEmpty()) {
374 for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++) {
376 gp_Pnt2d Center(Intp.Point(i).Value());
377 cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
378 // =======================================================
380 gp_Dir2d dir1(Center.XY()-center1.XY());
385 Standard_Real distcc1 = Center.Distance(center1);
386 if (!Qualified1.IsUnqualified()) {
387 qualifier1(NbrSol) = Qualified1.Qualifier();
389 else if (Abs(distcc1+Radius-R1) < Tol) {
390 qualifier1(NbrSol) = GccEnt_enclosed;
392 else if (Abs(distcc1-R1-Radius) < Tol) {
393 qualifier1(NbrSol) = GccEnt_outside;
395 else { qualifier1(NbrSol) = GccEnt_enclosing; }
396 qualifier2(NbrSol) = Qualified2.Qualifier();
397 TheSame1(NbrSol) = 0;
398 TheSame2(NbrSol) = 0;
399 pararg1(NbrSol) = Intp.Point(i).ParamOnFirst();
400 pararg2(NbrSol) = Intp.Point(i).ParamOnSecond();
401 pnttg1sol(NbrSol) = ElCLib::Value(pararg1(NbrSol),C1);
402 pnttg2sol(NbrSol) = Geom2dGcc_CurveTool::Value(Cu2,pararg2(NbrSol));
403 par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
405 par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
409 WellDone = Standard_True;
416 // circulaire tant a une courbe et un point ,de rayon donne
417 //============================================================
419 //========================================================================
420 // On initialise WellDone a false. +
421 // On recupere la courbe Cu1 et le point P2. +
422 // On sort en erreur dans les cas ou la construction est impossible. +
423 // On fait la parallele a Cu1 dans le bon sens. +
424 // On fait la parallele a P2 dans le bon sens. +
425 // On intersecte les paralleles ==> point de centre de la solution. +
426 // On cree la solution qu on ajoute aux solutions deja trouvees. +
427 // On remplit les champs. +
428 //========================================================================
430 Geom2dGcc_Circ2d2TanRadGeo::
431 Geom2dGcc_Circ2d2TanRadGeo (const Geom2dGcc_QCurve& Qualified1,
432 const gp_Pnt2d& Point2 ,
433 const Standard_Real Radius ,
434 const Standard_Real Tolerance ):
436 //========================================================================
437 // initialisation des champs. +
438 //========================================================================
453 //========================================================================
455 //========================================================================
457 Standard_Real Tol = Abs(Tolerance);
458 Standard_Real thefirst = -100000.;
459 Standard_Real thelast = 100000.;
460 Standard_Real firstparam;
461 Standard_Real lastparam;
462 gp_Dir2d dirx(1.,0.);
463 TColStd_Array1OfReal cote1(1,2);
464 Standard_Integer nbrcote1=0;
465 WellDone = Standard_False;
467 if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() ||
468 Qualified1.IsOutside() || Qualified1.IsUnqualified())) {
469 GccEnt_BadQualifier::Raise();
472 Geom2dAdaptor_Curve Cu1 = Qualified1.Qualified();
473 if (Radius < 0.0) { Standard_NegativeValue::Raise(); }
475 if (Qualified1.IsEnclosed()) {
476 // ===========================
480 else if(Qualified1.IsOutside()) {
481 // ===============================
485 else if(Qualified1.IsUnqualified()) {
486 // ===================================
491 gp_Circ2d Circ(gp_Ax2d(Point2,gp_Dir2d(1.,0.)),Radius);
492 IntRes2d_Domain D1(ElCLib::Value(0.,Circ), 0.,Tol,
493 ElCLib::Value(M_PI+M_PI,Circ),M_PI+M_PI,Tol);
494 D1.SetEquivalentParameters(0.,M_PI+M_PI);
495 Geom2dInt_TheIntConicCurveOfGInter Intp;
496 for (Standard_Integer jcote1 = 1 ; jcote1 <= nbrcote1 ; jcote1++) {
497 Handle(Geom2dAdaptor_HCurve) HCu1 = new Geom2dAdaptor_HCurve(Cu1);
498 Adaptor3d_OffsetCurve Cu2(HCu1,cote1(jcote1));
499 firstparam = Max(Geom2dGcc_CurveToolGeo::FirstParameter(Cu2),thefirst);
500 lastparam = Min(Geom2dGcc_CurveToolGeo::LastParameter(Cu2),thelast);
501 IntRes2d_Domain D2(Geom2dGcc_CurveToolGeo::Value(Cu2,firstparam),firstparam,Tol,
502 Geom2dGcc_CurveToolGeo::Value(Cu2,lastparam),lastparam,Tol);
503 Intp.Perform(Circ,D1,Cu2,D2,Tol,Tol);
505 if (!Intp.IsEmpty()) {
506 for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++) {
508 gp_Pnt2d Center(Intp.Point(i).Value());
509 cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
510 // =======================================================
511 qualifier1(NbrSol) = Qualified1.Qualifier();
512 qualifier2(NbrSol) = GccEnt_noqualifier;
513 TheSame1(NbrSol) = 0;
514 TheSame2(NbrSol) = 0;
515 pararg1(NbrSol) = Intp.Point(i).ParamOnSecond();
516 pararg2(NbrSol) = 0.;
517 pnttg1sol(NbrSol) = Geom2dGcc_CurveTool::Value(Cu1,pararg1(NbrSol));
518 pnttg2sol(NbrSol) = Point2;
519 par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
521 par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
525 WellDone = Standard_True;
531 static void PrecRoot(const Adaptor3d_OffsetCurve& theC1,
532 const Adaptor3d_OffsetCurve& theC2,
533 const Standard_Real theU0,
534 const Standard_Real theV0,
535 const Standard_Real theUmin,
536 const Standard_Real theUmax,
537 const Standard_Real theVmin,
538 const Standard_Real theVmax,
539 Standard_Real& theUfinal,
540 Standard_Real& theVfinal)
542 const Standard_Real aInitStepU = (theUmax - theUmin)/2.0,
543 aInitStepV = (theVmax - theVmin)/2.0;
545 Standard_Real aStepU = aInitStepU, aStepV = aInitStepV;
547 const Standard_Real aTol = Precision::PConfusion() * Precision::PConfusion();
548 const Standard_Integer aNbIterMax = 100;
553 Geom2dGcc_CurveToolGeo::D1(theC1, theU0, aP1, aD1);
554 Geom2dGcc_CurveToolGeo::D1(theC2, theV0, aP2, aD2);
556 gp_Vec2d vP12(aP1.XY() - aP2.XY());
558 Standard_Real aU = theU0, aV = theV0;
562 Standard_Real aSQDistPrev = aP1.SquareDistance(aP2);
564 Standard_Integer aNbIter = 1;
568 Standard_Real aDetH = aD1.Y()*aD2.X() - aD1.X()*aD2.Y();
572 aU += aStepU*(aD2.Y() * vP12.X() - aD2.X()*vP12.Y())/aDetH;
573 aV += aStepV*(aD1.Y() * vP12.X() - aD1.X()*vP12.Y())/aDetH;
575 if(Abs(aU - theUmin) > 1000.0)
579 if(Abs(aU - theUmax) > 1000.0)
583 if(Abs(aV - theVmin) > 1000.0)
587 if(Abs(aV - theVmax) > 1000.0)
591 Geom2dGcc_CurveToolGeo::D1(theC1, aU, aP1, aD1);
592 Geom2dGcc_CurveToolGeo::D1(theC2, aV, aP2, aD2);
593 const Standard_Real aSQDist = aP1.SquareDistance(aP2);
595 if(Precision::IsInfinite(aSQDist))
599 vP12.SetXY(aP1.XY() - aP2.XY());
601 if(aSQDist < aSQDistPrev)
603 aSQDistPrev = aSQDist;
615 while((aNbIter++ < aNbIterMax) && ((aStepU > aTol) || (aStepV > aTol)));
617 Standard_Boolean isInBound = Standard_True;
618 if(theUfinal < theUmin)
624 isInBound = Standard_False;
627 if(theUfinal > theUmax)
633 isInBound = Standard_False;
638 Geom2dGcc_CurveToolGeo::D1(theC1, aU, aP1, aD1);
639 Geom2dGcc_CurveToolGeo::D1(theC2, aV, aP2, aD2);
640 Standard_Real aV1 = (aD2.X() == 0.0) ? aV :((theUfinal - aU)*aD1.X() + aV*aD2.X() + (aP1.X() - aP2.X()))/aD2.X();
641 Standard_Real aV2 = (aD2.Y() == 0.0) ? aV :((theUfinal - aU)*aD1.Y() + aV*aD2.Y() + (aP1.Y() - aP2.Y()))/aD2.Y();
655 aP1 = Geom2dGcc_CurveToolGeo::Value(theC1,theUfinal);
656 aP2 = Geom2dGcc_CurveToolGeo::Value(theC2,aV1);
658 Standard_Real aSQ1 = aP1.SquareDistance(aP2);
660 aP2 = Geom2dGcc_CurveToolGeo::Value(theC2,aV2);
661 Standard_Real aSQ2 = aP1.SquareDistance(aP2);
671 if(theVfinal < theVmin)
677 isInBound = Standard_False;
680 if(theVfinal > theVmax)
686 isInBound = Standard_False;
692 Geom2dGcc_CurveToolGeo::D1(theC1, aU, aP1, aD1);
693 Geom2dGcc_CurveToolGeo::D1(theC2, aV, aP2, aD2);
694 Standard_Real aU1 = (aD1.X() == 0.0) ? aU :((theVfinal - aV)*aD2.X() + aU*aD1.X() + (aP2.X() - aP1.X()))/aD1.X();
695 Standard_Real aU2 = (aD1.Y() == 0.0) ? aU :((theVfinal - aV)*aD2.Y() + aU*aD1.Y() + (aP2.Y() - aP1.Y()))/aD1.Y();
709 aP2 = Geom2dGcc_CurveToolGeo::Value(theC2,theVfinal);
710 aP1 = Geom2dGcc_CurveToolGeo::Value(theC1,aU1);
712 Standard_Real aSQ1 = aP1.SquareDistance(aP2);
714 aP1 = Geom2dGcc_CurveToolGeo::Value(theC1,aU2);
715 Standard_Real aSQ2 = aP1.SquareDistance(aP2);
723 // circulaire tant a deux courbes ,de rayon donne
724 //==================================================
726 //========================================================================
727 // On initialise WellDone a false. +
728 // On recupere les courbes Cu1 et Cu2. +
729 // On sort en erreur dans les cas ou la construction est impossible. +
730 // On fait la parallele a Cu1 dans le bon sens. +
731 // On fait la parallele a Cu2 dans le bon sens. +
732 // On intersecte les paralleles ==> point de centre de la solution. +
733 // On cree la solution qu on ajoute aux solutions deja trouvees. +
734 // On remplit les champs. +
735 //========================================================================
737 Geom2dGcc_Circ2d2TanRadGeo::
738 Geom2dGcc_Circ2d2TanRadGeo (const Geom2dGcc_QCurve& Qualified1,
739 const Geom2dGcc_QCurve& Qualified2,
740 const Standard_Real Radius ,
741 const Standard_Real Tolerance ):
743 //========================================================================
744 // initialisation des champs. +
745 //========================================================================
760 //========================================================================
762 //========================================================================
764 Standard_Real Tol = Abs(Tolerance);
765 Standard_Real thefirst = -100000.;
766 Standard_Real thelast = 100000.;
767 Standard_Real firstparam;
768 Standard_Real lastparam;
769 gp_Dir2d dirx(1.,0.);
770 TColStd_Array1OfReal cote1(1,2);
771 TColStd_Array1OfReal cote2(1,2);
772 Standard_Integer nbrcote1=0;
773 Standard_Integer nbrcote2=0;
774 WellDone = Standard_False;
776 if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() ||
777 Qualified1.IsOutside() || Qualified1.IsUnqualified()) ||
778 !(Qualified2.IsEnclosed() || Qualified2.IsEnclosing() ||
779 Qualified2.IsOutside() || Qualified2.IsUnqualified())) {
780 GccEnt_BadQualifier::Raise();
783 Geom2dAdaptor_Curve Cu1 = Qualified1.Qualified();
784 Geom2dAdaptor_Curve Cu2 = Qualified2.Qualified();
785 if (Radius < 0.0) { Standard_NegativeValue::Raise(); }
787 if (Qualified1.IsEnclosed() && Qualified2.IsEnclosed()) {
788 // =======================================================
794 else if(Qualified1.IsEnclosed() && Qualified2.IsOutside()) {
795 // ==========================================================
801 else if (Qualified1.IsOutside() && Qualified2.IsEnclosed()) {
802 // ===========================================================
808 else if(Qualified1.IsOutside() && Qualified2.IsOutside()) {
809 // =========================================================
815 if(Qualified1.IsEnclosed() && Qualified2.IsUnqualified()) {
816 // =========================================================
823 if(Qualified1.IsUnqualified() && Qualified2.IsEnclosed()) {
824 // =========================================================
831 else if(Qualified1.IsOutside() && Qualified2.IsUnqualified()) {
832 // =============================================================
839 if(Qualified1.IsUnqualified() && Qualified2.IsOutside()) {
840 // ========================================================
847 else if(Qualified1.IsUnqualified() && Qualified2.IsUnqualified()) {
848 // =================================================================
856 Geom2dInt_GInter Intp;
857 for (Standard_Integer jcote1 = 1 ; jcote1 <= nbrcote1 ; jcote1++) {
858 Handle(Geom2dAdaptor_HCurve) HCu1 = new Geom2dAdaptor_HCurve(Cu1);
859 Adaptor3d_OffsetCurve C1(HCu1,cote1(jcote1));
860 firstparam = Max(Geom2dGcc_CurveToolGeo::FirstParameter(C1),thefirst);
861 lastparam = Min(Geom2dGcc_CurveToolGeo::LastParameter(C1),thelast);
863 IntRes2d_Domain D2(Geom2dGcc_CurveToolGeo::Value(C1,firstparam),firstparam,Tol,
864 Geom2dGcc_CurveToolGeo::Value(C1,lastparam),lastparam,Tol);
866 Geom2dGcc_CurveToolGeo::Value(C1,firstparam);
867 Geom2dGcc_CurveToolGeo::Value(C1,lastparam);
869 for (Standard_Integer jcote2 = 1 ; jcote2 <= nbrcote2 ; jcote2++) {
870 Handle(Geom2dAdaptor_HCurve) HCu2 = new Geom2dAdaptor_HCurve(Cu2);
871 Adaptor3d_OffsetCurve C2(HCu2,cote2(jcote2));
872 firstparam = Max(Geom2dGcc_CurveToolGeo::FirstParameter(C2),thefirst);
873 lastparam = Min(Geom2dGcc_CurveToolGeo::LastParameter(C2),thelast);
875 IntRes2d_Domain D2(Geom2dGcc_CurveToolGeo::Value(C2,firstparam),firstparam,Tol,
876 Geom2dGcc_CurveToolGeo::Value(C2,lastparam),lastparam,Tol);
878 Geom2dGcc_CurveToolGeo::Value(C2,firstparam);
879 Geom2dGcc_CurveToolGeo::Value(C2,lastparam);
881 Intp.Perform(C1,C2,Tol,Tol);
883 if (!Intp.IsEmpty()) {
884 for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++)
886 Standard_Real aU0 = Intp.Point(i).ParamOnFirst();
887 Standard_Real aV0 = Intp.Point(i).ParamOnSecond();
889 Standard_Real aU1 = aU0-Precision::PApproximation();
890 Standard_Real aV1 = aV0-Precision::PApproximation();
892 Standard_Real aU2 = aU0+Precision::PApproximation();
893 Standard_Real aV2 = aV0+Precision::PApproximation();
895 gp_Pnt2d P11 = Geom2dGcc_CurveToolGeo::Value(C1,aU1);
896 gp_Pnt2d P12 = Geom2dGcc_CurveToolGeo::Value(C2,aV1);
897 gp_Pnt2d P21 = Geom2dGcc_CurveToolGeo::Value(C1,aU2);
898 gp_Pnt2d P22 = Geom2dGcc_CurveToolGeo::Value(C2,aV2);
900 Standard_Real aDist1112 = P11.Distance(P12);
901 Standard_Real aDist1122 = P11.Distance(P22);
903 Standard_Real aDist1221 = P12.Distance(P21);
904 Standard_Real aDist2122 = P21.Distance(P22);
906 if( Min(aDist1112, aDist1122) <= Precision::Approximation() &&
907 Min(aDist1221, aDist2122) <= Precision::Approximation())
909 PrecRoot(C1, C2, aU0, aV0,
910 Max(Geom2dGcc_CurveToolGeo::FirstParameter(C1), aU0 - 10.0),
911 Min(Geom2dGcc_CurveToolGeo::LastParameter(C1), aU0 + 10.0),
912 Max(Geom2dGcc_CurveToolGeo::FirstParameter(C2), aV0 - 10.0),
913 Min(Geom2dGcc_CurveToolGeo::LastParameter(C2), aV0 + 10.0),
918 gp_Pnt2d Center(Geom2dGcc_CurveToolGeo::Value(C1, aU0));
919 cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
920 // =======================================================
921 qualifier1(NbrSol) = Qualified1.Qualifier();
922 qualifier1(NbrSol) = Qualified1.Qualifier();
923 TheSame1(NbrSol) = 0;
924 TheSame2(NbrSol) = 0;
925 pararg1(NbrSol) = Intp.Point(i).ParamOnFirst();
926 pararg2(NbrSol) = Intp.Point(i).ParamOnSecond();
927 pnttg1sol(NbrSol) = Geom2dGcc_CurveTool::Value(Cu1,pararg1(NbrSol));
928 pnttg2sol(NbrSol) = Geom2dGcc_CurveTool::Value(Cu2,pararg2(NbrSol));
929 par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
931 par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
936 WellDone = Standard_True;
943 //=========================================================================
945 Standard_Boolean Geom2dGcc_Circ2d2TanRadGeo::
946 IsDone () const { return WellDone; }
948 Standard_Integer Geom2dGcc_Circ2d2TanRadGeo::
949 NbSolutions () const { return NbrSol; }
951 gp_Circ2d Geom2dGcc_Circ2d2TanRadGeo::
952 ThisSolution (const Standard_Integer Index) const
954 if (!WellDone) { StdFail_NotDone::Raise(); }
955 if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
956 return cirsol(Index);
959 void Geom2dGcc_Circ2d2TanRadGeo::
960 WhichQualifier(const Standard_Integer Index ,
961 GccEnt_Position& Qualif1 ,
962 GccEnt_Position& Qualif2 ) const
964 if (!WellDone) { StdFail_NotDone::Raise(); }
965 else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
967 Qualif1 = qualifier1(Index);
968 Qualif2 = qualifier2(Index);
972 void Geom2dGcc_Circ2d2TanRadGeo::
973 Tangency1 (const Standard_Integer Index,
974 Standard_Real& ParSol,
975 Standard_Real& ParArg,
976 gp_Pnt2d& PntSol) const{
977 if (!WellDone) { StdFail_NotDone::Raise(); }
978 else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
980 if (TheSame1(Index) == 0) {
981 ParSol = par1sol(Index);
982 ParArg = pararg1(Index);
983 PntSol = gp_Pnt2d(pnttg1sol(Index));
985 else { StdFail_NotDone::Raise(); }
989 void Geom2dGcc_Circ2d2TanRadGeo::
990 Tangency2 (const Standard_Integer Index,
991 Standard_Real& ParSol,
992 Standard_Real& ParArg,
993 gp_Pnt2d& PntSol) const{
994 if (!WellDone) { StdFail_NotDone::Raise(); }
995 else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
997 if (TheSame2(Index) == 0) {
998 ParSol = par2sol(Index);
999 ParArg = pararg2(Index);
1000 PntSol = gp_Pnt2d(pnttg2sol(Index));
1002 else { StdFail_NotDone::Raise(); }
1006 Standard_Boolean Geom2dGcc_Circ2d2TanRadGeo::
1007 IsTheSame1 (const Standard_Integer Index) const
1009 if (!WellDone) { StdFail_NotDone::Raise(); }
1010 if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
1012 if (TheSame1(Index) == 0) { return Standard_False; }
1013 return Standard_True;
1016 Standard_Boolean Geom2dGcc_Circ2d2TanRadGeo::
1017 IsTheSame2 (const Standard_Integer Index) const
1019 if (!WellDone) { StdFail_NotDone::Raise(); }
1020 if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
1022 if (TheSame2(Index) == 0) { return Standard_False; }
1023 return Standard_True;