From: aml Date: Thu, 5 Feb 2015 13:13:39 +0000 (+0300) Subject: 0025635: Wrong result of 2D-extrema between two ellipsis X-Git-Tag: V6_9_0_beta~132 X-Git-Url: http://git.dev.opencascade.org/gitweb/?p=occt.git;a=commitdiff_plain;h=e8746a262f04ed6fde3cc5b2d6f60d99dedc2d25 0025635: Wrong result of 2D-extrema between two ellipsis Fixed Lipschitz constant evaluation in case co-parametrized objects. Fixed 2dextrema output. Testcase update to new behavior. Test cases for issue CR25635 Correction of test cases for issue CR25635 --- diff --git a/src/GeomliteTest/GeomliteTest_API2dCommands.cxx b/src/GeomliteTest/GeomliteTest_API2dCommands.cxx index 000f758153..dc21320e2b 100644 --- a/src/GeomliteTest/GeomliteTest_API2dCommands.cxx +++ b/src/GeomliteTest/GeomliteTest_API2dCommands.cxx @@ -250,20 +250,23 @@ static Standard_Integer extrema(Draw_Interpretor& di, Standard_Integer n, const gp_Pnt2d P1,P2; Ex.Points(i,P1,P2); - di << "dist " << i << ": " << Ex.Distance(i) << " \n"; + di << "dist " << i << ": " << Ex.Distance(i) << " "; if (Ex.Distance(i) <= Precision::PConfusion()) { Handle(Draw_Marker2D) mark = new Draw_Marker2D( P1, Draw_X, Draw_vert); dout << mark; dout.Flush(); + Sprintf(name,"%s%d","ext_",i); + char* temp = name; + DrawTrSurf::Set(temp, P1); + di << name << "\n"; } else { Handle(Geom2d_Line) L = new Geom2d_Line(P1,gp_Vec2d(P1,P2)); - Handle(Geom2d_TrimmedCurve) CT = - new Geom2d_TrimmedCurve(L, 0., P1.Distance(P2)); + Handle(Geom2d_TrimmedCurve) CT = new Geom2d_TrimmedCurve(L, 0., P1.Distance(P2)); Sprintf(name,"%s%d","ext_",i); char* temp = name; // portage WNT DrawTrSurf::Set(temp, CT); - di << name << " "; + di << name << "\n"; } } if (i==1) diff --git a/src/math/math_GlobOptMin.cxx b/src/math/math_GlobOptMin.cxx index 42f6a8bf19..0efeedb3ec 100644 --- a/src/math/math_GlobOptMin.cxx +++ b/src/math/math_GlobOptMin.cxx @@ -23,6 +23,7 @@ #include #include #include +#include //======================================================================= @@ -194,9 +195,6 @@ void math_GlobOptMin::Perform() { Standard_Integer i; - // Compute initial values for myF, myY, myC. - computeInitialValues(); - // Compute parameters range Standard_Real minLength = RealLast(); Standard_Real maxLength = RealFirst(); @@ -209,6 +207,18 @@ void math_GlobOptMin::Perform() maxLength = currentLength; } + if (minLength < Precision::PConfusion()) + { + #ifdef OCCT_DEBUG + cout << "math_GlobOptMin::Perform(): Degenerated parameters space" << endl; + #endif + + return; + } + + // Compute initial values for myF, myY, myC. + computeInitialValues(); + myE1 = minLength * myTol; myE2 = maxLength * myTol; if (myC > 1.0) @@ -293,7 +303,7 @@ void math_GlobOptMin::computeInitialValues() Standard_Integer i; math_Vector aCurrPnt(1, myN); math_Vector aBestPnt(1, myN); - + math_Vector aParamStep(1, myN); Standard_Real aCurrVal = RealLast(); Standard_Real aBestVal = RealLast(); @@ -324,21 +334,29 @@ void math_GlobOptMin::computeInitialValues() mySolCount++; // Lipschitz const approximation - Standard_Real aLipConst = 0.0, aPrevVal; + Standard_Real aLipConst = 0.0, aPrevValDiag, aPrevValProj; Standard_Integer aPntNb = 13; - myFunc->Value(myA, aPrevVal); + myFunc->Value(myA, aPrevValDiag); + aPrevValProj = aPrevValDiag; Standard_Real aStep = (myB - myA).Norm() / aPntNb; + aParamStep = (myB - myA) / aPntNb; for(i = 1; i <= aPntNb; i++) { - aCurrPnt = myA + (myB - myA) * i / (aPntNb - 1); - myFunc->Value(aCurrPnt, aCurrVal); + aCurrPnt = myA + aParamStep * i; - if(Abs(aCurrVal - aPrevVal) / aStep > aLipConst) - aLipConst = Abs(aCurrVal - aPrevVal) / aStep; + // Walk over diagonal. + myFunc->Value(aCurrPnt, aCurrVal); + aLipConst = Max (Abs(aCurrVal - aPrevValDiag), aLipConst); + aPrevValDiag = aCurrVal; - aPrevVal = aCurrVal; + // Walk over diag in projected space aPnt(1) = myA(1) = const. + aCurrPnt(1) = myA(1); + myFunc->Value(aCurrPnt, aCurrVal); + aLipConst = Max (Abs(aCurrVal - aPrevValProj), aLipConst); + aPrevValProj = aCurrVal; } - aLipConst *= Sqrt(myN); + + aLipConst *= Sqrt(myN) / aStep; if (aLipConst < myC * 0.1) { diff --git a/tests/bugs/fclasses/bug25635_1 b/tests/bugs/fclasses/bug25635_1 new file mode 100755 index 0000000000..0aba7dcc54 --- /dev/null +++ b/tests/bugs/fclasses/bug25635_1 @@ -0,0 +1,46 @@ +puts "============" +puts "OCC25635" +puts "============" +puts "" +###################################################### +# Wrong result of 2D-extrema between two ellipsis +###################################################### + +ellipse c1 0 0 2 1 +ellipse c2 4 0 2 1 + +set info [2dextrema c1 c2] + +set tol_abs 1.e-7 +set tol_rel 0.01 + +#-1 +regexp "dist 1: +(\[-0-9.+eE\]+)" ${info} full dist_1 + +set expected_dist_1 7.9e-09 +checkreal "Distance" ${dist_1} ${expected_dist_1} ${tol_abs} ${tol_rel} + +#-2 +set dump_list [dump ext_1] + +regexp { *Parameters *: *([-0-9.+eE]+) *([-0-9.+eE]+)} ${dump_list} full Parameter1 Parameter2 +regexp { *Origin *:([-0-9.+eE]+), *([-0-9.+eE]+) } ${dump_list} full OriginX OriginY +regexp { *Axis *:([-0-9.+eE]+), *([-0-9.+eE]+) } ${dump_list} full AxisX AxisY + +set expected_Parameter1 0. +checkreal "Parameter1" ${Parameter1} ${expected_Parameter1} ${tol_abs} ${tol_rel} + +set expected_Parameter2 7.94518140168066e-09 +checkreal "Parameter2" ${Parameter2} ${expected_Parameter2} ${tol_abs} ${tol_rel} + +set expected_OriginX 1.99999999602741 +checkreal "OriginX" ${OriginX} ${expected_OriginX} ${tol_abs} ${tol_rel} + +set expected_OriginY -6.30284903027441e-05 +checkreal "OriginY" ${OriginY} ${expected_OriginY} ${tol_abs} ${tol_rel} + +set expected_AxisX 1. +checkreal "AxisX" ${AxisX} ${expected_AxisX} ${tol_abs} ${tol_rel} + +set expected_AxisY -9.65456920683062e-09 +checkreal "AxisY" ${AxisY} ${expected_AxisY} ${tol_abs} ${tol_rel} diff --git a/tests/bugs/fclasses/bug25635_2 b/tests/bugs/fclasses/bug25635_2 new file mode 100755 index 0000000000..ee048034cc --- /dev/null +++ b/tests/bugs/fclasses/bug25635_2 @@ -0,0 +1,47 @@ +puts "============" +puts "OCC25635" +puts "============" +puts "" +###################################################### +# Wrong result of 2D-extrema between two ellipsis +###################################################### + +circle c1 0 0 2 +circle c2 4 0 2 + +set info [2dextrema c1 c2] + +#-1 +if { [regexp "dist 1: +(\[-0-9.+eE\]+) +ext_1" ${info}] } { + puts "OK: Good ext_1" +} else { + puts "Error: Wrong ext_1" +} + +if { [regexp "dist 2: +(\[-0-9.+eE\]+) +ext_2" ${info}] } { + puts "OK: Good ext_2" +} else { + puts "Error: Wrong ext_2" +} + +if { [regexp "dist 3: +(\[-0-9.+eE\]+) +ext_3" ${info}] } { + puts "OK: Good ext_3" +} else { + puts "Error: Wrong ext_3" +} + +if { [regexp "dist 4: +(\[-0-9.+eE\]+) +ext_4" ${info}] } { + puts "OK: Good ext_4" +} else { + puts "Error: Wrong ext_4" +} + + +#-2 +set dump_list [dump ext_2] + +if { [regexp {Point 2d} ${dump_list}] } { + puts "OK: Good result of 2D-extrema between two circles" +} else { + puts "Error: Wrong result of 2D-extrema between two circles" +} diff --git a/tests/bugs/moddata_1/buc60890 b/tests/bugs/moddata_1/buc60890 index e2cb21f72c..453b19b67d 100755 --- a/tests/bugs/moddata_1/buc60890 +++ b/tests/bugs/moddata_1/buc60890 @@ -15,7 +15,7 @@ circle curve_2 5.3 -0.5 2 set err [llength [2dextrema curve_1 curve_2]] -if {$err == 6} { +if {$err == 8} { puts "BUC60890 OK: Function 2dextrema works properly." } else { puts "Faulty BUC60890 : Function 2dextrema works wrongly."