1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-10 18:51:21 +03:00

0024303: Precision degradation for Geom2dGcc_Circ2d2TanRad in OCCT6.6.0.

1. DRAW-command.
2. Initial point (the center of found circle), which is found by standard algorithm, is precised in function PrecRoot(...). Correction is called, if and only if initial point is in tangent zone.
3. Handling of possible divergences and of possible exceptions in PrecRoot() function is added.

Test cases for issue CR24303
This commit is contained in:
nbv 2013-11-14 11:11:29 +04:00 committed by bugmaster
parent c24d401753
commit 74f5f8df5d
3 changed files with 980 additions and 615 deletions

View File

@ -44,7 +44,7 @@
//========================================================================
GccGeo_Circ2d2TanRad::
GccGeo_Circ2d2TanRad (const GccEnt_QualifiedLin& Qualified1,
GccGeo_Circ2d2TanRad (const GccEnt_QualifiedLin& Qualified1,
const TheQCurve& Qualified2,
const Standard_Real Radius ,
const Standard_Real Tolerance ):
@ -53,22 +53,22 @@ GccGeo_Circ2d2TanRad::
// 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.;
@ -101,35 +101,35 @@ GccGeo_Circ2d2TanRad::
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;
@ -137,7 +137,7 @@ GccGeo_Circ2d2TanRad::
cote2(2) = -Radius;
}
if(Qualified1.IsUnqualified() && Qualified2.IsEnclosed()) {
// =========================================================
// =========================================================
nbrcote1 = 2;
nbrcote2 = 1;
cote1(1) = Radius;
@ -145,7 +145,7 @@ GccGeo_Circ2d2TanRad::
cote2(1) = Radius;
}
else if(Qualified1.IsOutside() && Qualified2.IsUnqualified()) {
// =============================================================
// =============================================================
nbrcote1 = 1;
nbrcote2 = 2;
cote1(1) = -Radius;
@ -153,7 +153,7 @@ GccGeo_Circ2d2TanRad::
cote2(2) = -Radius;
}
if(Qualified1.IsUnqualified() && Qualified2.IsOutside()) {
// ========================================================
// ========================================================
nbrcote1 = 2;
nbrcote2 = 1;
cote1(1) = Radius;
@ -161,7 +161,7 @@ GccGeo_Circ2d2TanRad::
cote2(1) = -Radius;
}
else if(Qualified1.IsUnqualified() && Qualified2.IsUnqualified()) {
// =================================================================
// =================================================================
nbrcote1 = 2;
nbrcote2 = 2;
cote1(1) = Radius;
@ -188,7 +188,7 @@ GccGeo_Circ2d2TanRad::
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()) {
@ -215,7 +215,7 @@ GccGeo_Circ2d2TanRad::
}
}
}
}
}
// circulaire tant a une courbe et un cercle ,de rayon donne
//=============================================================
@ -232,7 +232,7 @@ GccGeo_Circ2d2TanRad::
//========================================================================
GccGeo_Circ2d2TanRad::
GccGeo_Circ2d2TanRad (const GccEnt_QualifiedCirc& Qualified1,
GccGeo_Circ2d2TanRad (const GccEnt_QualifiedCirc& Qualified1,
const TheQCurve& Qualified2,
const Standard_Real Radius ,
const Standard_Real Tolerance ):
@ -241,22 +241,22 @@ GccGeo_Circ2d2TanRad::
// 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.;
@ -283,35 +283,35 @@ GccGeo_Circ2d2TanRad::
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;
@ -319,7 +319,7 @@ GccGeo_Circ2d2TanRad::
cote2(2) = -Radius;
}
if(Qualified1.IsUnqualified() && Qualified2.IsEnclosed()) {
// =========================================================
// =========================================================
nbrcote1 = 2;
nbrcote2 = 1;
cote1(1) = Radius;
@ -327,7 +327,7 @@ GccGeo_Circ2d2TanRad::
cote2(1) = Radius;
}
else if(Qualified1.IsOutside() && Qualified2.IsUnqualified()) {
// =============================================================
// =============================================================
nbrcote1 = 1;
nbrcote2 = 2;
cote1(1) = -Radius;
@ -335,7 +335,7 @@ GccGeo_Circ2d2TanRad::
cote2(2) = -Radius;
}
if(Qualified1.IsUnqualified() && Qualified2.IsOutside()) {
// ========================================================
// ========================================================
nbrcote1 = 2;
nbrcote2 = 1;
cote1(1) = Radius;
@ -343,7 +343,7 @@ GccGeo_Circ2d2TanRad::
cote2(1) = -Radius;
}
else if(Qualified1.IsUnqualified() && Qualified2.IsUnqualified()) {
// =================================================================
// =================================================================
nbrcote1 = 2;
nbrcote2 = 2;
cote1(1) = Radius;
@ -372,7 +372,7 @@ GccGeo_Circ2d2TanRad::
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());
#else
@ -408,7 +408,7 @@ GccGeo_Circ2d2TanRad::
}
}
}
}
}
// circulaire tant a une courbe et un point ,de rayon donne
//============================================================
@ -425,7 +425,7 @@ GccGeo_Circ2d2TanRad::
//========================================================================
GccGeo_Circ2d2TanRad::
GccGeo_Circ2d2TanRad (const TheQCurve& Qualified1,
GccGeo_Circ2d2TanRad (const TheQCurve& Qualified1,
const gp_Pnt2d& Point2 ,
const Standard_Real Radius ,
const Standard_Real Tolerance ):
@ -434,22 +434,22 @@ GccGeo_Circ2d2TanRad::
// 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.;
@ -470,17 +470,17 @@ GccGeo_Circ2d2TanRad::
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;
@ -504,7 +504,7 @@ GccGeo_Circ2d2TanRad::
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;
@ -523,7 +523,199 @@ GccGeo_Circ2d2TanRad::
}
}
}
}
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,7 +732,7 @@ GccGeo_Circ2d2TanRad::
//========================================================================
GccGeo_Circ2d2TanRad::
GccGeo_Circ2d2TanRad (const TheQCurve& Qualified1,
GccGeo_Circ2d2TanRad (const TheQCurve& Qualified1,
const TheQCurve& Qualified2,
const Standard_Real Radius ,
const Standard_Real Tolerance ):
@ -549,22 +741,22 @@ GccGeo_Circ2d2TanRad::
// 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.;
@ -590,35 +782,35 @@ GccGeo_Circ2d2TanRad::
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;
@ -626,7 +818,7 @@ GccGeo_Circ2d2TanRad::
cote2(2) = -Radius;
}
if(Qualified1.IsUnqualified() && Qualified2.IsEnclosed()) {
// =========================================================
// =========================================================
nbrcote1 = 2;
nbrcote2 = 1;
cote1(1) = Radius;
@ -634,7 +826,7 @@ GccGeo_Circ2d2TanRad::
cote2(1) = Radius;
}
else if(Qualified1.IsOutside() && Qualified2.IsUnqualified()) {
// =============================================================
// =============================================================
nbrcote1 = 1;
nbrcote2 = 2;
cote1(1) = -Radius;
@ -642,7 +834,7 @@ GccGeo_Circ2d2TanRad::
cote2(2) = -Radius;
}
if(Qualified1.IsUnqualified() && Qualified2.IsOutside()) {
// ========================================================
// ========================================================
nbrcote1 = 2;
nbrcote2 = 1;
cote1(1) = Radius;
@ -650,7 +842,7 @@ GccGeo_Circ2d2TanRad::
cote2(1) = -Radius;
}
else if(Qualified1.IsUnqualified() && Qualified2.IsUnqualified()) {
// =================================================================
// =================================================================
nbrcote1 = 2;
nbrcote2 = 2;
cote1(1) = Radius;
@ -686,11 +878,43 @@ GccGeo_Circ2d2TanRad::
Intp.Perform(C1,C2,Tol,Tol);
if (Intp.IsDone()) {
if (!Intp.IsEmpty()) {
for (Standard_Integer i = 1 ; i <= Intp.NbPoints() ; i++) {
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(Intp.Point(i).Value());
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;
@ -705,23 +929,24 @@ GccGeo_Circ2d2TanRad::
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,7 +954,7 @@ gp_Circ2d GccGeo_Circ2d2TanRad::
}
void GccGeo_Circ2d2TanRad::
WhichQualifier(const Standard_Integer Index ,
WhichQualifier(const Standard_Integer Index ,
GccEnt_Position& Qualif1 ,
GccEnt_Position& Qualif2 ) const
{
@ -742,7 +967,7 @@ void GccGeo_Circ2d2TanRad::
}
void GccGeo_Circ2d2TanRad::
Tangency1 (const Standard_Integer Index,
Tangency1 (const Standard_Integer Index,
Standard_Real& ParSol,
Standard_Real& ParArg,
gp_Pnt2d& PntSol) const{
@ -756,10 +981,10 @@ void GccGeo_Circ2d2TanRad::
}
else { StdFail_NotDone::Raise(); }
}
}
}
void GccGeo_Circ2d2TanRad::
Tangency2 (const Standard_Integer Index,
Tangency2 (const Standard_Integer Index,
Standard_Real& ParSol,
Standard_Real& ParArg,
gp_Pnt2d& PntSol) const{
@ -773,10 +998,10 @@ void GccGeo_Circ2d2TanRad::
}
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(); }

View File

@ -148,12 +148,85 @@ static Standard_Integer OCC137_z (Draw_Interpretor& di, Standard_Integer argc, c
return 0;
}
#include <GccEnt_Position.hxx>
#include <Geom2dGcc_QualifiedCurve.hxx>
#include <Geom2dGcc_Circ2d2TanRad.hxx>
#include <gp_Elips2d.hxx>
#include <Geom2d_Ellipse.hxx>
#include <Geom2d_Circle.hxx>
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;
}

67
tests/bugs/modalg_5/bug24303 Executable file
View File

@ -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"
}