diff --git a/src/GccGeo/GccGeo_Circ2d2TanRad.gxx b/src/GccGeo/GccGeo_Circ2d2TanRad.gxx index b7ac235fe1..71ba7ddc71 100755 --- a/src/GccGeo/GccGeo_Circ2d2TanRad.gxx +++ b/src/GccGeo/GccGeo_Circ2d2TanRad.gxx @@ -44,178 +44,178 @@ //======================================================================== GccGeo_Circ2d2TanRad:: - GccGeo_Circ2d2TanRad (const GccEnt_QualifiedLin& Qualified1, - const TheQCurve& Qualified2, - const Standard_Real Radius , - const Standard_Real Tolerance ): +GccGeo_Circ2d2TanRad (const GccEnt_QualifiedLin& Qualified1, + const TheQCurve& Qualified2, + const Standard_Real Radius , + const Standard_Real Tolerance ): //======================================================================== // initialisation des champs. + //======================================================================== - cirsol(1,16) , - qualifier1(1,16), - qualifier2(1,16), - TheSame1(1,16) , - TheSame2(1,16) , - pnttg1sol(1,16), - pnttg2sol(1,16), - par1sol(1,16) , - par2sol(1,16) , - pararg1(1,16) , - pararg2(1,16) +cirsol(1,16) , +qualifier1(1,16), +qualifier2(1,16), +TheSame1(1,16) , +TheSame2(1,16) , +pnttg1sol(1,16), +pnttg2sol(1,16), +par1sol(1,16) , +par2sol(1,16) , +pararg1(1,16) , +pararg2(1,16) { -//======================================================================== -// Traitement. + -//======================================================================== + //======================================================================== + // 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); - TColStd_Array1OfReal cote2(1,2); - Standard_Integer nbrcote1=0; - Standard_Integer nbrcote2=0; - WellDone = Standard_False; - NbrSol = 0; - if (!(Qualified1.IsEnclosed() || - Qualified1.IsOutside() || Qualified1.IsUnqualified()) || - !(Qualified2.IsEnclosed() || Qualified2.IsEnclosing() || - Qualified2.IsOutside() || Qualified2.IsUnqualified())) { + 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); + TColStd_Array1OfReal cote2(1,2); + Standard_Integer nbrcote1=0; + Standard_Integer nbrcote2=0; + WellDone = Standard_False; + NbrSol = 0; + if (!(Qualified1.IsEnclosed() || + Qualified1.IsOutside() || Qualified1.IsUnqualified()) || + !(Qualified2.IsEnclosed() || Qualified2.IsEnclosing() || + Qualified2.IsOutside() || Qualified2.IsUnqualified())) { - GccEnt_BadQualifier::Raise(); - return; - } - gp_Lin2d L1 = Qualified1.Qualified(); - Standard_Real x1dir = (L1.Direction()).X(); - Standard_Real y1dir = (L1.Direction()).Y(); - Standard_Real lxloc = (L1.Location()).X(); - Standard_Real lyloc = (L1.Location()).Y(); - gp_Pnt2d origin1(lxloc,lyloc); - gp_Dir2d normL1(-y1dir,x1dir); - TheCurve Cu2= Qualified2.Qualified(); - if (Radius < 0.0) { Standard_NegativeValue::Raise(); } - else { - if (Qualified1.IsEnclosed() && Qualified2.IsEnclosed()) { -// ======================================================= - nbrcote1 = 1; - nbrcote2 = 1; - cote1(1) = Radius; - cote2(1) = Radius; - } - else if(Qualified1.IsEnclosed() && Qualified2.IsOutside()) { -// ========================================================== - nbrcote1 = 1; - nbrcote2 = 1; - cote1(1) = Radius; - cote2(1) = -Radius; - } - else if (Qualified1.IsOutside() && Qualified2.IsEnclosed()) { -// =========================================================== - nbrcote1 = 1; - nbrcote2 = 1; - cote1(1) = -Radius; - cote2(1) = Radius; - } - else if(Qualified1.IsOutside() && Qualified2.IsOutside()) { -// ========================================================= - nbrcote1 = 1; - nbrcote2 = 1; - cote1(1) = -Radius; - cote2(1) = -Radius; - } - if(Qualified1.IsEnclosed() && Qualified2.IsUnqualified()) { -// ========================================================= - nbrcote1 = 1; - nbrcote2 = 2; - cote1(1) = Radius; - cote2(1) = Radius; - cote2(2) = -Radius; - } - if(Qualified1.IsUnqualified() && Qualified2.IsEnclosed()) { -// ========================================================= - nbrcote1 = 2; - nbrcote2 = 1; - cote1(1) = Radius; - cote1(2) = -Radius; - cote2(1) = Radius; - } - else if(Qualified1.IsOutside() && Qualified2.IsUnqualified()) { -// ============================================================= - nbrcote1 = 1; - nbrcote2 = 2; - cote1(1) = -Radius; - cote2(1) = Radius; - cote2(2) = -Radius; - } - if(Qualified1.IsUnqualified() && Qualified2.IsOutside()) { -// ======================================================== - nbrcote1 = 2; - nbrcote2 = 1; - cote1(1) = Radius; - cote1(2) = -Radius; - cote2(1) = -Radius; - } - else if(Qualified1.IsUnqualified() && Qualified2.IsUnqualified()) { -// ================================================================= - nbrcote1 = 2; - nbrcote2 = 2; - cote1(1) = Radius; - cote1(2) = -Radius; - cote2(1) = Radius; - cote2(2) = -Radius; - } - gp_Dir2d Dir(-y1dir,x1dir); - for (Standard_Integer jcote1 = 1 ; jcote1 <= nbrcote1 ; jcote1++) { - gp_Pnt2d Point(L1.Location().XY()+cote1(jcote1)*Dir.XY()); - gp_Lin2d Line(Point,L1.Direction()); // ligne avec deport. - IntRes2d_Domain D1; - for (Standard_Integer jcote2 = 1 ; jcote2 <= nbrcote2 ; jcote2++) { - Handle(TheHParGenCurve) HCu2 = new TheHParGenCurve(Cu2); - TheParGenCurve C2(HCu2,cote2(jcote2)); - firstparam = Max(TheCurvePGTool::FirstParameter(C2),thefirst); - lastparam = Min(TheCurvePGTool::LastParameter(C2),thelast); - IntRes2d_Domain D2(TheCurvePGTool::Value(C2,firstparam),firstparam,Tol, - TheCurvePGTool::Value(C2,lastparam),lastparam,Tol); - TheIntConicCurve Intp(Line,D1,C2,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); -// ======================================================= - gp_Dir2d dc1(origin1.XY()-Center.XY()); - qualifier2(NbrSol) = Qualified2.Qualifier(); - if (!Qualified1.IsUnqualified()) { - qualifier1(NbrSol) = Qualified1.Qualifier(); - } - else if (dc1.Dot(normL1) > 0.0) { - qualifier1(NbrSol) = GccEnt_outside; - } - else { qualifier1(NbrSol) = GccEnt_enclosed; } - TheSame1(NbrSol) = 0; - TheSame2(NbrSol) = 0; - pararg1(NbrSol) = Intp.Point(i).ParamOnFirst(); - pararg2(NbrSol) = Intp.Point(i).ParamOnSecond(); - pnttg1sol(NbrSol) = ElCLib::Value(pararg1(NbrSol),L1); - pnttg2sol(NbrSol) = TheTool::Value(Cu2,pararg2(NbrSol)); - par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol), - pnttg1sol(NbrSol)); - par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol), - pnttg2sol(NbrSol)); - } - } - WellDone = Standard_True; - } - } - } - } - } + GccEnt_BadQualifier::Raise(); + return; + } + gp_Lin2d L1 = Qualified1.Qualified(); + Standard_Real x1dir = (L1.Direction()).X(); + Standard_Real y1dir = (L1.Direction()).Y(); + Standard_Real lxloc = (L1.Location()).X(); + Standard_Real lyloc = (L1.Location()).Y(); + gp_Pnt2d origin1(lxloc,lyloc); + gp_Dir2d normL1(-y1dir,x1dir); + TheCurve Cu2= Qualified2.Qualified(); + if (Radius < 0.0) { Standard_NegativeValue::Raise(); } + else { + if (Qualified1.IsEnclosed() && Qualified2.IsEnclosed()) { + // ======================================================= + nbrcote1 = 1; + nbrcote2 = 1; + cote1(1) = Radius; + cote2(1) = Radius; + } + else if(Qualified1.IsEnclosed() && Qualified2.IsOutside()) { + // ========================================================== + nbrcote1 = 1; + nbrcote2 = 1; + cote1(1) = Radius; + cote2(1) = -Radius; + } + else if (Qualified1.IsOutside() && Qualified2.IsEnclosed()) { + // =========================================================== + nbrcote1 = 1; + nbrcote2 = 1; + cote1(1) = -Radius; + cote2(1) = Radius; + } + else if(Qualified1.IsOutside() && Qualified2.IsOutside()) { + // ========================================================= + nbrcote1 = 1; + nbrcote2 = 1; + cote1(1) = -Radius; + cote2(1) = -Radius; + } + if(Qualified1.IsEnclosed() && Qualified2.IsUnqualified()) { + // ========================================================= + nbrcote1 = 1; + nbrcote2 = 2; + cote1(1) = Radius; + cote2(1) = Radius; + cote2(2) = -Radius; + } + if(Qualified1.IsUnqualified() && Qualified2.IsEnclosed()) { + // ========================================================= + nbrcote1 = 2; + nbrcote2 = 1; + cote1(1) = Radius; + cote1(2) = -Radius; + cote2(1) = Radius; + } + else if(Qualified1.IsOutside() && Qualified2.IsUnqualified()) { + // ============================================================= + nbrcote1 = 1; + nbrcote2 = 2; + cote1(1) = -Radius; + cote2(1) = Radius; + cote2(2) = -Radius; + } + if(Qualified1.IsUnqualified() && Qualified2.IsOutside()) { + // ======================================================== + nbrcote1 = 2; + nbrcote2 = 1; + cote1(1) = Radius; + cote1(2) = -Radius; + cote2(1) = -Radius; + } + else if(Qualified1.IsUnqualified() && Qualified2.IsUnqualified()) { + // ================================================================= + nbrcote1 = 2; + nbrcote2 = 2; + cote1(1) = Radius; + cote1(2) = -Radius; + cote2(1) = Radius; + cote2(2) = -Radius; + } + gp_Dir2d Dir(-y1dir,x1dir); + for (Standard_Integer jcote1 = 1 ; jcote1 <= nbrcote1 ; jcote1++) { + gp_Pnt2d Point(L1.Location().XY()+cote1(jcote1)*Dir.XY()); + gp_Lin2d Line(Point,L1.Direction()); // ligne avec deport. + IntRes2d_Domain D1; + for (Standard_Integer jcote2 = 1 ; jcote2 <= nbrcote2 ; jcote2++) { + Handle(TheHParGenCurve) HCu2 = new TheHParGenCurve(Cu2); + TheParGenCurve C2(HCu2,cote2(jcote2)); + firstparam = Max(TheCurvePGTool::FirstParameter(C2),thefirst); + lastparam = Min(TheCurvePGTool::LastParameter(C2),thelast); + IntRes2d_Domain D2(TheCurvePGTool::Value(C2,firstparam),firstparam,Tol, + TheCurvePGTool::Value(C2,lastparam),lastparam,Tol); + TheIntConicCurve Intp(Line,D1,C2,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); + // ======================================================= + gp_Dir2d dc1(origin1.XY()-Center.XY()); + qualifier2(NbrSol) = Qualified2.Qualifier(); + if (!Qualified1.IsUnqualified()) { + qualifier1(NbrSol) = Qualified1.Qualifier(); + } + else if (dc1.Dot(normL1) > 0.0) { + qualifier1(NbrSol) = GccEnt_outside; + } + else { qualifier1(NbrSol) = GccEnt_enclosed; } + TheSame1(NbrSol) = 0; + TheSame2(NbrSol) = 0; + pararg1(NbrSol) = Intp.Point(i).ParamOnFirst(); + pararg2(NbrSol) = Intp.Point(i).ParamOnSecond(); + pnttg1sol(NbrSol) = ElCLib::Value(pararg1(NbrSol),L1); + pnttg2sol(NbrSol) = TheTool::Value(Cu2,pararg2(NbrSol)); + par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol), + pnttg1sol(NbrSol)); + par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol), + pnttg2sol(NbrSol)); + } + } + WellDone = Standard_True; + } + } + } + } +} // circulaire tant a une courbe et un cercle ,de rayon donne //============================================================= @@ -232,183 +232,183 @@ GccGeo_Circ2d2TanRad:: //======================================================================== GccGeo_Circ2d2TanRad:: - GccGeo_Circ2d2TanRad (const GccEnt_QualifiedCirc& Qualified1, - const TheQCurve& Qualified2, - const Standard_Real Radius , - const Standard_Real Tolerance ): +GccGeo_Circ2d2TanRad (const GccEnt_QualifiedCirc& Qualified1, + const TheQCurve& Qualified2, + const Standard_Real Radius , + const Standard_Real Tolerance ): //======================================================================== // initialisation des champs. + //======================================================================== - cirsol(1,16) , - qualifier1(1,16), - qualifier2(1,16), - TheSame1(1,16) , - TheSame2(1,16) , - pnttg1sol(1,16), - pnttg2sol(1,16), - par1sol(1,16) , - par2sol(1,16) , - pararg1(1,16) , - pararg2(1,16) +cirsol(1,16) , +qualifier1(1,16), +qualifier2(1,16), +TheSame1(1,16) , +TheSame2(1,16) , +pnttg1sol(1,16), +pnttg2sol(1,16), +par1sol(1,16) , +par2sol(1,16) , +pararg1(1,16) , +pararg2(1,16) { -//======================================================================== -// Traitement. + -//======================================================================== + //======================================================================== + // 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); - TColStd_Array1OfReal cote2(1,2); - Standard_Integer nbrcote1=0; - Standard_Integer nbrcote2=0; - WellDone = Standard_False; - NbrSol = 0; - if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() || - Qualified1.IsOutside() || Qualified1.IsUnqualified()) || - !(Qualified2.IsEnclosed() || Qualified2.IsEnclosing() || - Qualified2.IsOutside() || Qualified2.IsUnqualified())) { - GccEnt_BadQualifier::Raise(); - return; - } - gp_Circ2d C1 = Qualified1.Qualified(); - gp_Pnt2d center1(C1.Location()); - TheCurve Cu2 = Qualified2.Qualified(); - if (Radius < 0.0) { Standard_NegativeValue::Raise(); } - else { - if (Qualified1.IsEnclosed() && Qualified2.IsEnclosed()) { -// ======================================================= - nbrcote1 = 1; - nbrcote2 = 1; - cote1(1) = Radius; - cote2(1) = Radius; - } - else if(Qualified1.IsEnclosed() && Qualified2.IsOutside()) { -// ========================================================== - nbrcote1 = 1; - nbrcote2 = 1; - cote1(1) = Radius; - cote2(1) = -Radius; - } - else if (Qualified1.IsOutside() && Qualified2.IsEnclosed()) { -// =========================================================== - nbrcote1 = 1; - nbrcote2 = 1; - cote1(1) = -Radius; - cote2(1) = Radius; - } - else if(Qualified1.IsOutside() && Qualified2.IsOutside()) { -// ========================================================= - nbrcote1 = 1; - nbrcote2 = 1; - cote1(1) = -Radius; - cote2(1) = -Radius; - } - if(Qualified1.IsEnclosed() && Qualified2.IsUnqualified()) { -// ========================================================= - nbrcote1 = 1; - nbrcote2 = 2; - cote1(1) = Radius; - cote2(1) = Radius; - cote2(2) = -Radius; - } - if(Qualified1.IsUnqualified() && Qualified2.IsEnclosed()) { -// ========================================================= - nbrcote1 = 2; - nbrcote2 = 1; - cote1(1) = Radius; - cote1(2) = -Radius; - cote2(1) = Radius; - } - else if(Qualified1.IsOutside() && Qualified2.IsUnqualified()) { -// ============================================================= - nbrcote1 = 1; - nbrcote2 = 2; - cote1(1) = -Radius; - cote2(1) = Radius; - cote2(2) = -Radius; - } - if(Qualified1.IsUnqualified() && Qualified2.IsOutside()) { -// ======================================================== - nbrcote1 = 2; - nbrcote2 = 1; - cote1(1) = Radius; - cote1(2) = -Radius; - cote2(1) = -Radius; - } - else if(Qualified1.IsUnqualified() && Qualified2.IsUnqualified()) { -// ================================================================= - nbrcote1 = 2; - nbrcote2 = 2; - cote1(1) = Radius; - cote1(2) = -Radius; - cote2(1) = Radius; - cote2(2) = -Radius; - } - Standard_Real R1 = C1.Radius(); - TheIntConicCurve Intp; - for (Standard_Integer jcote1 = 1 ; jcote1 <= nbrcote1 ; jcote1++) { - gp_Circ2d Circ(C1.XAxis(),R1+cote1(jcote1)); - IntRes2d_Domain D1(ElCLib::Value(0.,Circ), 0.,Tol, - ElCLib::Value(2.*M_PI,Circ),2.*M_PI,Tol); - D1.SetEquivalentParameters(0.,2.*M_PI); - for (Standard_Integer jcote2 = 1 ; jcote2 <= nbrcote2 ; jcote2++) { - Handle(TheHParGenCurve) HCu2 = new TheHParGenCurve(Cu2); - TheParGenCurve C2(HCu2,cote2(jcote2)); - firstparam = Max(TheCurvePGTool::FirstParameter(C2),thefirst); - lastparam = Min(TheCurvePGTool::LastParameter(C2),thelast); - IntRes2d_Domain D2(TheCurvePGTool::Value(C2,firstparam),firstparam,Tol, - TheCurvePGTool::Value(C2,lastparam),lastparam,Tol); - Intp.Perform(Circ,D1,C2,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); -// ======================================================= + 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); + TColStd_Array1OfReal cote2(1,2); + Standard_Integer nbrcote1=0; + Standard_Integer nbrcote2=0; + WellDone = Standard_False; + NbrSol = 0; + if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() || + Qualified1.IsOutside() || Qualified1.IsUnqualified()) || + !(Qualified2.IsEnclosed() || Qualified2.IsEnclosing() || + Qualified2.IsOutside() || Qualified2.IsUnqualified())) { + GccEnt_BadQualifier::Raise(); + return; + } + gp_Circ2d C1 = Qualified1.Qualified(); + gp_Pnt2d center1(C1.Location()); + TheCurve Cu2 = Qualified2.Qualified(); + if (Radius < 0.0) { Standard_NegativeValue::Raise(); } + else { + if (Qualified1.IsEnclosed() && Qualified2.IsEnclosed()) { + // ======================================================= + nbrcote1 = 1; + nbrcote2 = 1; + cote1(1) = Radius; + cote2(1) = Radius; + } + else if(Qualified1.IsEnclosed() && Qualified2.IsOutside()) { + // ========================================================== + nbrcote1 = 1; + nbrcote2 = 1; + cote1(1) = Radius; + cote2(1) = -Radius; + } + else if (Qualified1.IsOutside() && Qualified2.IsEnclosed()) { + // =========================================================== + nbrcote1 = 1; + nbrcote2 = 1; + cote1(1) = -Radius; + cote2(1) = Radius; + } + else if(Qualified1.IsOutside() && Qualified2.IsOutside()) { + // ========================================================= + nbrcote1 = 1; + nbrcote2 = 1; + cote1(1) = -Radius; + cote2(1) = -Radius; + } + if(Qualified1.IsEnclosed() && Qualified2.IsUnqualified()) { + // ========================================================= + nbrcote1 = 1; + nbrcote2 = 2; + cote1(1) = Radius; + cote2(1) = Radius; + cote2(2) = -Radius; + } + if(Qualified1.IsUnqualified() && Qualified2.IsEnclosed()) { + // ========================================================= + nbrcote1 = 2; + nbrcote2 = 1; + cote1(1) = Radius; + cote1(2) = -Radius; + cote2(1) = Radius; + } + else if(Qualified1.IsOutside() && Qualified2.IsUnqualified()) { + // ============================================================= + nbrcote1 = 1; + nbrcote2 = 2; + cote1(1) = -Radius; + cote2(1) = Radius; + cote2(2) = -Radius; + } + if(Qualified1.IsUnqualified() && Qualified2.IsOutside()) { + // ======================================================== + nbrcote1 = 2; + nbrcote2 = 1; + cote1(1) = Radius; + cote1(2) = -Radius; + cote2(1) = -Radius; + } + else if(Qualified1.IsUnqualified() && Qualified2.IsUnqualified()) { + // ================================================================= + nbrcote1 = 2; + nbrcote2 = 2; + cote1(1) = Radius; + cote1(2) = -Radius; + cote2(1) = Radius; + cote2(2) = -Radius; + } + Standard_Real R1 = C1.Radius(); + TheIntConicCurve Intp; + for (Standard_Integer jcote1 = 1 ; jcote1 <= nbrcote1 ; jcote1++) { + gp_Circ2d Circ(C1.XAxis(),R1+cote1(jcote1)); + IntRes2d_Domain D1(ElCLib::Value(0.,Circ), 0.,Tol, + ElCLib::Value(2.*M_PI,Circ),2.*M_PI,Tol); + D1.SetEquivalentParameters(0.,2.*M_PI); + for (Standard_Integer jcote2 = 1 ; jcote2 <= nbrcote2 ; jcote2++) { + Handle(TheHParGenCurve) HCu2 = new TheHParGenCurve(Cu2); + TheParGenCurve C2(HCu2,cote2(jcote2)); + firstparam = Max(TheCurvePGTool::FirstParameter(C2),thefirst); + lastparam = Min(TheCurvePGTool::LastParameter(C2),thelast); + IntRes2d_Domain D2(TheCurvePGTool::Value(C2,firstparam),firstparam,Tol, + TheCurvePGTool::Value(C2,lastparam),lastparam,Tol); + Intp.Perform(Circ,D1,C2,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); + // ======================================================= #ifdef DEB - gp_Dir2d dir1(Center.XY()-center1.XY()); + gp_Dir2d dir1(Center.XY()-center1.XY()); #else - Center.XY() ; - center1.XY() ; + Center.XY() ; + center1.XY() ; #endif - Standard_Real distcc1 = Center.Distance(center1); - if (!Qualified1.IsUnqualified()) { - qualifier1(NbrSol) = Qualified1.Qualifier(); - } - else if (Abs(distcc1+Radius-R1) < Tol) { - qualifier1(NbrSol) = GccEnt_enclosed; - } - else if (Abs(distcc1-R1-Radius) < Tol) { - qualifier1(NbrSol) = GccEnt_outside; - } - else { qualifier1(NbrSol) = GccEnt_enclosing; } - qualifier2(NbrSol) = Qualified2.Qualifier(); - TheSame1(NbrSol) = 0; - TheSame2(NbrSol) = 0; - pararg1(NbrSol) = Intp.Point(i).ParamOnFirst(); - pararg2(NbrSol) = Intp.Point(i).ParamOnSecond(); - pnttg1sol(NbrSol) = ElCLib::Value(pararg1(NbrSol),C1); - pnttg2sol(NbrSol) = TheTool::Value(Cu2,pararg2(NbrSol)); - par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol), - pnttg1sol(NbrSol)); - par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol), - pnttg2sol(NbrSol)); - } - } - WellDone = Standard_True; - } - } - } - } - } + Standard_Real distcc1 = Center.Distance(center1); + if (!Qualified1.IsUnqualified()) { + qualifier1(NbrSol) = Qualified1.Qualifier(); + } + else if (Abs(distcc1+Radius-R1) < Tol) { + qualifier1(NbrSol) = GccEnt_enclosed; + } + else if (Abs(distcc1-R1-Radius) < Tol) { + qualifier1(NbrSol) = GccEnt_outside; + } + else { qualifier1(NbrSol) = GccEnt_enclosing; } + qualifier2(NbrSol) = Qualified2.Qualifier(); + TheSame1(NbrSol) = 0; + TheSame2(NbrSol) = 0; + pararg1(NbrSol) = Intp.Point(i).ParamOnFirst(); + pararg2(NbrSol) = Intp.Point(i).ParamOnSecond(); + pnttg1sol(NbrSol) = ElCLib::Value(pararg1(NbrSol),C1); + pnttg2sol(NbrSol) = TheTool::Value(Cu2,pararg2(NbrSol)); + par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol), + pnttg1sol(NbrSol)); + par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol), + pnttg2sol(NbrSol)); + } + } + WellDone = Standard_True; + } + } + } + } +} // circulaire tant a une courbe et un point ,de rayon donne //============================================================ @@ -425,105 +425,297 @@ GccGeo_Circ2d2TanRad:: //======================================================================== GccGeo_Circ2d2TanRad:: - GccGeo_Circ2d2TanRad (const TheQCurve& Qualified1, - const gp_Pnt2d& Point2 , - const Standard_Real Radius , - const Standard_Real Tolerance ): +GccGeo_Circ2d2TanRad (const TheQCurve& Qualified1, + const gp_Pnt2d& Point2 , + const Standard_Real Radius , + const Standard_Real Tolerance ): //======================================================================== // initialisation des champs. + //======================================================================== - cirsol(1,16) , - qualifier1(1,16), - qualifier2(1,16), - TheSame1(1,16) , - TheSame2(1,16) , - pnttg1sol(1,16), - pnttg2sol(1,16), - par1sol(1,16) , - par2sol(1,16) , - pararg1(1,16) , - pararg2(1,16) +cirsol(1,16) , +qualifier1(1,16), +qualifier2(1,16), +TheSame1(1,16) , +TheSame2(1,16) , +pnttg1sol(1,16), +pnttg2sol(1,16), +par1sol(1,16) , +par2sol(1,16) , +pararg1(1,16) , +pararg2(1,16) { -//======================================================================== -// Traitement. + -//======================================================================== + //======================================================================== + // 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; - } - } - } - } + 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; + + if(aV2 > theVmax) + aV2 = theVmax; + + aP1 = TheCurvePGTool::Value(theC1,theUfinal); + aP2 = TheCurvePGTool::Value(theC2,aV1); + + Standard_Real aSQ1 = aP1.SquareDistance(aP2); + + aP2 = TheCurvePGTool::Value(theC2,aV2); + Standard_Real aSQ2 = aP1.SquareDistance(aP2); + + if(aSQ1 < aSQ2) + theVfinal = aV1; + else + theVfinal = aV2; + + return; + } + + if(theVfinal < theVmin) + { + aU = theUfinal; + aV = theVfinal; + + theVfinal = theVmin; + isInBound = Standard_False; + } + + if(theVfinal > theVmax) + { + aU = theUfinal; + aV = theVfinal; + + theVfinal = theVmax; + isInBound = Standard_False; + } + + if(isInBound) + return; + + TheCurvePGTool::D1(theC1, aU, aP1, aD1); + TheCurvePGTool::D1(theC2, aV, aP2, aD2); + Standard_Real aU1 = (aD1.X() == 0.0) ? aU :((theVfinal - aV)*aD2.X() + aU*aD1.X() + (aP2.X() - aP1.X()))/aD1.X(); + Standard_Real aU2 = (aD1.Y() == 0.0) ? aU :((theVfinal - aV)*aD2.Y() + aU*aD1.Y() + (aP2.Y() - aP1.Y()))/aD1.Y(); + + if(aU1 < theUmin) + aU1 = theUmin; + + if(aU1 > theUmax) + aU1 = theUmax; + + if(aU2 < theUmin) + aU2 = theUmin; + + if(aU2 > theUmax) + aU2 = theUmax; + + aP2 = TheCurvePGTool::Value(theC2,theVfinal); + aP1 = TheCurvePGTool::Value(theC1,aU1); + + Standard_Real aSQ1 = aP1.SquareDistance(aP2); + + aP1 = TheCurvePGTool::Value(theC1,aU2); + Standard_Real aSQ2 = aP1.SquareDistance(aP2); + + if(aSQ1 < aSQ2) + theUfinal = aU1; + else + theUfinal = aU2; +} // circulaire tant a deux courbes ,de rayon donne //================================================== @@ -540,188 +732,221 @@ GccGeo_Circ2d2TanRad:: //======================================================================== GccGeo_Circ2d2TanRad:: - GccGeo_Circ2d2TanRad (const TheQCurve& Qualified1, - const TheQCurve& Qualified2, - const Standard_Real Radius , - const Standard_Real Tolerance ): +GccGeo_Circ2d2TanRad (const TheQCurve& Qualified1, + const TheQCurve& Qualified2, + const Standard_Real Radius , + const Standard_Real Tolerance ): //======================================================================== // initialisation des champs. + //======================================================================== - cirsol(1,16) , - qualifier1(1,16), - qualifier2(1,16), - TheSame1(1,16) , - TheSame2(1,16) , - pnttg1sol(1,16), - pnttg2sol(1,16), - par1sol(1,16) , - par2sol(1,16) , - pararg1(1,16) , - pararg2(1,16) +cirsol(1,16) , +qualifier1(1,16), +qualifier2(1,16), +TheSame1(1,16) , +TheSame2(1,16) , +pnttg1sol(1,16), +pnttg2sol(1,16), +par1sol(1,16) , +par2sol(1,16) , +pararg1(1,16) , +pararg2(1,16) { -//======================================================================== -// Traitement. + -//======================================================================== + //======================================================================== + // 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); - TColStd_Array1OfReal cote2(1,2); - Standard_Integer nbrcote1=0; - Standard_Integer nbrcote2=0; - WellDone = Standard_False; - NbrSol = 0; - if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() || - Qualified1.IsOutside() || Qualified1.IsUnqualified()) || - !(Qualified2.IsEnclosed() || Qualified2.IsEnclosing() || - Qualified2.IsOutside() || Qualified2.IsUnqualified())) { - GccEnt_BadQualifier::Raise(); - return; - } - TheCurve Cu1 = Qualified1.Qualified(); - TheCurve Cu2 = Qualified2.Qualified(); - if (Radius < 0.0) { Standard_NegativeValue::Raise(); } - else { - if (Qualified1.IsEnclosed() && Qualified2.IsEnclosed()) { -// ======================================================= - nbrcote1 = 1; - nbrcote2 = 1; - cote1(1) = Radius; - cote2(1) = Radius; - } - else if(Qualified1.IsEnclosed() && Qualified2.IsOutside()) { -// ========================================================== - nbrcote1 = 1; - nbrcote2 = 1; - cote1(1) = Radius; - cote2(1) = -Radius; - } - else if (Qualified1.IsOutside() && Qualified2.IsEnclosed()) { -// =========================================================== - nbrcote1 = 1; - nbrcote2 = 1; - cote1(1) = -Radius; - cote2(1) = Radius; - } - else if(Qualified1.IsOutside() && Qualified2.IsOutside()) { -// ========================================================= - nbrcote1 = 1; - nbrcote2 = 1; - cote1(1) = -Radius; - cote2(1) = -Radius; - } - if(Qualified1.IsEnclosed() && Qualified2.IsUnqualified()) { -// ========================================================= - nbrcote1 = 1; - nbrcote2 = 2; - cote1(1) = Radius; - cote2(1) = Radius; - cote2(2) = -Radius; - } - if(Qualified1.IsUnqualified() && Qualified2.IsEnclosed()) { -// ========================================================= - nbrcote1 = 2; - nbrcote2 = 1; - cote1(1) = Radius; - cote1(2) = -Radius; - cote2(1) = Radius; - } - else if(Qualified1.IsOutside() && Qualified2.IsUnqualified()) { -// ============================================================= - nbrcote1 = 1; - nbrcote2 = 2; - cote1(1) = -Radius; - cote2(1) = Radius; - cote2(2) = -Radius; - } - if(Qualified1.IsUnqualified() && Qualified2.IsOutside()) { -// ======================================================== - nbrcote1 = 2; - nbrcote2 = 1; - cote1(1) = Radius; - cote1(2) = -Radius; - cote2(1) = -Radius; - } - else if(Qualified1.IsUnqualified() && Qualified2.IsUnqualified()) { -// ================================================================= - nbrcote1 = 2; - nbrcote2 = 2; - cote1(1) = Radius; - cote1(2) = -Radius; - cote2(1) = Radius; - cote2(2) = -Radius; - } - TheIntCurveCurve Intp; - for (Standard_Integer jcote1 = 1 ; jcote1 <= nbrcote1 ; jcote1++) { - Handle(TheHParGenCurve) HCu1 = new TheHParGenCurve(Cu1); - TheParGenCurve C1(HCu1,cote1(jcote1)); - firstparam = Max(TheCurvePGTool::FirstParameter(C1),thefirst); - lastparam = Min(TheCurvePGTool::LastParameter(C1),thelast); + 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); + TColStd_Array1OfReal cote2(1,2); + Standard_Integer nbrcote1=0; + Standard_Integer nbrcote2=0; + WellDone = Standard_False; + NbrSol = 0; + if (!(Qualified1.IsEnclosed() || Qualified1.IsEnclosing() || + Qualified1.IsOutside() || Qualified1.IsUnqualified()) || + !(Qualified2.IsEnclosed() || Qualified2.IsEnclosing() || + Qualified2.IsOutside() || Qualified2.IsUnqualified())) { + GccEnt_BadQualifier::Raise(); + return; + } + TheCurve Cu1 = Qualified1.Qualified(); + TheCurve Cu2 = Qualified2.Qualified(); + if (Radius < 0.0) { Standard_NegativeValue::Raise(); } + else { + if (Qualified1.IsEnclosed() && Qualified2.IsEnclosed()) { + // ======================================================= + nbrcote1 = 1; + nbrcote2 = 1; + cote1(1) = Radius; + cote2(1) = Radius; + } + else if(Qualified1.IsEnclosed() && Qualified2.IsOutside()) { + // ========================================================== + nbrcote1 = 1; + nbrcote2 = 1; + cote1(1) = Radius; + cote2(1) = -Radius; + } + else if (Qualified1.IsOutside() && Qualified2.IsEnclosed()) { + // =========================================================== + nbrcote1 = 1; + nbrcote2 = 1; + cote1(1) = -Radius; + cote2(1) = Radius; + } + else if(Qualified1.IsOutside() && Qualified2.IsOutside()) { + // ========================================================= + nbrcote1 = 1; + nbrcote2 = 1; + cote1(1) = -Radius; + cote2(1) = -Radius; + } + if(Qualified1.IsEnclosed() && Qualified2.IsUnqualified()) { + // ========================================================= + nbrcote1 = 1; + nbrcote2 = 2; + cote1(1) = Radius; + cote2(1) = Radius; + cote2(2) = -Radius; + } + if(Qualified1.IsUnqualified() && Qualified2.IsEnclosed()) { + // ========================================================= + nbrcote1 = 2; + nbrcote2 = 1; + cote1(1) = Radius; + cote1(2) = -Radius; + cote2(1) = Radius; + } + else if(Qualified1.IsOutside() && Qualified2.IsUnqualified()) { + // ============================================================= + nbrcote1 = 1; + nbrcote2 = 2; + cote1(1) = -Radius; + cote2(1) = Radius; + cote2(2) = -Radius; + } + if(Qualified1.IsUnqualified() && Qualified2.IsOutside()) { + // ======================================================== + nbrcote1 = 2; + nbrcote2 = 1; + cote1(1) = Radius; + cote1(2) = -Radius; + cote2(1) = -Radius; + } + else if(Qualified1.IsUnqualified() && Qualified2.IsUnqualified()) { + // ================================================================= + nbrcote1 = 2; + nbrcote2 = 2; + cote1(1) = Radius; + cote1(2) = -Radius; + cote2(1) = Radius; + cote2(2) = -Radius; + } + TheIntCurveCurve Intp; + for (Standard_Integer jcote1 = 1 ; jcote1 <= nbrcote1 ; jcote1++) { + Handle(TheHParGenCurve) HCu1 = new TheHParGenCurve(Cu1); + TheParGenCurve C1(HCu1,cote1(jcote1)); + firstparam = Max(TheCurvePGTool::FirstParameter(C1),thefirst); + lastparam = Min(TheCurvePGTool::LastParameter(C1),thelast); #ifdef DEB - IntRes2d_Domain D2(TheCurvePGTool::Value(C1,firstparam),firstparam,Tol, - TheCurvePGTool::Value(C1,lastparam),lastparam,Tol); + IntRes2d_Domain D2(TheCurvePGTool::Value(C1,firstparam),firstparam,Tol, + TheCurvePGTool::Value(C1,lastparam),lastparam,Tol); #else - TheCurvePGTool::Value(C1,firstparam); - TheCurvePGTool::Value(C1,lastparam); + TheCurvePGTool::Value(C1,firstparam); + TheCurvePGTool::Value(C1,lastparam); #endif - for (Standard_Integer jcote2 = 1 ; jcote2 <= nbrcote2 ; jcote2++) { - Handle(TheHParGenCurve) HCu2 = new TheHParGenCurve(Cu2); - TheParGenCurve C2(HCu2,cote2(jcote2)); - firstparam = Max(TheCurvePGTool::FirstParameter(C2),thefirst); - lastparam = Min(TheCurvePGTool::LastParameter(C2),thelast); + for (Standard_Integer jcote2 = 1 ; jcote2 <= nbrcote2 ; jcote2++) { + Handle(TheHParGenCurve) HCu2 = new TheHParGenCurve(Cu2); + TheParGenCurve C2(HCu2,cote2(jcote2)); + firstparam = Max(TheCurvePGTool::FirstParameter(C2),thefirst); + lastparam = Min(TheCurvePGTool::LastParameter(C2),thelast); #ifdef DEB - IntRes2d_Domain D2(TheCurvePGTool::Value(C2,firstparam),firstparam,Tol, - TheCurvePGTool::Value(C2,lastparam),lastparam,Tol); + IntRes2d_Domain D2(TheCurvePGTool::Value(C2,firstparam),firstparam,Tol, + TheCurvePGTool::Value(C2,lastparam),lastparam,Tol); #else - TheCurvePGTool::Value(C2,firstparam); - TheCurvePGTool::Value(C2,lastparam); + TheCurvePGTool::Value(C2,firstparam); + TheCurvePGTool::Value(C2,lastparam); #endif - Intp.Perform(C1,C2,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(); - qualifier1(NbrSol) = Qualified1.Qualifier(); - TheSame1(NbrSol) = 0; - TheSame2(NbrSol) = 0; - pararg1(NbrSol) = Intp.Point(i).ParamOnFirst(); - pararg2(NbrSol) = Intp.Point(i).ParamOnSecond(); - pnttg1sol(NbrSol) = TheTool::Value(Cu1,pararg1(NbrSol)); - pnttg2sol(NbrSol) = TheTool::Value(Cu2,pararg2(NbrSol)); - par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol), - pnttg1sol(NbrSol)); - par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol), - pnttg2sol(NbrSol)); - } - } - WellDone = Standard_True; - } - } - } - } - } + Intp.Perform(C1,C2,Tol,Tol); + if (Intp.IsDone()) { + if (!Intp.IsEmpty()) { + for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++) + { + Standard_Real aU0 = Intp.Point(i).ParamOnFirst(); + Standard_Real aV0 = Intp.Point(i).ParamOnSecond(); + + Standard_Real aU1 = aU0-Precision::PApproximation(); + Standard_Real aV1 = aV0-Precision::PApproximation(); + + Standard_Real aU2 = aU0+Precision::PApproximation(); + Standard_Real aV2 = aV0+Precision::PApproximation(); + + gp_Pnt2d P11 = TheCurvePGTool::Value(C1,aU1); + gp_Pnt2d P12 = TheCurvePGTool::Value(C2,aV1); + gp_Pnt2d P21 = TheCurvePGTool::Value(C1,aU2); + gp_Pnt2d P22 = TheCurvePGTool::Value(C2,aV2); + + Standard_Real aDist1112 = P11.Distance(P12); + Standard_Real aDist1122 = P11.Distance(P22); + + Standard_Real aDist1221 = P12.Distance(P21); + Standard_Real aDist2122 = P21.Distance(P22); + + if( Min(aDist1112, aDist1122) <= Precision::Approximation() && + Min(aDist1221, aDist2122) <= Precision::Approximation()) + { + PrecRoot(C1, C2, aU0, aV0, + Max(TheCurvePGTool::FirstParameter(C1), aU0 - 10.0), + Min(TheCurvePGTool::LastParameter(C1), aU0 + 10.0), + Max(TheCurvePGTool::FirstParameter(C2), aV0 - 10.0), + Min(TheCurvePGTool::LastParameter(C2), aV0 + 10.0), + aU0, aV0); + } + + NbrSol++; + gp_Pnt2d Center(TheCurvePGTool::Value(C1, aU0)); + cirsol(NbrSol) = gp_Circ2d(gp_Ax2d(Center,dirx),Radius); + // ======================================================= + qualifier1(NbrSol) = Qualified1.Qualifier(); + qualifier1(NbrSol) = Qualified1.Qualifier(); + TheSame1(NbrSol) = 0; + TheSame2(NbrSol) = 0; + pararg1(NbrSol) = Intp.Point(i).ParamOnFirst(); + pararg2(NbrSol) = Intp.Point(i).ParamOnSecond(); + pnttg1sol(NbrSol) = TheTool::Value(Cu1,pararg1(NbrSol)); + pnttg2sol(NbrSol) = TheTool::Value(Cu2,pararg2(NbrSol)); + par1sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol), + pnttg1sol(NbrSol)); + par2sol(NbrSol)=ElCLib::Parameter(cirsol(NbrSol), + pnttg2sol(NbrSol)); + } + } + + WellDone = Standard_True; + } + } + } + } +} //========================================================================= Standard_Boolean GccGeo_Circ2d2TanRad:: - IsDone () const { return WellDone; } +IsDone () const { return WellDone; } Standard_Integer GccGeo_Circ2d2TanRad:: - NbSolutions () const { return NbrSol; } +NbSolutions () const { return NbrSol; } gp_Circ2d GccGeo_Circ2d2TanRad:: - ThisSolution (const Standard_Integer Index) const +ThisSolution (const Standard_Integer Index) const { if (!WellDone) { StdFail_NotDone::Raise(); } if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); } @@ -729,9 +954,9 @@ gp_Circ2d GccGeo_Circ2d2TanRad:: } void GccGeo_Circ2d2TanRad:: - WhichQualifier(const Standard_Integer Index , - GccEnt_Position& Qualif1 , - GccEnt_Position& Qualif2 ) const +WhichQualifier(const Standard_Integer Index , + GccEnt_Position& Qualif1 , + GccEnt_Position& Qualif2 ) const { if (!WellDone) { StdFail_NotDone::Raise(); } else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); } @@ -742,41 +967,41 @@ void GccGeo_Circ2d2TanRad:: } void GccGeo_Circ2d2TanRad:: - Tangency1 (const Standard_Integer Index, - Standard_Real& ParSol, - Standard_Real& ParArg, - gp_Pnt2d& PntSol) const{ - if (!WellDone) { StdFail_NotDone::Raise(); } - else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); } - else { - if (TheSame1(Index) == 0) { - ParSol = par1sol(Index); - ParArg = pararg1(Index); - PntSol = gp_Pnt2d(pnttg1sol(Index)); - } - else { StdFail_NotDone::Raise(); } - } - } +Tangency1 (const Standard_Integer Index, + Standard_Real& ParSol, + Standard_Real& ParArg, + gp_Pnt2d& PntSol) const{ + if (!WellDone) { StdFail_NotDone::Raise(); } + else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); } + else { + if (TheSame1(Index) == 0) { + ParSol = par1sol(Index); + ParArg = pararg1(Index); + PntSol = gp_Pnt2d(pnttg1sol(Index)); + } + else { StdFail_NotDone::Raise(); } + } +} void GccGeo_Circ2d2TanRad:: - Tangency2 (const Standard_Integer Index, - Standard_Real& ParSol, - Standard_Real& ParArg, - gp_Pnt2d& PntSol) const{ - if (!WellDone) { StdFail_NotDone::Raise(); } - else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); } - else { - if (TheSame2(Index) == 0) { - ParSol = par2sol(Index); - ParArg = pararg2(Index); - PntSol = gp_Pnt2d(pnttg2sol(Index)); - } - else { StdFail_NotDone::Raise(); } - } - } +Tangency2 (const Standard_Integer Index, + Standard_Real& ParSol, + Standard_Real& ParArg, + gp_Pnt2d& PntSol) const{ + if (!WellDone) { StdFail_NotDone::Raise(); } + else if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); } + else { + if (TheSame2(Index) == 0) { + ParSol = par2sol(Index); + ParArg = pararg2(Index); + PntSol = gp_Pnt2d(pnttg2sol(Index)); + } + else { StdFail_NotDone::Raise(); } + } +} Standard_Boolean GccGeo_Circ2d2TanRad:: - IsTheSame1 (const Standard_Integer Index) const +IsTheSame1 (const Standard_Integer Index) const { if (!WellDone) { StdFail_NotDone::Raise(); } if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); } @@ -786,7 +1011,7 @@ Standard_Boolean GccGeo_Circ2d2TanRad:: } Standard_Boolean GccGeo_Circ2d2TanRad:: - IsTheSame2 (const Standard_Integer Index) const +IsTheSame2 (const Standard_Integer Index) const { if (!WellDone) { StdFail_NotDone::Raise(); } if (Index <= 0 ||Index > NbrSol) { Standard_OutOfRange::Raise(); } diff --git a/src/QABugs/QABugs_9.cxx b/src/QABugs/QABugs_9.cxx index ce662f00db..d07303fe45 100755 --- a/src/QABugs/QABugs_9.cxx +++ b/src/QABugs/QABugs_9.cxx @@ -148,12 +148,85 @@ static Standard_Integer OCC137_z (Draw_Interpretor& di, Standard_Integer argc, c return 0; } +#include +#include +#include +#include +#include +#include + +static Standard_Integer OCC24303(Draw_Interpretor& di, Standard_Integer n, const char** a) +{ + if(n < 2) + return 1; + + const Standard_Integer SolID = Draw::Atoi(a[1]); + + //Ellipses + Standard_Real majorRadius = 2.0; + Standard_Real minorRadius = 1.0; + gp_Pnt2d p0(gp::Origin2d()); + gp_Pnt2d p1(4.0,0.0); + + gp_Elips2d ellipse1 = gp_Elips2d( gp_Ax2d(p0,gp::DX2d()),majorRadius, minorRadius,true); + gp_Elips2d ellipse2 = gp_Elips2d( gp_Ax2d(p1,gp::DX2d()),majorRadius, minorRadius,true); + + Handle_Geom2d_Curve curve1 = new Geom2d_Ellipse(ellipse1); + Handle_Geom2d_Curve curve2 = new Geom2d_Ellipse(ellipse2); + DrawTrSurf::Set("c1", curve1); + DrawTrSurf::Set("c2", curve2); + //Expected tangent + gp_Pnt2d centre(5.0,0.0); + Standard_Real radius = 3.0; + gp_Circ2d theorical_tangent = gp_Circ2d(gp_Ax2d(centre,gp::DX2d()),radius); + + //Calculate the tangent with Geom2dGcc_Circ2dTanRan + + const Geom2dAdaptor_Curve AdaptedCurve1 ( curve1 ); + const Geom2dAdaptor_Curve AdaptedCurve2 ( curve2 ); + + GccEnt_Position curveQualif1 = GccEnt_unqualified; + GccEnt_Position curveQualif2 = GccEnt_unqualified; + + const Geom2dGcc_QualifiedCurve qualifiedCurve1 ( AdaptedCurve1, curveQualif1 ); + const Geom2dGcc_QualifiedCurve qualifiedCurve2 ( AdaptedCurve2, curveQualif2 ); + + const Geom2dGcc_Circ2d2TanRad circCalc(qualifiedCurve1,qualifiedCurve2,radius,/*Precision::Approximation()*/ 1.0e-9); + + const Standard_Integer aNbSol = circCalc.NbSolutions(); + di << "Solutions " << aNbSol << "\n"; + + if((SolID < 1) || (SolID > aNbSol)) + { + di << "Wrong SolID value\n"; + return 1; + } + + gp_Circ2d calculated_tangent = circCalc.ThisSolution(SolID); + + char Buf[10]; + for (Standard_Integer i = 1; i <= aNbSol; i++) + { + gp_Circ2d ct = circCalc.ThisSolution(i); + Handle (Geom2d_Circle) GSol = new Geom2d_Circle(ct); + Sprintf(Buf, "Sol%d",i); + DrawTrSurf::Set(Buf, GSol); + } + + //This distance is different in OC 6.5.4 and OC 6.6.0 + Standard_Real dist = theorical_tangent.Location().Distance(calculated_tangent.Location()); + di << "Distance = " << dist << "\n"; + + return 0; +} + void QABugs::Commands_9(Draw_Interpretor& theCommands) { const char *group = "QABugs"; theCommands.Add ("BUC60857", "BUC60857", __FILE__, BUC60857, group); theCommands.Add("OCC137","OCC137 mode [shape]",__FILE__,OCC137,group); theCommands.Add("OCC137_z","OCC137_z [ZDetection_mode]",__FILE__,OCC137_z,group); + theCommands.Add("OCC24303", "OCC24303 SolID ", __FILE__, OCC24303,group); return; } diff --git a/tests/bugs/modalg_5/bug24303 b/tests/bugs/modalg_5/bug24303 new file mode 100755 index 0000000000..14a8ea699e --- /dev/null +++ b/tests/bugs/modalg_5/bug24303 @@ -0,0 +1,67 @@ +puts "============" +puts "OCC24303" +puts "============" +puts "" +############################### +## Precision degradation for Geom2dGcc_Circ2d2TanRad in OCCT6.6.0. +############################### + +pload QAcommands + +set status 0 + +set info1 [OCC24303 4] +regexp {Solutions +([-0-9.+eE]+)} ${info1} full Solution +regexp {Distance += +([-0-9.+eE]+)} ${info1} full Distance + +if { [info exists Sol4] } { + set info2 [dump Sol4] + regexp {Center +:([-0-9.+eE]+), +([-0-9.+eE]+)} ${info2} full CenterX CenterY + regexp {XAxis +:([-0-9.+eE]+), +([-0-9.+eE]+)} ${info2} full XAxisX XAxisY + regexp {YAxis +:([-0-9.+eE]+), +([-0-9.+eE]+)} ${info2} full YAxisX YAxisY + regexp {Radius +:([-0-9.+eE]+)} ${info2} full Radius + set good_CenterX 5 + set good_CenterY 0 + set good_XAxisX 1 + set good_XAxisY 0 + set good_YAxisX 0 + set good_YAxisY 1 + set good_Radius 3 + if { ${CenterX} != ${good_CenterX} } { + puts "Faulty : Bad CenterX" + set status 1 + } + if { ${CenterY} != ${good_CenterY} } { + puts "Faulty : Bad CenterY" + set status 1 + } + if { ${XAxisX} != ${good_XAxisX} } { + puts "Faulty : Bad XAxisX" + set status 1 + } + if { ${XAxisY} != ${good_XAxisY} } { + puts "Faulty : Bad XAxisY" + set status 1 + } + if { ${YAxisX} != ${good_YAxisX} } { + puts "Faulty : Bad YAxisX" + set status 1 + } + if { ${YAxisY} != ${good_YAxisY} } { + puts "Faulty : Bad YAxisY" + set status 1 + } + if { ${Radius} != ${good_Radius} } { + puts "Faulty : Bad Radius" + set status 1 + } + } else { + puts "Faulty : Bad solution" + set status 1 +} + +if { ${status} != 0 } { + puts "Faulty : solution is wrong" +} else { + puts "OK : solution is correct" +}