1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-09-13 14:27:08 +03:00

0026038: Wrong result done by extrema for the circle and plane

Test cases for issue CR26038
This commit is contained in:
ifv
2015-04-16 14:00:57 +03:00
committed by bugmaster
parent c40b7d580e
commit 9dfbbfe673
4 changed files with 182 additions and 5 deletions

View File

@@ -38,6 +38,7 @@
#include <Extrema_ExtPElS.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <Extrema_ExtPS.hxx>
#include <ElSLib.hxx>
Extrema_ExtCS::Extrema_ExtCS()
{
@@ -218,6 +219,11 @@ void Extrema_ExtCS::Perform(const Adaptor3d_Curve& C,
myExtElCS.Perform(C.Circle(), myS->Cylinder());
break;
}
else if(myStype == GeomAbs_Plane)
{
myExtElCS.Perform(C.Circle(), myS->Plane());
break;
}
}
case GeomAbs_Hyperbola:
{
@@ -351,6 +357,30 @@ void Extrema_ExtCS::Perform(const Adaptor3d_Curve& C,
PS.Parameter(U, V);
AddSolution(C, Ucurve, U, V, PC.Value(), PS.Value(), myExtElCS.SquareDistance(i));
}
if(mySqDist.Length() == 0 && NbExt > 0)
{
//Analytical extremas seem to be out of curve/surface boundaries.
//For plane it is possible to add extremity points of curve
if(myStype == GeomAbs_Plane)
{
gp_Pln aPln = myS->Plane();
gp_Pnt PC, PP;
if(!Precision::IsInfinite(myucinf))
{
PC = C.Value(myucinf);
ElSLib::PlaneParameters(aPln.Position(), PC, U, V);
PP = ElSLib::PlaneValue(U, V, aPln.Position());
AddSolution(C, myucinf, U, V, PC, PP, PC.SquareDistance(PP));
}
if(!Precision::IsInfinite(myucsup))
{
PC = C.Value(myucsup);
ElSLib::PlaneParameters(aPln.Position(), PC, U, V);
PP = ElSLib::PlaneValue(U, V, aPln.Position());
AddSolution(C, myucsup, U, V, PC, PP, PC.SquareDistance(PP));
}
}
}
}
}

View File

@@ -311,13 +311,90 @@ Extrema_ExtElCS::Extrema_ExtElCS(const gp_Circ& C,
//void Extrema_ExtElCS::Perform(const gp_Circ& C,
// const gp_Pln& S)
void Extrema_ExtElCS::Perform(const gp_Circ& ,
const gp_Pln& )
void Extrema_ExtElCS::Perform(const gp_Circ& C,
const gp_Pln& S)
{
Standard_NotImplemented::Raise();
myDone = Standard_True;
myIsPar = Standard_False;
gp_Ax2 Pos = C.Position();
gp_Dir NCirc = Pos.Direction();
gp_Dir NPln = S.Axis().Direction();
if (NCirc.IsParallel(NPln, Precision::Angular())) {
mySqDist = new TColStd_HArray1OfReal(1, 1);
mySqDist->SetValue(1, S.SquareDistance(C.Location()));
myIsPar = Standard_True;
}
else {
gp_Dir ExtLine = NCirc ^ NPln;
ExtLine = ExtLine ^ NCirc;
//
gp_Dir XDir = Pos.XDirection();
Standard_Real T[2];
T[0] = XDir.AngleWithRef(ExtLine, NCirc);
if(T[0] < 0.)
{
//Put in period
T[0] += M_PI;
}
T[1] = T[0] + M_PI;
//
myNbExt = 2;
//Check intersection
IntAna_IntConicQuad anInter(C, S,
Precision::Angular(),
Precision::Confusion());
if(anInter.IsDone())
{
if(anInter.NbPoints() > 1)
{
myNbExt += anInter.NbPoints();
}
}
myPoint1 = new Extrema_HArray1OfPOnCurv(1, myNbExt);
mySqDist = new TColStd_HArray1OfReal(1, myNbExt);
myPoint2 = new Extrema_HArray1OfPOnSurf(1, myNbExt);
Standard_Integer i;
gp_Pnt PC, PP;
Standard_Real U, V;
Extrema_POnCurv POnC;
Extrema_POnSurf POnS;
for(i = 0; i < 2; ++i)
{
PC = ElCLib::CircleValue(T[i], C.Position(), C.Radius());
POnC.SetValues(T[i], PC);
myPoint1->SetValue(i+1, POnC);
ElSLib::PlaneParameters(S.Position(), PC, U, V);
PP = ElSLib::PlaneValue(U, V, S.Position());
POnS.SetParameters(U, V, PP);
myPoint2->SetValue(i+1, POnS);
mySqDist->SetValue(i+1, PC.SquareDistance(PP));
}
//
if(myNbExt > 2)
{
//Add intersection points
for(i = 1; i <= anInter.NbPoints(); ++i)
{
Standard_Real t = anInter.ParamOnConic(i);
PC = ElCLib::CircleValue(t, C.Position(), C.Radius());
POnC.SetValues(t, PC);
myPoint1->SetValue(i+2, POnC);
ElSLib::PlaneParameters(S.Position(), PC, U, V);
PP = ElSLib::PlaneValue(U, V, S.Position());
POnS.SetParameters(U, V, PP);
myPoint2->SetValue(i+2, POnS);
mySqDist->SetValue(i+2, PC.SquareDistance(PP));
}
}
}
//
}