Loading files
3d097a032This file is pinned to the selected release. Download the original to open it in your design tool.
// Created on: 1993-12-13
// Created by: Christophe MARION
// Copyright (c) 1993-1999 Matra Datavision
// Copyright (c) 1999-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <ElCLib.hxx>
#include <Extrema_ExtPElC2d.hxx>
#include <Extrema_POnCurv2d.hxx>
#include <gp_Circ2d.hxx>
#include <gp_Elips2d.hxx>
#include <gp_Hypr2d.hxx>
#include <gp_Lin2d.hxx>
#include <gp_Parab2d.hxx>
#include <gp_Pnt2d.hxx>
#include <math_DirectPolynomialRoots.hxx>
#include <math_TrigonometricFunctionRoots.hxx>
#include <Precision.hxx>
#include <Standard_NotImplemented.hxx>
#include <Standard_OutOfRange.hxx>
#include <StdFail_NotDone.hxx>
//=============================================================================
Extrema_ExtPElC2d::Extrema_ExtPElC2d()
{
myDone = false;
myNbExt = 0;
for (int i = 0; i < 4; i++)
{
mySqDist[i] = RealLast();
myIsMin[i] = false;
}
}
//=============================================================================
Extrema_ExtPElC2d::Extrema_ExtPElC2d(const gp_Pnt2d& P,
const gp_Lin2d& L,
const double Tol,
const double Uinf,
const double Usup)
{
Perform(P, L, Tol, Uinf, Usup);
}
void Extrema_ExtPElC2d::Perform(const gp_Pnt2d& P,
const gp_Lin2d& L,
const double Tol,
const double Uinf,
const double Usup)
{
myDone = true;
gp_Pnt2d OR, MyP;
myNbExt = 0;
gp_Vec2d V1 = gp_Vec2d(L.Direction());
OR = L.Location();
gp_Vec2d V(OR, P);
double Mydist = V1.Dot(V);
if ((Mydist >= Uinf - Tol) && (Mydist <= Usup + Tol))
{
myNbExt = 1;
MyP = OR.Translated(Mydist * V1);
Extrema_POnCurv2d MyPOnCurve(Mydist, MyP);
mySqDist[0] = P.SquareDistance(MyP);
myPoint[0] = MyPOnCurve;
myIsMin[0] = true;
}
}
//=============================================================================
Extrema_ExtPElC2d::Extrema_ExtPElC2d(const gp_Pnt2d& P,
const gp_Circ2d& C,
const double Tol,
const double Uinf,
const double Usup)
{
Perform(P, C, Tol, Uinf, Usup);
}
void Extrema_ExtPElC2d::Perform(const gp_Pnt2d& P,
const gp_Circ2d& C,
const double Tol,
const double Uinf,
const double Usup)
{
// gp_Pnt2d OC, P1, P2, OL;
gp_Pnt2d OC(C.Location());
myNbExt = 0;
if (OC.IsEqual(P, Precision::Confusion()))
{
myDone = false;
}
else
{
double radius, U1, U2;
gp_Pnt2d P1, P2;
myDone = true;
gp_Dir2d V(gp_Vec2d(P, OC));
radius = C.Radius();
P1 = OC.Translated(radius * V);
U1 = ElCLib::Parameter(C, P1);
U2 = U1 + M_PI;
P2 = OC.Translated(-radius * V);
double myuinf = Uinf;
ElCLib::AdjustPeriodic(Uinf, Uinf + 2 * M_PI, Precision::PConfusion(), myuinf, U1);
ElCLib::AdjustPeriodic(Uinf, Uinf + 2 * M_PI, Precision::PConfusion(), myuinf, U2);
if (((U1 - 2 * M_PI - Uinf) < Tol) && ((U1 - 2 * M_PI - Uinf) > -Tol))
{
U1 = Uinf;
P1 = OC.XY()
+ radius * (cos(U1) * C.XAxis().Direction().XY() + sin(U1) * C.YAxis().Direction().XY());
}
if (((U2 - 2 * M_PI - Uinf) < Tol) && ((U2 - 2 * M_PI - Uinf) > -Tol))
{
U2 = Uinf;
P2 = OC.XY()
+ radius * (cos(U2) * C.XAxis().Direction().XY() + sin(U2) * C.YAxis().Direction().XY());
}
if (((Uinf - U1) < Tol) && ((U1 - Usup) < Tol))
{
Extrema_POnCurv2d MyPOnCurve(U1, P1);
mySqDist[0] = P.SquareDistance(P1);
myPoint[0] = MyPOnCurve;
myIsMin[0] = true;
myNbExt++;
}
if (((Uinf - U2) < Tol) && ((U2 - Usup) < Tol))
{
Extrema_POnCurv2d MyPOnCurve(U2, P2);
mySqDist[myNbExt] = P.SquareDistance(P2);
myPoint[myNbExt] = MyPOnCurve;
myIsMin[myNbExt] = true;
myNbExt++;
}
}
}
//=============================================================================
Extrema_ExtPElC2d::Extrema_ExtPElC2d(const gp_Pnt2d& P,
const gp_Elips2d& E,
const double Tol,
const double Uinf,
const double Usup)
{
Perform(P, E, Tol, Uinf, Usup);
}
void Extrema_ExtPElC2d::Perform(const gp_Pnt2d& P,
const gp_Elips2d& E,
const double Tol,
const double Uinf,
const double Usup)
{
myDone = false;
myNbExt = 0;
// gp_Pnt2d OR, P1, P2;
gp_Pnt2d OR;
OR = E.Location();
int NoSol, NbSol;
double A = E.MajorRadius();
double B = E.MinorRadius();
gp_Vec2d V(OR, P);
if (OR.IsEqual(P, Precision::Confusion()) && (std::abs(A - B) <= Tol))
{
return;
}
else
{
double X = V.Dot(gp_Vec2d(E.XAxis().Direction()));
double Y = V.Dot(gp_Vec2d(E.YAxis().Direction()));
math_TrigonometricFunctionRoots Sol(0., (B * B - A * A) / 2., -B * Y, A * X, 0., Uinf, Usup);
if (!Sol.IsDone())
{
return;
}
gp_Pnt2d Cu;
double Us;
NbSol = Sol.NbSolutions();
myNbExt = 0;
for (NoSol = 1; NoSol <= NbSol; NoSol++)
{
Us = Sol.Value(NoSol);
Cu = ElCLib::Value(Us, E);
mySqDist[myNbExt] = Cu.SquareDistance(P);
myIsMin[myNbExt] = (NoSol == 0);
myPoint[myNbExt] = Extrema_POnCurv2d(Us, Cu);
myNbExt++;
}
myDone = true;
}
}
//=============================================================================
Extrema_ExtPElC2d::Extrema_ExtPElC2d(const gp_Pnt2d& P,
const gp_Hypr2d& C,
const double Tol,
const double Uinf,
const double Usup)
{
Perform(P, C, Tol, Uinf, Usup);
}
void Extrema_ExtPElC2d::Perform(const gp_Pnt2d& P,
const gp_Hypr2d& H,
const double Tol,
const double Uinf,
const double Usup)
{
gp_Pnt2d O = H.Location();
myDone = false;
myNbExt = 0;
double R = H.MajorRadius();
double r = H.MinorRadius();
gp_Vec2d OPp(O, P);
double Tol2 = Tol * Tol;
double X = OPp.Dot(gp_Vec2d(H.XAxis().Direction()));
double Y = OPp.Dot(gp_Vec2d(H.YAxis().Direction()));
double C1 = (R * R + r * r) / 4.;
math_DirectPolynomialRoots Sol(C1, -(X * R + Y * r) / 2., 0., (X * R - Y * r) / 2., -C1);
if (!Sol.IsDone())
{
return;
}
gp_Pnt2d Cu;
double Us, Vs;
int NbSol = Sol.NbSolutions();
bool DejaEnr;
int NoExt;
gp_Pnt2d TbExt[4];
for (int NoSol = 1; NoSol <= NbSol; NoSol++)
{
Vs = Sol.Value(NoSol);
if (Vs > 0.)
{
Us = std::log(Vs);
if ((Us >= Uinf) && (Us <= Usup))
{
Cu = ElCLib::Value(Us, H);
DejaEnr = false;
for (NoExt = 0; NoExt < myNbExt; NoExt++)
{
if (TbExt[NoExt].SquareDistance(Cu) < Tol2)
{
DejaEnr = true;
break;
}
}
if (!DejaEnr)
{
TbExt[myNbExt] = Cu;
mySqDist[myNbExt] = Cu.SquareDistance(P);
myIsMin[myNbExt] = (NoSol == 0);
myPoint[myNbExt] = Extrema_POnCurv2d(Us, Cu);
myNbExt++;
}
} // if ((Us >= Uinf) && (Us <= Usup))
} // if (Vs > 0.)
} // for (int NoSol = 1; ...
myDone = true;
}
//=============================================================================
Extrema_ExtPElC2d::Extrema_ExtPElC2d(const gp_Pnt2d& P,
const gp_Parab2d& C,
const double Tol,
const double Uinf,
const double Usup)
{
Perform(P, C, Tol, Uinf, Usup);
}
void Extrema_ExtPElC2d::Perform(const gp_Pnt2d& P,
const gp_Parab2d& C,
const double Tol,
const double Uinf,
const double Usup)
{
myDone = false;
myNbExt = 0;
gp_Pnt2d O = C.Location();
double Tol2 = Tol * Tol;
double F = C.Focal();
gp_Vec2d OPp(O, P);
double X = OPp.Dot(gp_Vec2d(C.MirrorAxis().Direction()));
double Y = OPp.Dot(gp_Vec2d(C.Axis().YAxis().Direction()));
math_DirectPolynomialRoots Sol(1. / (4. * F), 0., 2. * F - X, -2. * F * Y);
if (!Sol.IsDone())
{
return;
}
gp_Pnt2d Cu;
double Us;
int NbSol = Sol.NbSolutions();
bool DejaEnr;
int NoExt;
gp_Pnt2d TbExt[3];
for (int NoSol = 1; NoSol <= NbSol; NoSol++)
{
Us = Sol.Value(NoSol);
if ((Us >= Uinf) && (Us <= Usup))
{
Cu = ElCLib::Value(Us, C);
DejaEnr = false;
for (NoExt = 0; NoExt < myNbExt; NoExt++)
{
if (TbExt[NoExt].SquareDistance(Cu) < Tol2)
{
DejaEnr = true;
break;
}
}
if (!DejaEnr)
{
TbExt[myNbExt] = Cu;
mySqDist[myNbExt] = Cu.SquareDistance(P);
myIsMin[myNbExt] = (NoSol == 0);
myPoint[myNbExt] = Extrema_POnCurv2d(Us, Cu);
myNbExt++;
}
} // if ((Us >= Uinf) && (Us <= Usup))
} // for (int NoSol = 1; ...
myDone = true;
}
//=============================================================================
bool Extrema_ExtPElC2d::IsDone() const
{
return myDone;
}
//=============================================================================
int Extrema_ExtPElC2d::NbExt() const
{
if (!IsDone())
{
throw StdFail_NotDone();
}
return myNbExt;
}
//=============================================================================
double Extrema_ExtPElC2d::SquareDistance(const int N) const
{
if ((N < 1) || (N > NbExt()))
{
throw Standard_OutOfRange();
}
return mySqDist[N - 1];
}
//=============================================================================
bool Extrema_ExtPElC2d::IsMin(const int N) const
{
if ((N < 1) || (N > NbExt()))
{
throw Standard_OutOfRange();
}
return myIsMin[N - 1];
}
//=============================================================================
const Extrema_POnCurv2d& Extrema_ExtPElC2d::Point(const int N) const
{
if ((N < 1) || (N > NbExt()))
{
throw Standard_OutOfRange();
}
return myPoint[N - 1];
}
//=============================================================================