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.
16 #include <gp_Ax2d.hxx>
17 #include <gp_Circ2d.hxx>
18 #include <gp_Lin2d.hxx>
19 #include <Standard_NegativeValue.hxx>
20 #include <Standard_OutOfRange.hxx>
21 #include <StdFail_NotDone.hxx>
22 #include <TColStd_Array1OfReal.hxx>
23 #include <GccEnt_BadQualifier.hxx>
24 #include <IntRes2d_Domain.hxx>
25 #include <IntRes2d_IntersectionPoint.hxx>
27 // circulaire tant a une courbe et une droite ,de rayon donne
28 //==============================================================
30 //========================================================================
31 // On initialise WellDone a false. +
32 // On recupere la courbe Cu2 et la droite L1. +
33 // On sort en erreur dans les cas ou la construction est impossible. +
34 // On fait la parallele a Cu2 dans le bon sens. +
35 // On fait la parallele a L1 dans le bon sens. +
36 // On intersecte les paralleles ==> point de centre de la solution. +
37 // On cree la solution qu on ajoute aux solutions deja trouvees. +
38 // On remplit les champs. +
39 //========================================================================
41 GccGeo_Circ2d2TanRad::
42 GccGeo_Circ2d2TanRad (const GccEnt_QualifiedLin& Qualified1,
43 const TheQCurve& Qualified2,
44 const Standard_Real Radius ,
45 const Standard_Real Tolerance ):
47 //========================================================================
48 // initialisation des champs. +
49 //========================================================================
64 //========================================================================
66 //========================================================================
68 Standard_Real Tol = Abs(Tolerance);
69 Standard_Real thefirst = -100000.;
70 Standard_Real thelast = 100000.;
71 Standard_Real firstparam;
72 Standard_Real lastparam;
74 TColStd_Array1OfReal cote1(1,2);
75 TColStd_Array1OfReal cote2(1,2);
76 Standard_Integer nbrcote1=0;
77 Standard_Integer nbrcote2=0;
78 WellDone = Standard_False;
80 if (!(Qualified1.IsEnclosed() ||
81 Qualified1.IsOutside() || Qualified1.IsUnqualified()) ||
82 !(Qualified2.IsEnclosed() || Qualified2.IsEnclosing() ||
83 Qualified2.IsOutside() || Qualified2.IsUnqualified())) {
85 GccEnt_BadQualifier::Raise();
88 gp_Lin2d L1 = Qualified1.Qualified();
89 Standard_Real x1dir = (L1.Direction()).X();
90 Standard_Real y1dir = (L1.Direction()).Y();
91 Standard_Real lxloc = (L1.Location()).X();
92 Standard_Real lyloc = (L1.Location()).Y();
93 gp_Pnt2d origin1(lxloc,lyloc);
94 gp_Dir2d normL1(-y1dir,x1dir);
95 TheCurve Cu2= Qualified2.Qualified();
96 if (Radius < 0.0) { Standard_NegativeValue::Raise(); }
98 if (Qualified1.IsEnclosed() && Qualified2.IsEnclosed()) {
99 // =======================================================
105 else if(Qualified1.IsEnclosed() && Qualified2.IsOutside()) {
106 // ==========================================================
112 else if (Qualified1.IsOutside() && Qualified2.IsEnclosed()) {
113 // ===========================================================
119 else if(Qualified1.IsOutside() && Qualified2.IsOutside()) {
120 // =========================================================
126 if(Qualified1.IsEnclosed() && Qualified2.IsUnqualified()) {
127 // =========================================================
134 if(Qualified1.IsUnqualified() && Qualified2.IsEnclosed()) {
135 // =========================================================
142 else if(Qualified1.IsOutside() && Qualified2.IsUnqualified()) {
143 // =============================================================
150 if(Qualified1.IsUnqualified() && Qualified2.IsOutside()) {
151 // ========================================================
158 else if(Qualified1.IsUnqualified() && Qualified2.IsUnqualified()) {
159 // =================================================================
167 gp_Dir2d Dir(-y1dir,x1dir);
168 for (Standard_Integer jcote1 = 1 ; jcote1 <= nbrcote1 ; jcote1++) {
169 gp_Pnt2d Point(L1.Location().XY()+cote1(jcote1)*Dir.XY());
170 gp_Lin2d Line(Point,L1.Direction()); // ligne avec deport.
172 for (Standard_Integer jcote2 = 1 ; jcote2 <= nbrcote2 ; jcote2++) {
173 Handle(TheHParGenCurve) HCu2 = new TheHParGenCurve(Cu2);
174 TheParGenCurve C2(HCu2,cote2(jcote2));
175 firstparam = Max(TheCurvePGTool::FirstParameter(C2),thefirst);
176 lastparam = Min(TheCurvePGTool::LastParameter(C2),thelast);
177 IntRes2d_Domain D2(TheCurvePGTool::Value(C2,firstparam),firstparam,Tol,
178 TheCurvePGTool::Value(C2,lastparam),lastparam,Tol);
179 TheIntConicCurve Intp(Line,D1,C2,D2,Tol,Tol);
181 if (!Intp.IsEmpty()) {
182 for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++) {
184 gp_Pnt2d Center(Intp.Point(i).Value());
185 cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
186 // =======================================================
187 gp_Dir2d dc1(origin1.XY()-Center.XY());
188 qualifier2(NbrSol) = Qualified2.Qualifier();
189 if (!Qualified1.IsUnqualified()) {
190 qualifier1(NbrSol) = Qualified1.Qualifier();
192 else if (dc1.Dot(normL1) > 0.0) {
193 qualifier1(NbrSol) = GccEnt_outside;
195 else { qualifier1(NbrSol) = GccEnt_enclosed; }
196 TheSame1(NbrSol) = 0;
197 TheSame2(NbrSol) = 0;
198 pararg1(NbrSol) = Intp.Point(i).ParamOnFirst();
199 pararg2(NbrSol) = Intp.Point(i).ParamOnSecond();
200 pnttg1sol(NbrSol) = ElCLib::Value(pararg1(NbrSol),L1);
201 pnttg2sol(NbrSol) = TheTool::Value(Cu2,pararg2(NbrSol));
202 par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
204 par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
208 WellDone = Standard_True;
215 // circulaire tant a une courbe et un cercle ,de rayon donne
216 //=============================================================
218 //========================================================================
219 // On initialise WellDone a false. +
220 // On recupere la courbe Cu2 et le cercle C1. +
221 // On sort en erreur dans les cas ou la construction est impossible. +
222 // On fait la parallele a Cu2 dans le bon sens. +
223 // On fait la parallele a C1 dans le bon sens. +
224 // On intersecte les paralleles ==> point de centre de la solution. +
225 // On cree la solution qu on ajoute aux solutions deja trouvees. +
226 // On remplit les champs. +
227 //========================================================================
229 GccGeo_Circ2d2TanRad::
230 GccGeo_Circ2d2TanRad (const GccEnt_QualifiedCirc& Qualified1,
231 const TheQCurve& Qualified2,
232 const Standard_Real Radius ,
233 const Standard_Real Tolerance ):
235 //========================================================================
236 // initialisation des champs. +
237 //========================================================================
252 //========================================================================
254 //========================================================================
256 Standard_Real Tol = Abs(Tolerance);
257 Standard_Real thefirst = -100000.;
258 Standard_Real thelast = 100000.;
259 Standard_Real firstparam;
260 Standard_Real lastparam;
261 gp_Dir2d dirx(1.,0.);
262 TColStd_Array1OfReal cote1(1,2);
263 TColStd_Array1OfReal cote2(1,2);
264 Standard_Integer nbrcote1=0;
265 Standard_Integer nbrcote2=0;
266 WellDone = Standard_False;
268 if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() ||
269 Qualified1.IsOutside() || Qualified1.IsUnqualified()) ||
270 !(Qualified2.IsEnclosed() || Qualified2.IsEnclosing() ||
271 Qualified2.IsOutside() || Qualified2.IsUnqualified())) {
272 GccEnt_BadQualifier::Raise();
275 gp_Circ2d C1 = Qualified1.Qualified();
276 gp_Pnt2d center1(C1.Location());
277 TheCurve Cu2 = Qualified2.Qualified();
278 if (Radius < 0.0) { Standard_NegativeValue::Raise(); }
280 if (Qualified1.IsEnclosed() && Qualified2.IsEnclosed()) {
281 // =======================================================
287 else if(Qualified1.IsEnclosed() && Qualified2.IsOutside()) {
288 // ==========================================================
294 else if (Qualified1.IsOutside() && Qualified2.IsEnclosed()) {
295 // ===========================================================
301 else if(Qualified1.IsOutside() && Qualified2.IsOutside()) {
302 // =========================================================
308 if(Qualified1.IsEnclosed() && Qualified2.IsUnqualified()) {
309 // =========================================================
316 if(Qualified1.IsUnqualified() && Qualified2.IsEnclosed()) {
317 // =========================================================
324 else if(Qualified1.IsOutside() && Qualified2.IsUnqualified()) {
325 // =============================================================
332 if(Qualified1.IsUnqualified() && Qualified2.IsOutside()) {
333 // ========================================================
340 else if(Qualified1.IsUnqualified() && Qualified2.IsUnqualified()) {
341 // =================================================================
349 Standard_Real R1 = C1.Radius();
350 TheIntConicCurve 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 for (Standard_Integer jcote2 = 1 ; jcote2 <= nbrcote2 ; jcote2++) {
357 Handle(TheHParGenCurve) HCu2 = new TheHParGenCurve(Cu2);
358 TheParGenCurve C2(HCu2,cote2(jcote2));
359 firstparam = Max(TheCurvePGTool::FirstParameter(C2),thefirst);
360 lastparam = Min(TheCurvePGTool::LastParameter(C2),thelast);
361 IntRes2d_Domain D2(TheCurvePGTool::Value(C2,firstparam),firstparam,Tol,
362 TheCurvePGTool::Value(C2,lastparam),lastparam,Tol);
363 Intp.Perform(Circ,D1,C2,D2,Tol,Tol);
365 if (!Intp.IsEmpty()) {
366 for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++) {
368 gp_Pnt2d Center(Intp.Point(i).Value());
369 cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
370 // =======================================================
372 gp_Dir2d dir1(Center.XY()-center1.XY());
377 Standard_Real distcc1 = Center.Distance(center1);
378 if (!Qualified1.IsUnqualified()) {
379 qualifier1(NbrSol) = Qualified1.Qualifier();
381 else if (Abs(distcc1+Radius-R1) < Tol) {
382 qualifier1(NbrSol) = GccEnt_enclosed;
384 else if (Abs(distcc1-R1-Radius) < Tol) {
385 qualifier1(NbrSol) = GccEnt_outside;
387 else { qualifier1(NbrSol) = GccEnt_enclosing; }
388 qualifier2(NbrSol) = Qualified2.Qualifier();
389 TheSame1(NbrSol) = 0;
390 TheSame2(NbrSol) = 0;
391 pararg1(NbrSol) = Intp.Point(i).ParamOnFirst();
392 pararg2(NbrSol) = Intp.Point(i).ParamOnSecond();
393 pnttg1sol(NbrSol) = ElCLib::Value(pararg1(NbrSol),C1);
394 pnttg2sol(NbrSol) = TheTool::Value(Cu2,pararg2(NbrSol));
395 par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
397 par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
401 WellDone = Standard_True;
408 // circulaire tant a une courbe et un point ,de rayon donne
409 //============================================================
411 //========================================================================
412 // On initialise WellDone a false. +
413 // On recupere la courbe Cu1 et le point P2. +
414 // On sort en erreur dans les cas ou la construction est impossible. +
415 // On fait la parallele a Cu1 dans le bon sens. +
416 // On fait la parallele a P2 dans le bon sens. +
417 // On intersecte les paralleles ==> point de centre de la solution. +
418 // On cree la solution qu on ajoute aux solutions deja trouvees. +
419 // On remplit les champs. +
420 //========================================================================
422 GccGeo_Circ2d2TanRad::
423 GccGeo_Circ2d2TanRad (const TheQCurve& Qualified1,
424 const gp_Pnt2d& Point2 ,
425 const Standard_Real Radius ,
426 const Standard_Real Tolerance ):
428 //========================================================================
429 // initialisation des champs. +
430 //========================================================================
445 //========================================================================
447 //========================================================================
449 Standard_Real Tol = Abs(Tolerance);
450 Standard_Real thefirst = -100000.;
451 Standard_Real thelast = 100000.;
452 Standard_Real firstparam;
453 Standard_Real lastparam;
454 gp_Dir2d dirx(1.,0.);
455 TColStd_Array1OfReal cote1(1,2);
456 Standard_Integer nbrcote1=0;
457 WellDone = Standard_False;
459 if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() ||
460 Qualified1.IsOutside() || Qualified1.IsUnqualified())) {
461 GccEnt_BadQualifier::Raise();
464 TheCurve Cu1 = Qualified1.Qualified();
465 if (Radius < 0.0) { Standard_NegativeValue::Raise(); }
467 if (Qualified1.IsEnclosed()) {
468 // ===========================
472 else if(Qualified1.IsOutside()) {
473 // ===============================
477 else if(Qualified1.IsUnqualified()) {
478 // ===================================
483 gp_Circ2d Circ(gp_Ax2d(Point2,gp_Dir2d(1.,0.)),Radius);
484 IntRes2d_Domain D1(ElCLib::Value(0.,Circ), 0.,Tol,
485 ElCLib::Value(M_PI+M_PI,Circ),M_PI+M_PI,Tol);
486 D1.SetEquivalentParameters(0.,M_PI+M_PI);
487 TheIntConicCurve Intp;
488 for (Standard_Integer jcote1 = 1 ; jcote1 <= nbrcote1 ; jcote1++) {
489 Handle(TheHParGenCurve) HCu1 = new TheHParGenCurve(Cu1);
490 TheParGenCurve Cu2(HCu1,cote1(jcote1));
491 firstparam = Max(TheCurvePGTool::FirstParameter(Cu2),thefirst);
492 lastparam = Min(TheCurvePGTool::LastParameter(Cu2),thelast);
493 IntRes2d_Domain D2(TheCurvePGTool::Value(Cu2,firstparam),firstparam,Tol,
494 TheCurvePGTool::Value(Cu2,lastparam),lastparam,Tol);
495 Intp.Perform(Circ,D1,Cu2,D2,Tol,Tol);
497 if (!Intp.IsEmpty()) {
498 for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++) {
500 gp_Pnt2d Center(Intp.Point(i).Value());
501 cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
502 // =======================================================
503 qualifier1(NbrSol) = Qualified1.Qualifier();
504 qualifier2(NbrSol) = GccEnt_noqualifier;
505 TheSame1(NbrSol) = 0;
506 TheSame2(NbrSol) = 0;
507 pararg1(NbrSol) = Intp.Point(i).ParamOnSecond();
508 pararg2(NbrSol) = 0.;
509 pnttg1sol(NbrSol) = TheTool::Value(Cu1,pararg1(NbrSol));
510 pnttg2sol(NbrSol) = Point2;
511 par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
513 par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
517 WellDone = Standard_True;
523 static void PrecRoot(const TheParGenCurve& theC1,
524 const TheParGenCurve& theC2,
525 const Standard_Real theU0,
526 const Standard_Real theV0,
527 const Standard_Real theUmin,
528 const Standard_Real theUmax,
529 const Standard_Real theVmin,
530 const Standard_Real theVmax,
531 Standard_Real& theUfinal,
532 Standard_Real& theVfinal)
534 const Standard_Real aInitStepU = (theUmax - theUmin)/2.0,
535 aInitStepV = (theVmax - theVmin)/2.0;
537 Standard_Real aStepU = aInitStepU, aStepV = aInitStepV;
539 const Standard_Real aTol = Precision::PConfusion() * Precision::PConfusion();
540 const Standard_Integer aNbIterMax = 100;
545 TheCurvePGTool::D1(theC1, theU0, aP1, aD1);
546 TheCurvePGTool::D1(theC2, theV0, aP2, aD2);
548 gp_Vec2d vP12(aP1.XY() - aP2.XY());
550 Standard_Real aU = theU0, aV = theV0;
554 Standard_Real aSQDistPrev = aP1.SquareDistance(aP2);
556 Standard_Integer aNbIter = 1;
560 Standard_Real aDetH = aD1.Y()*aD2.X() - aD1.X()*aD2.Y();
564 aU += aStepU*(aD2.Y() * vP12.X() - aD2.X()*vP12.Y())/aDetH;
565 aV += aStepV*(aD1.Y() * vP12.X() - aD1.X()*vP12.Y())/aDetH;
567 if(Abs(aU - theUmin) > 1000.0)
571 if(Abs(aU - theUmax) > 1000.0)
575 if(Abs(aV - theVmin) > 1000.0)
579 if(Abs(aV - theVmax) > 1000.0)
583 TheCurvePGTool::D1(theC1, aU, aP1, aD1);
584 TheCurvePGTool::D1(theC2, aV, aP2, aD2);
585 const Standard_Real aSQDist = aP1.SquareDistance(aP2);
587 if(Precision::IsInfinite(aSQDist))
591 vP12.SetXY(aP1.XY() - aP2.XY());
593 if(aSQDist < aSQDistPrev)
595 aSQDistPrev = aSQDist;
607 while((aNbIter++ < aNbIterMax) && ((aStepU > aTol) || (aStepV > aTol)));
609 Standard_Boolean isInBound = Standard_True;
610 if(theUfinal < theUmin)
616 isInBound = Standard_False;
619 if(theUfinal > theUmax)
625 isInBound = Standard_False;
630 TheCurvePGTool::D1(theC1, aU, aP1, aD1);
631 TheCurvePGTool::D1(theC2, aV, aP2, aD2);
632 Standard_Real aV1 = (aD2.X() == 0.0) ? aV :((theUfinal - aU)*aD1.X() + aV*aD2.X() + (aP1.X() - aP2.X()))/aD2.X();
633 Standard_Real aV2 = (aD2.Y() == 0.0) ? aV :((theUfinal - aU)*aD1.Y() + aV*aD2.Y() + (aP1.Y() - aP2.Y()))/aD2.Y();
647 aP1 = TheCurvePGTool::Value(theC1,theUfinal);
648 aP2 = TheCurvePGTool::Value(theC2,aV1);
650 Standard_Real aSQ1 = aP1.SquareDistance(aP2);
652 aP2 = TheCurvePGTool::Value(theC2,aV2);
653 Standard_Real aSQ2 = aP1.SquareDistance(aP2);
663 if(theVfinal < theVmin)
669 isInBound = Standard_False;
672 if(theVfinal > theVmax)
678 isInBound = Standard_False;
684 TheCurvePGTool::D1(theC1, aU, aP1, aD1);
685 TheCurvePGTool::D1(theC2, aV, aP2, aD2);
686 Standard_Real aU1 = (aD1.X() == 0.0) ? aU :((theVfinal - aV)*aD2.X() + aU*aD1.X() + (aP2.X() - aP1.X()))/aD1.X();
687 Standard_Real aU2 = (aD1.Y() == 0.0) ? aU :((theVfinal - aV)*aD2.Y() + aU*aD1.Y() + (aP2.Y() - aP1.Y()))/aD1.Y();
701 aP2 = TheCurvePGTool::Value(theC2,theVfinal);
702 aP1 = TheCurvePGTool::Value(theC1,aU1);
704 Standard_Real aSQ1 = aP1.SquareDistance(aP2);
706 aP1 = TheCurvePGTool::Value(theC1,aU2);
707 Standard_Real aSQ2 = aP1.SquareDistance(aP2);
715 // circulaire tant a deux courbes ,de rayon donne
716 //==================================================
718 //========================================================================
719 // On initialise WellDone a false. +
720 // On recupere les courbes Cu1 et Cu2. +
721 // On sort en erreur dans les cas ou la construction est impossible. +
722 // On fait la parallele a Cu1 dans le bon sens. +
723 // On fait la parallele a Cu2 dans le bon sens. +
724 // On intersecte les paralleles ==> point de centre de la solution. +
725 // On cree la solution qu on ajoute aux solutions deja trouvees. +
726 // On remplit les champs. +
727 //========================================================================
729 GccGeo_Circ2d2TanRad::
730 GccGeo_Circ2d2TanRad (const TheQCurve& Qualified1,
731 const TheQCurve& Qualified2,
732 const Standard_Real Radius ,
733 const Standard_Real Tolerance ):
735 //========================================================================
736 // initialisation des champs. +
737 //========================================================================
752 //========================================================================
754 //========================================================================
756 Standard_Real Tol = Abs(Tolerance);
757 Standard_Real thefirst = -100000.;
758 Standard_Real thelast = 100000.;
759 Standard_Real firstparam;
760 Standard_Real lastparam;
761 gp_Dir2d dirx(1.,0.);
762 TColStd_Array1OfReal cote1(1,2);
763 TColStd_Array1OfReal cote2(1,2);
764 Standard_Integer nbrcote1=0;
765 Standard_Integer nbrcote2=0;
766 WellDone = Standard_False;
768 if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() ||
769 Qualified1.IsOutside() || Qualified1.IsUnqualified()) ||
770 !(Qualified2.IsEnclosed() || Qualified2.IsEnclosing() ||
771 Qualified2.IsOutside() || Qualified2.IsUnqualified())) {
772 GccEnt_BadQualifier::Raise();
775 TheCurve Cu1 = Qualified1.Qualified();
776 TheCurve Cu2 = Qualified2.Qualified();
777 if (Radius < 0.0) { Standard_NegativeValue::Raise(); }
779 if (Qualified1.IsEnclosed() && Qualified2.IsEnclosed()) {
780 // =======================================================
786 else if(Qualified1.IsEnclosed() && Qualified2.IsOutside()) {
787 // ==========================================================
793 else if (Qualified1.IsOutside() && Qualified2.IsEnclosed()) {
794 // ===========================================================
800 else if(Qualified1.IsOutside() && Qualified2.IsOutside()) {
801 // =========================================================
807 if(Qualified1.IsEnclosed() && Qualified2.IsUnqualified()) {
808 // =========================================================
815 if(Qualified1.IsUnqualified() && Qualified2.IsEnclosed()) {
816 // =========================================================
823 else if(Qualified1.IsOutside() && Qualified2.IsUnqualified()) {
824 // =============================================================
831 if(Qualified1.IsUnqualified() && Qualified2.IsOutside()) {
832 // ========================================================
839 else if(Qualified1.IsUnqualified() && Qualified2.IsUnqualified()) {
840 // =================================================================
848 TheIntCurveCurve Intp;
849 for (Standard_Integer jcote1 = 1 ; jcote1 <= nbrcote1 ; jcote1++) {
850 Handle(TheHParGenCurve) HCu1 = new TheHParGenCurve(Cu1);
851 TheParGenCurve C1(HCu1,cote1(jcote1));
852 firstparam = Max(TheCurvePGTool::FirstParameter(C1),thefirst);
853 lastparam = Min(TheCurvePGTool::LastParameter(C1),thelast);
855 IntRes2d_Domain D2(TheCurvePGTool::Value(C1,firstparam),firstparam,Tol,
856 TheCurvePGTool::Value(C1,lastparam),lastparam,Tol);
858 TheCurvePGTool::Value(C1,firstparam);
859 TheCurvePGTool::Value(C1,lastparam);
861 for (Standard_Integer jcote2 = 1 ; jcote2 <= nbrcote2 ; jcote2++) {
862 Handle(TheHParGenCurve) HCu2 = new TheHParGenCurve(Cu2);
863 TheParGenCurve C2(HCu2,cote2(jcote2));
864 firstparam = Max(TheCurvePGTool::FirstParameter(C2),thefirst);
865 lastparam = Min(TheCurvePGTool::LastParameter(C2),thelast);
867 IntRes2d_Domain D2(TheCurvePGTool::Value(C2,firstparam),firstparam,Tol,
868 TheCurvePGTool::Value(C2,lastparam),lastparam,Tol);
870 TheCurvePGTool::Value(C2,firstparam);
871 TheCurvePGTool::Value(C2,lastparam);
873 Intp.Perform(C1,C2,Tol,Tol);
875 if (!Intp.IsEmpty()) {
876 for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++)
878 Standard_Real aU0 = Intp.Point(i).ParamOnFirst();
879 Standard_Real aV0 = Intp.Point(i).ParamOnSecond();
881 Standard_Real aU1 = aU0-Precision::PApproximation();
882 Standard_Real aV1 = aV0-Precision::PApproximation();
884 Standard_Real aU2 = aU0+Precision::PApproximation();
885 Standard_Real aV2 = aV0+Precision::PApproximation();
887 gp_Pnt2d P11 = TheCurvePGTool::Value(C1,aU1);
888 gp_Pnt2d P12 = TheCurvePGTool::Value(C2,aV1);
889 gp_Pnt2d P21 = TheCurvePGTool::Value(C1,aU2);
890 gp_Pnt2d P22 = TheCurvePGTool::Value(C2,aV2);
892 Standard_Real aDist1112 = P11.Distance(P12);
893 Standard_Real aDist1122 = P11.Distance(P22);
895 Standard_Real aDist1221 = P12.Distance(P21);
896 Standard_Real aDist2122 = P21.Distance(P22);
898 if( Min(aDist1112, aDist1122) <= Precision::Approximation() &&
899 Min(aDist1221, aDist2122) <= Precision::Approximation())
901 PrecRoot(C1, C2, aU0, aV0,
902 Max(TheCurvePGTool::FirstParameter(C1), aU0 - 10.0),
903 Min(TheCurvePGTool::LastParameter(C1), aU0 + 10.0),
904 Max(TheCurvePGTool::FirstParameter(C2), aV0 - 10.0),
905 Min(TheCurvePGTool::LastParameter(C2), aV0 + 10.0),
910 gp_Pnt2d Center(TheCurvePGTool::Value(C1, aU0));
911 cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
912 // =======================================================
913 qualifier1(NbrSol) = Qualified1.Qualifier();
914 qualifier1(NbrSol) = Qualified1.Qualifier();
915 TheSame1(NbrSol) = 0;
916 TheSame2(NbrSol) = 0;
917 pararg1(NbrSol) = Intp.Point(i).ParamOnFirst();
918 pararg2(NbrSol) = Intp.Point(i).ParamOnSecond();
919 pnttg1sol(NbrSol) = TheTool::Value(Cu1,pararg1(NbrSol));
920 pnttg2sol(NbrSol) = TheTool::Value(Cu2,pararg2(NbrSol));
921 par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
923 par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
928 WellDone = Standard_True;
935 //=========================================================================
937 Standard_Boolean GccGeo_Circ2d2TanRad::
938 IsDone () const { return WellDone; }
940 Standard_Integer GccGeo_Circ2d2TanRad::
941 NbSolutions () const { return NbrSol; }
943 gp_Circ2d GccGeo_Circ2d2TanRad::
944 ThisSolution (const Standard_Integer Index) const
946 if (!WellDone) { StdFail_NotDone::Raise(); }
947 if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
948 return cirsol(Index);
951 void GccGeo_Circ2d2TanRad::
952 WhichQualifier(const Standard_Integer Index ,
953 GccEnt_Position& Qualif1 ,
954 GccEnt_Position& Qualif2 ) const
956 if (!WellDone) { StdFail_NotDone::Raise(); }
957 else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
959 Qualif1 = qualifier1(Index);
960 Qualif2 = qualifier2(Index);
964 void GccGeo_Circ2d2TanRad::
965 Tangency1 (const Standard_Integer Index,
966 Standard_Real& ParSol,
967 Standard_Real& ParArg,
968 gp_Pnt2d& PntSol) const{
969 if (!WellDone) { StdFail_NotDone::Raise(); }
970 else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
972 if (TheSame1(Index) == 0) {
973 ParSol = par1sol(Index);
974 ParArg = pararg1(Index);
975 PntSol = gp_Pnt2d(pnttg1sol(Index));
977 else { StdFail_NotDone::Raise(); }
981 void GccGeo_Circ2d2TanRad::
982 Tangency2 (const Standard_Integer Index,
983 Standard_Real& ParSol,
984 Standard_Real& ParArg,
985 gp_Pnt2d& PntSol) const{
986 if (!WellDone) { StdFail_NotDone::Raise(); }
987 else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
989 if (TheSame2(Index) == 0) {
990 ParSol = par2sol(Index);
991 ParArg = pararg2(Index);
992 PntSol = gp_Pnt2d(pnttg2sol(Index));
994 else { StdFail_NotDone::Raise(); }
998 Standard_Boolean GccGeo_Circ2d2TanRad::
999 IsTheSame1 (const Standard_Integer Index) const
1001 if (!WellDone) { StdFail_NotDone::Raise(); }
1002 if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
1004 if (TheSame1(Index) == 0) { return Standard_False; }
1005 return Standard_True;
1008 Standard_Boolean GccGeo_Circ2d2TanRad::
1009 IsTheSame2 (const Standard_Integer Index) const
1011 if (!WellDone) { StdFail_NotDone::Raise(); }
1012 if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); }
1014 if (TheSame2(Index) == 0) { return Standard_False; }
1015 return Standard_True;