+ //========================================================================
+ // Traitement. +
+ //========================================================================
+
+ Standard_Real Tol = Abs(Tolerance);
+ Standard_Real thefirst = -100000.;
+ Standard_Real thelast = 100000.;
+ Standard_Real firstparam;
+ Standard_Real lastparam;
+ gp_Dir2d dirx(1.,0.);
+ TColStd_Array1OfReal cote1(1,2);
+ Standard_Integer nbrcote1=0;
+ WellDone = Standard_False;
+ NbrSol = 0;
+ if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() ||
+ Qualified1.IsOutside() || Qualified1.IsUnqualified())) {
+ GccEnt_BadQualifier::Raise();
+ return;
+ }
+ TheCurve Cu1 = Qualified1.Qualified();
+ if (Radius < 0.0) { Standard_NegativeValue::Raise(); }
+ else {
+ if (Qualified1.IsEnclosed()) {
+ // ===========================
+ nbrcote1 = 1;
+ cote1(1) = Radius;
+ }
+ else if(Qualified1.IsOutside()) {
+ // ===============================
+ nbrcote1 = 1;
+ cote1(1) = -Radius;
+ }
+ else if(Qualified1.IsUnqualified()) {
+ // ===================================
+ nbrcote1 = 2;
+ cote1(1) = Radius;
+ cote1(2) = -Radius;
+ }
+ gp_Circ2d Circ(gp_Ax2d(Point2,gp_Dir2d(1.,0.)),Radius);
+ IntRes2d_Domain D1(ElCLib::Value(0.,Circ), 0.,Tol,
+ ElCLib::Value(M_PI+M_PI,Circ),M_PI+M_PI,Tol);
+ D1.SetEquivalentParameters(0.,M_PI+M_PI);
+ TheIntConicCurve Intp;
+ for (Standard_Integer jcote1 = 1 ; jcote1 <= nbrcote1 ; jcote1++) {
+ Handle(TheHParGenCurve) HCu1 = new TheHParGenCurve(Cu1);
+ TheParGenCurve Cu2(HCu1,cote1(jcote1));
+ firstparam = Max(TheCurvePGTool::FirstParameter(Cu2),thefirst);
+ lastparam = Min(TheCurvePGTool::LastParameter(Cu2),thelast);
+ IntRes2d_Domain D2(TheCurvePGTool::Value(Cu2,firstparam),firstparam,Tol,
+ TheCurvePGTool::Value(Cu2,lastparam),lastparam,Tol);
+ Intp.Perform(Circ,D1,Cu2,D2,Tol,Tol);
+ if (Intp.IsDone()) {
+ if (!Intp.IsEmpty()) {
+ for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++) {
+ NbrSol++;
+ gp_Pnt2d Center(Intp.Point(i).Value());
+ cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius);
+ // =======================================================
+ qualifier1(NbrSol) = Qualified1.Qualifier();
+ qualifier2(NbrSol) = GccEnt_noqualifier;
+ TheSame1(NbrSol) = 0;
+ TheSame2(NbrSol) = 0;
+ pararg1(NbrSol) = Intp.Point(i).ParamOnSecond();
+ pararg2(NbrSol) = 0.;
+ pnttg1sol(NbrSol) = TheTool::Value(Cu1,pararg1(NbrSol));
+ pnttg2sol(NbrSol) = Point2;
+ par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
+ pnttg1sol(NbrSol));
+ par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol),
+ pnttg2sol(NbrSol));
+ }
+ }
+ WellDone = Standard_True;
+ }
+ }
+ }
+}
+
+static void PrecRoot(const TheParGenCurve& theC1,
+ const TheParGenCurve& theC2,
+ const Standard_Real theU0,
+ const Standard_Real theV0,
+ const Standard_Real theUmin,
+ const Standard_Real theUmax,
+ const Standard_Real theVmin,
+ const Standard_Real theVmax,
+ Standard_Real& theUfinal,
+ Standard_Real& theVfinal)
+{
+ const Standard_Real aInitStepU = (theUmax - theUmin)/2.0,
+ aInitStepV = (theVmax - theVmin)/2.0;
+
+ Standard_Real aStepU = aInitStepU, aStepV = aInitStepV;
+
+ const Standard_Real aTol = Precision::PConfusion() * Precision::PConfusion();
+ const Standard_Integer aNbIterMax = 100;
+
+ gp_Pnt2d aP1, aP2;
+ gp_Vec2d aD1, aD2;
+
+ TheCurvePGTool::D1(theC1, theU0, aP1, aD1);
+ TheCurvePGTool::D1(theC2, theV0, aP2, aD2);
+
+ gp_Vec2d vP12(aP1.XY() - aP2.XY());
+
+ Standard_Real aU = theU0, aV = theV0;
+ theUfinal = theU0;
+ theVfinal = theV0;
+
+ Standard_Real aSQDistPrev = aP1.SquareDistance(aP2);
+
+ Standard_Integer aNbIter = 1;
+
+ do
+ {
+ Standard_Real aDetH = aD1.Y()*aD2.X() - aD1.X()*aD2.Y();
+ if(aDetH == 0.0)
+ break;
+
+ aU += aStepU*(aD2.Y() * vP12.X() - aD2.X()*vP12.Y())/aDetH;
+ aV += aStepV*(aD1.Y() * vP12.X() - aD1.X()*vP12.Y())/aDetH;
+
+ if(Abs(aU - theUmin) > 1000.0)
+ //method diverges
+ return;
+
+ if(Abs(aU - theUmax) > 1000.0)
+ //method diverges
+ return;
+
+ if(Abs(aV - theVmin) > 1000.0)
+ //method diverges
+ return;
+
+ if(Abs(aV - theVmax) > 1000.0)
+ //method diverges
+ return;
+
+ TheCurvePGTool::D1(theC1, aU, aP1, aD1);
+ TheCurvePGTool::D1(theC2, aV, aP2, aD2);
+ const Standard_Real aSQDist = aP1.SquareDistance(aP2);
+
+ if(Precision::IsInfinite(aSQDist))
+ //method diverges
+ return;
+
+ vP12.SetXY(aP1.XY() - aP2.XY());
+
+ if(aSQDist < aSQDistPrev)
+ {
+ aSQDistPrev = aSQDist;
+ aStepU = aInitStepU;
+ aStepV = aInitStepV;
+ theUfinal = aU;
+ theVfinal = aV;
+ }
+ else
+ {
+ aStepU /= 2.0;
+ aStepV /= 2.0;
+ }
+ }
+ while((aNbIter++ < aNbIterMax) && ((aStepU > aTol) || (aStepV > aTol)));
+
+ Standard_Boolean isInBound = Standard_True;
+ if(theUfinal < theUmin)
+ {
+ aU = theUfinal;
+ aV = theVfinal;
+
+ theUfinal = theUmin;
+ isInBound = Standard_False;
+ }
+
+ if(theUfinal > theUmax)
+ {
+ aU = theUfinal;
+ aV = theVfinal;
+
+ theUfinal = theUmax;
+ isInBound = Standard_False;
+ }
+
+ if(!isInBound)
+ {
+ TheCurvePGTool::D1(theC1, aU, aP1, aD1);
+ TheCurvePGTool::D1(theC2, aV, aP2, aD2);
+ Standard_Real aV1 = (aD2.X() == 0.0) ? aV :((theUfinal - aU)*aD1.X() + aV*aD2.X() + (aP1.X() - aP2.X()))/aD2.X();
+ Standard_Real aV2 = (aD2.Y() == 0.0) ? aV :((theUfinal - aU)*aD1.Y() + aV*aD2.Y() + (aP1.Y() - aP2.Y()))/aD2.Y();
+
+ if(aV1 < theVmin)
+ aV1 = theVmin;
+
+ if(aV1 > theVmax)
+ aV1 = theVmax;
+
+ if(aV2 < theVmin)
+ aV2 = theVmin;