mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-04-10 18:51:21 +03:00
0025757: distmini returns wrong solution for ellipse/vertex
Analytical handling of degenerated cases added. Test case for issue CR25757 Correction of test case for issue CR25757
This commit is contained in:
parent
2bfe59b69c
commit
20f319cdb8
@ -29,6 +29,7 @@
|
|||||||
#include <Standard_OutOfRange.hxx>
|
#include <Standard_OutOfRange.hxx>
|
||||||
#include <math_FunctionWithDerivative.hxx>
|
#include <math_FunctionWithDerivative.hxx>
|
||||||
#include <math_NewtonFunctionRoot.hxx>
|
#include <math_NewtonFunctionRoot.hxx>
|
||||||
|
#include <Precision.hxx>
|
||||||
|
|
||||||
|
|
||||||
class MyTrigoFunction: public math_FunctionWithDerivative
|
class MyTrigoFunction: public math_FunctionWithDerivative
|
||||||
@ -178,97 +179,207 @@ void math_TrigonometricFunctionRoots::Perform(const Standard_Real A,
|
|||||||
if ((Abs(A) <= Eps) && (Abs(B) <= Eps)) {
|
if ((Abs(A) <= Eps) && (Abs(B) <= Eps)) {
|
||||||
if (Abs(C) <= Eps) {
|
if (Abs(C) <= Eps) {
|
||||||
if (Abs(D) <= Eps) {
|
if (Abs(D) <= Eps) {
|
||||||
if (Abs(E) <= Eps) {
|
if (Abs(E) <= Eps) {
|
||||||
InfiniteStatus = Standard_True; // infinite de solutions.
|
InfiniteStatus = Standard_True; // infinite de solutions.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
NbSol = 0;
|
NbSol = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Equation du type d*sin(x) + e = 0
|
// Equation du type d*sin(x) + e = 0
|
||||||
// =================================
|
// =================================
|
||||||
NbSol = 0;
|
NbSol = 0;
|
||||||
AA = -E/D;
|
AA = -E/D;
|
||||||
if (Abs(AA) > 1.) {
|
if (Abs(AA) > 1.) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Zer(1) = ASin(AA);
|
Zer(1) = ASin(AA);
|
||||||
Zer(2) = M_PI - Zer(1);
|
Zer(2) = M_PI - Zer(1);
|
||||||
NZer = 2;
|
NZer = 2;
|
||||||
for (i = 1; i <= NZer; i++) {
|
for (i = 1; i <= NZer; i++) {
|
||||||
if (Zer(i) <= -Eps) {
|
if (Zer(i) <= -Eps) {
|
||||||
Zer(i) = Depi - Abs(Zer(i));
|
Zer(i) = Depi - Abs(Zer(i));
|
||||||
}
|
}
|
||||||
// On rend les solutions entre InfBound et SupBound:
|
// On rend les solutions entre InfBound et SupBound:
|
||||||
// =================================================
|
// =================================================
|
||||||
Zer(i) += IntegerPart(Mod)*Depi;
|
Zer(i) += IntegerPart(Mod)*Depi;
|
||||||
X = Zer(i)-MyBorneInf;
|
X = Zer(i)-MyBorneInf;
|
||||||
if ((X > (-Epsilon(Delta))) && (X < Delta+ Epsilon(Delta))) {
|
if ((X > (-Epsilon(Delta))) && (X < Delta+ Epsilon(Delta))) {
|
||||||
NbSol++;
|
NbSol++;
|
||||||
Sol(NbSol) = Zer(i);
|
Sol(NbSol) = Zer(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (Abs(D) <= Eps) {
|
else if (Abs(D) <= Eps) {
|
||||||
|
|
||||||
// Equation du premier degre de la forme c*cos(x) + e = 0
|
// Equation du premier degre de la forme c*cos(x) + e = 0
|
||||||
// ======================================================
|
// ======================================================
|
||||||
NbSol = 0;
|
NbSol = 0;
|
||||||
AA = -E/C;
|
AA = -E/C;
|
||||||
if (Abs(AA) >1.) {
|
if (Abs(AA) >1.) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Zer(1) = ACos(AA);
|
Zer(1) = ACos(AA);
|
||||||
Zer(2) = -Zer(1);
|
Zer(2) = -Zer(1);
|
||||||
NZer = 2;
|
NZer = 2;
|
||||||
|
|
||||||
for (i = 1; i <= NZer; i++) {
|
for (i = 1; i <= NZer; i++) {
|
||||||
if (Zer(i) <= -Eps) {
|
if (Zer(i) <= -Eps) {
|
||||||
Zer(i) = Depi-Abs(Zer(i));
|
Zer(i) = Depi - Abs(Zer(i));
|
||||||
}
|
}
|
||||||
// On rend les solutions entre InfBound et SupBound:
|
// On rend les solutions entre InfBound et SupBound:
|
||||||
// =================================================
|
// =================================================
|
||||||
Zer(i) += IntegerPart(Mod)*2.*M_PI;
|
Zer(i) += IntegerPart(Mod)*2.*M_PI;
|
||||||
X = Zer(i)-MyBorneInf;
|
X = Zer(i)-MyBorneInf;
|
||||||
if ((X >= (-Epsilon(Delta))) && (X <= Delta+ Epsilon(Delta))) {
|
if ((X >= (-Epsilon(Delta))) && (X <= Delta+ Epsilon(Delta))) {
|
||||||
NbSol++;
|
NbSol++;
|
||||||
Sol(NbSol) = Zer(i);
|
Sol(NbSol) = Zer(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
// Equation du second degre:
|
// Equation du second degre:
|
||||||
// =========================
|
// =========================
|
||||||
AA = E - C;
|
AA = E - C;
|
||||||
BB = 2.0*D;
|
BB = 2.0*D;
|
||||||
CC = E + C;
|
CC = E + C;
|
||||||
|
|
||||||
math_DirectPolynomialRoots Resol(AA, BB, CC);
|
math_DirectPolynomialRoots Resol(AA, BB, CC);
|
||||||
if (!Resol.IsDone()) {
|
if (!Resol.IsDone()) {
|
||||||
Done = Standard_False;
|
Done = Standard_False;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if(!Resol.InfiniteRoots()) {
|
else if(!Resol.InfiniteRoots()) {
|
||||||
NZer = Resol.NbSolutions();
|
NZer = Resol.NbSolutions();
|
||||||
for (i = 1; i <= NZer; i++) {
|
for (i = 1; i <= NZer; i++) {
|
||||||
Zer(i) = Resol.Value(i);
|
Zer(i) = Resol.Value(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (Resol.InfiniteRoots()) {
|
else if (Resol.InfiniteRoots()) {
|
||||||
InfiniteStatus = Standard_True;
|
InfiniteStatus = Standard_True;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
// Two additional analytical cases.
|
||||||
|
if ((Abs(A) <= Eps) &&
|
||||||
|
(Abs(E) <= Eps))
|
||||||
|
{
|
||||||
|
if (Abs(C) <= Eps)
|
||||||
|
{
|
||||||
|
// 2 * B * sin * cos + D * sin = 0
|
||||||
|
NZer = 2;
|
||||||
|
Zer(1) = 0.0;
|
||||||
|
Zer(2) = M_PI;
|
||||||
|
|
||||||
|
AA = -D/(B * 2);
|
||||||
|
if (Abs(AA) <= 1.0 + Precision::PConfusion())
|
||||||
|
{
|
||||||
|
NZer = 4;
|
||||||
|
if (AA >= 1.0)
|
||||||
|
{
|
||||||
|
Zer(3)= 0.0;
|
||||||
|
Zer(4)= 0.0;
|
||||||
|
}
|
||||||
|
else if (AA <= -1.0)
|
||||||
|
{
|
||||||
|
Zer(3)= M_PI;
|
||||||
|
Zer(4)= M_PI;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Zer(3)= ACos(AA);
|
||||||
|
Zer(4) = Depi - Zer(3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NbSol = 0;
|
||||||
|
for (i = 1; i <= NZer; i++)
|
||||||
|
{
|
||||||
|
if (Zer(i) <= MyBorneInf - Eps)
|
||||||
|
{
|
||||||
|
Zer(i) += Depi;
|
||||||
|
}
|
||||||
|
// On rend les solutions entre InfBound et SupBound:
|
||||||
|
// =================================================
|
||||||
|
Zer(i) += IntegerPart(Mod)*2.*M_PI;
|
||||||
|
X = Zer(i)-MyBorneInf;
|
||||||
|
if ((X >= (-Precision::PConfusion())) &&
|
||||||
|
(X <= Delta + Precision::PConfusion()))
|
||||||
|
{
|
||||||
|
if (Zer(i) < InfBound)
|
||||||
|
Zer(i) = InfBound;
|
||||||
|
if (Zer(i) > SupBound)
|
||||||
|
Zer(i) = SupBound;
|
||||||
|
NbSol++;
|
||||||
|
Sol(NbSol) = Zer(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (Abs(D) <= Eps)
|
||||||
|
{
|
||||||
|
// 2 * B * sin * cos + C * cos = 0
|
||||||
|
NZer = 2;
|
||||||
|
Zer(1) = M_PI / 2.0;
|
||||||
|
Zer(2) = M_PI * 3.0 / 2.0;
|
||||||
|
|
||||||
|
AA = -C/(B * 2);
|
||||||
|
if (Abs(AA) <= 1.0 + Precision::PConfusion())
|
||||||
|
{
|
||||||
|
NZer = 4;
|
||||||
|
if (AA >= 1.0)
|
||||||
|
{
|
||||||
|
Zer(3) = M_PI / 2.0;
|
||||||
|
Zer(4) = M_PI / 2.0;
|
||||||
|
}
|
||||||
|
else if (AA <= -1.0)
|
||||||
|
{
|
||||||
|
|
||||||
|
Zer(3) = M_PI * 3.0 / 2.0;
|
||||||
|
Zer(4) = M_PI * 3.0 / 2.0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Zer(3)= ASin(AA);
|
||||||
|
Zer(4) = M_PI - Zer(3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NbSol = 0;
|
||||||
|
for (i = 1; i <= NZer; i++)
|
||||||
|
{
|
||||||
|
if (Zer(i) <= MyBorneInf - Eps)
|
||||||
|
{
|
||||||
|
Zer(i) += Depi;
|
||||||
|
}
|
||||||
|
// On rend les solutions entre InfBound et SupBound:
|
||||||
|
// =================================================
|
||||||
|
Zer(i) += IntegerPart(Mod)*2.*M_PI;
|
||||||
|
X = Zer(i)-MyBorneInf;
|
||||||
|
if ((X >= (-Precision::PConfusion())) &&
|
||||||
|
(X <= Delta + Precision::PConfusion()))
|
||||||
|
{
|
||||||
|
if (Zer(i) < InfBound)
|
||||||
|
Zer(i) = InfBound;
|
||||||
|
if (Zer(i) > SupBound)
|
||||||
|
Zer(i) = SupBound;
|
||||||
|
NbSol++;
|
||||||
|
Sol(NbSol) = Zer(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Equation du 4 ieme degre
|
// Equation du 4 ieme degre
|
||||||
// ========================
|
// ========================
|
||||||
|
29
tests/bugs/fclasses/bug25757
Executable file
29
tests/bugs/fclasses/bug25757
Executable file
@ -0,0 +1,29 @@
|
|||||||
|
puts "========"
|
||||||
|
puts "OCC25757"
|
||||||
|
puts "========"
|
||||||
|
puts ""
|
||||||
|
##############################################
|
||||||
|
# distmini returns wrong solution for ellipse/vertex
|
||||||
|
##############################################
|
||||||
|
|
||||||
|
restore [locate_data_file bug25757_ellipse.brep] ellipse
|
||||||
|
|
||||||
|
vertex vertex1 7.32050807568877 3.999999999999999 10.0
|
||||||
|
vertex vertex2 7.32050807568877 3.99999999999999 10.0
|
||||||
|
|
||||||
|
distmini dv1 vertex1 ellipse
|
||||||
|
set dist1 [dval dv1_val]
|
||||||
|
puts "vertex1 distance = ${dist1}"
|
||||||
|
|
||||||
|
distmini dv2 vertex2 ellipse
|
||||||
|
set dist2 [dval dv2_val]
|
||||||
|
puts "vertex2 distance = ${dist2}"
|
||||||
|
|
||||||
|
set tol_abs_dist 1.0e-12
|
||||||
|
set tol_rel_dist 1.0e-2
|
||||||
|
|
||||||
|
set expected_dist1 0.0
|
||||||
|
set expected_dist2 0.0
|
||||||
|
|
||||||
|
checkreal "Distance 1" ${dist1} ${expected_dist1} ${tol_abs_dist} ${tol_rel_dist}
|
||||||
|
checkreal "Distance 2" ${dist2} ${expected_dist2} ${tol_abs_dist} ${tol_rel_dist}
|
Loading…
x
Reference in New Issue
Block a user