1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-21 10:13:43 +03:00
occt/src/GeomAPI/GeomAPI_ExtremaCurveCurve.cxx
2012-03-05 19:23:40 +04:00

497 lines
12 KiB
C++
Executable File

// File: GeomAPI_ExtremaCurveCurve.cxx
// Created: Fri Mar 18 14:54:40 1994
// Author: Bruno DUMORTIER
// <dub@fuegox>
#include <GeomAPI_ExtremaCurveCurve.ixx>
#include <GeomAdaptor_Curve.hxx>
//#include <Extrema_POnCurv.hxx>
#include <Precision.hxx>
#include <GeomAPI_ProjectPointOnCurve.hxx>
//=======================================================================
//function : GeomAPI_ExtremaCurveCurve
//purpose :
//=======================================================================
GeomAPI_ExtremaCurveCurve::GeomAPI_ExtremaCurveCurve()
{
myIsDone = Standard_False;
myTotalExt = Standard_False;
}
//=======================================================================
//function : GeomAPI_ExtremaCurveCurve
//purpose :
//=======================================================================
GeomAPI_ExtremaCurveCurve::GeomAPI_ExtremaCurveCurve
(const Handle(Geom_Curve)& C1,
const Handle(Geom_Curve)& C2)
{
Init(C1,C2);
}
//=======================================================================
//function : GeomAPI_ExtremaCurveCurve
//purpose :
//=======================================================================
GeomAPI_ExtremaCurveCurve::GeomAPI_ExtremaCurveCurve
(const Handle(Geom_Curve)& C1,
const Handle(Geom_Curve)& C2,
const Standard_Real U1min,
const Standard_Real U1max,
const Standard_Real U2min,
const Standard_Real U2max)
{
Init(C1,C2,U1min,U1max,U2min,U2max);
}
//=======================================================================
//function : Init
//purpose :
//=======================================================================
void GeomAPI_ExtremaCurveCurve::Init
(const Handle(Geom_Curve)& C1,
const Handle(Geom_Curve)& C2)
{
myTotalExt = Standard_False;
Standard_Real Tol = Precision::PConfusion();
myC1.Load(C1);
myC2.Load(C2);
Extrema_ExtCC theExtCC(myC1, myC2, Tol,Tol);
myExtCC = theExtCC;
myIsDone = myExtCC.IsDone() && ( myExtCC.NbExt() > 0);
if ( myIsDone) {
// evaluate the lower distance and its index;
Standard_Real Dist2, Dist2Min = myExtCC.SquareDistance(1);
myIndex = 1;
for ( Standard_Integer i = 2; i <= myExtCC.NbExt(); i++) {
Dist2 = myExtCC.SquareDistance(i);
if ( Dist2 < Dist2Min) {
Dist2Min = Dist2;
myIndex = i;
}
}
}
}
//=======================================================================
//function : Init
//purpose :
//=======================================================================
void GeomAPI_ExtremaCurveCurve::Init
(const Handle(Geom_Curve)& C1,
const Handle(Geom_Curve)& C2,
const Standard_Real U1min,
const Standard_Real U1max,
const Standard_Real U2min,
const Standard_Real U2max)
{
myTotalExt = Standard_False;
Standard_Real Tol = Precision::PConfusion();
myC1.Load(C1);
myC2.Load(C2);
Extrema_ExtCC theExtCC(myC1,myC2,U1min,U1max,U2min,U2max,Tol,Tol);
myExtCC = theExtCC;
myIsDone = myExtCC.IsDone() && ( myExtCC.NbExt() > 0 );
if ( myIsDone) {
// evaluate the lower distance and its index;
Standard_Real Dist2, Dist2Min = myExtCC.SquareDistance(1);
myIndex = 1;
for ( Standard_Integer i = 2; i <= myExtCC.NbExt(); i++) {
Dist2 = myExtCC.SquareDistance(i);
if ( Dist2 < Dist2Min) {
Dist2Min = Dist2;
myIndex = i;
}
}
}
}
//=======================================================================
//function : NbExtrema
//purpose :
//=======================================================================
Standard_Integer GeomAPI_ExtremaCurveCurve::NbExtrema() const
{
if ( myIsDone)
return myExtCC.NbExt();
else
return 0;
}
//=======================================================================
//function : Points
//purpose :
//=======================================================================
void GeomAPI_ExtremaCurveCurve::Points
(const Standard_Integer Index,
gp_Pnt& P1,
gp_Pnt& P2) const
{
Standard_OutOfRange_Raise_if( Index < 1 || Index > NbExtrema(),
"GeomAPI_ExtremaCurveCurve::Points");
Extrema_POnCurv PC1, PC2;
myExtCC.Points(Index,PC1,PC2);
P1 = PC1.Value();
P2 = PC2.Value();
}
//=======================================================================
//function : Parameters
//purpose :
//=======================================================================
void GeomAPI_ExtremaCurveCurve::Parameters
(const Standard_Integer Index,
Standard_Real& U1,
Standard_Real& U2) const
{
Standard_OutOfRange_Raise_if( Index < 1 || Index > NbExtrema(),
"GeomAPI_ExtremaCurveCurve::Parameters");
Extrema_POnCurv PC1, PC2;
myExtCC.Points(Index,PC1,PC2);
U1 = PC1.Parameter();
U2 = PC2.Parameter();
}
//=======================================================================
//function : Distance
//purpose :
//=======================================================================
Standard_Real GeomAPI_ExtremaCurveCurve::Distance
(const Standard_Integer Index) const
{
Standard_OutOfRange_Raise_if( Index < 1 || Index > NbExtrema(),
"GeomAPI_ExtremaCurveCurve::Distance");
return sqrt (myExtCC.SquareDistance(Index));
}
//=======================================================================
//function : NearestPoints
//purpose :
//=======================================================================
void GeomAPI_ExtremaCurveCurve::NearestPoints(gp_Pnt& P1, gp_Pnt& P2) const
{
StdFail_NotDone_Raise_if
(!myIsDone, "GeomAPI_ExtremaCurveCurve::NearestPoints");
Points(myIndex,P1,P2);
}
//=======================================================================
//function : LowerDistanceParameters
//purpose :
//=======================================================================
void GeomAPI_ExtremaCurveCurve::LowerDistanceParameters
(Standard_Real& U1,
Standard_Real& U2) const
{
StdFail_NotDone_Raise_if
(!myIsDone, "GeomAPI_ExtremaCurveCurve::LowerDistanceParameters");
Parameters(myIndex,U1,U2);
}
//=======================================================================
//function : LowerDistance
//purpose :
//=======================================================================
Standard_Real GeomAPI_ExtremaCurveCurve::LowerDistance() const
{
StdFail_NotDone_Raise_if
(!myIsDone, "GeomAPI_ExtremaCurveCurve::LowerDistance");
return sqrt (myExtCC.SquareDistance(myIndex));
}
//=======================================================================
//function : Standard_Real
//purpose :
//=======================================================================
GeomAPI_ExtremaCurveCurve::operator Standard_Real() const
{
return LowerDistance();
}
//=======================================================================
//function : Standard_Integer
//purpose :
//=======================================================================
GeomAPI_ExtremaCurveCurve::operator Standard_Integer() const
{
return myExtCC.NbExt();
}
Standard_Boolean GeomAPI_ExtremaCurveCurve::TotalNearestPoints(gp_Pnt& P1,gp_Pnt& P2)
{
if(!myTotalExt) {
TotalPerform();
myTotalExt = Standard_True;
}
if(myIsInfinite) return Standard_False;
P1 = myTotalPoints[0];
P2 = myTotalPoints[1];
return Standard_True;
}
Standard_Boolean GeomAPI_ExtremaCurveCurve::TotalLowerDistanceParameters(Quantity_Parameter& U1,
Quantity_Parameter& U2)
{
if(!myTotalExt) {
TotalPerform();
myTotalExt = Standard_True;
}
if(myIsInfinite) return Standard_False;
U1 = myTotalPars[0];
U2 = myTotalPars[1];
return Standard_True;
}
Quantity_Length GeomAPI_ExtremaCurveCurve::TotalLowerDistance()
{
if(!myTotalExt) {
TotalPerform();
myTotalExt = Standard_True;
}
return myTotalDist;
}
void GeomAPI_ExtremaCurveCurve::TotalPerform()
{
// StdFail_NotDone_Raise_if
// (!myExtCC.IsDone(), "GeomAPI_ExtremaCurveCurve::TotalPerform");
Standard_Real u11 = myC1.FirstParameter();
Standard_Real u12 = myC1.LastParameter();
Standard_Real u21 = myC2.FirstParameter();
Standard_Real u22 = myC2.LastParameter();
Standard_Boolean infinite = Precision::IsInfinite(u11) &&
Precision::IsInfinite(u12) &&
Precision::IsInfinite(u21) &&
Precision::IsInfinite(u22);
myIsInfinite = Standard_False;
if(infinite && myExtCC.IsParallel()) {
myIsInfinite = Standard_True;
//calculate distance between any suitable point on C1 and C2
gp_Pnt PonC1 = myC1.Value(0.);
GeomAPI_ProjectPointOnCurve proj(PonC1, myC2.Curve());
myTotalDist = proj.LowerDistance();
return;
}
myTotalDist = RealLast();
if(myIsDone && !myExtCC.IsParallel()) {
Points(myIndex, myTotalPoints[0], myTotalPoints[1]);
Parameters(myIndex, myTotalPars[0], myTotalPars[1]);
myTotalDist = sqrt (myExtCC.SquareDistance(myIndex));
if(myTotalDist <= Precision::Confusion()) return;
}
gp_Pnt P11, P12, P21, P22;
Standard_Real d11, d12, d21, d22;
myExtCC.TrimmedSquareDistances(d11, d12, d21, d22, P11, P12, P21, P22);
Standard_Real aTotalDist2 = myTotalDist * myTotalDist;
if(aTotalDist2 > d11) {
myTotalDist = sqrt (d11);
myTotalPoints[0] = P11;
myTotalPoints[1] = P21;
myTotalPars[0] = u11;
myTotalPars[1] = u21;
if(myTotalDist <= Precision::Confusion()) return;
}
if(aTotalDist2 > d12) {
myTotalDist = sqrt (d12);
myTotalPoints[0] = P11;
myTotalPoints[1] = P22;
myTotalPars[0] = u11;
myTotalPars[1] = u22;
if(myTotalDist <= Precision::Confusion()) return;
}
if(aTotalDist2 > d21) {
myTotalDist = sqrt (d21);
myTotalPoints[0] = P12;
myTotalPoints[1] = P21;
myTotalPars[0] = u12;
myTotalPars[1] = u21;
if(myTotalDist <= Precision::Confusion()) return;
}
if(aTotalDist2 > d22) {
myTotalDist = sqrt (d22);
myTotalPoints[0] = P12;
myTotalPoints[1] = P22;
myTotalPars[0] = u12;
myTotalPars[1] = u22;
if(myTotalDist <= Precision::Confusion()) return;
}
// calculate distances between extremities one curve and other curve
if(!Precision::IsInfinite(u11)) {
GeomAPI_ProjectPointOnCurve proj(P11, myC2.Curve(), u21, u22);
if(proj.NbPoints() > 0) {
Standard_Real dmin = proj.LowerDistance();
if(myTotalDist > dmin) {
myTotalDist = dmin;
myTotalPoints[0] = P11;
myTotalPars[0] = u11;
myTotalPoints[1] = proj.NearestPoint();
myTotalPars[1] = proj.LowerDistanceParameter();
if(myTotalDist <= Precision::Confusion()) return;
}
}
}
if(!Precision::IsInfinite(u12)) {
GeomAPI_ProjectPointOnCurve proj(P12, myC2.Curve(), u21, u22);
if(proj.NbPoints() > 0) {
Standard_Real dmin = proj.LowerDistance();
if(myTotalDist > dmin) {
myTotalDist = dmin;
myTotalPoints[0] = P12;
myTotalPars[0] = u12;
myTotalPoints[1] = proj.NearestPoint();
myTotalPars[1] = proj.LowerDistanceParameter();
if(myTotalDist <= Precision::Confusion()) return;
}
}
}
if(!Precision::IsInfinite(u21)) {
GeomAPI_ProjectPointOnCurve proj(P21, myC1.Curve(), u11, u12);
if(proj.NbPoints() > 0) {
Standard_Real dmin = proj.LowerDistance();
if(myTotalDist > dmin) {
myTotalDist = dmin;
myTotalPoints[0] = proj.NearestPoint();
myTotalPars[0] = proj.LowerDistanceParameter();
myTotalPoints[1] = P21;
myTotalPars[1] = u21;
if(myTotalDist <= Precision::Confusion()) return;
}
}
}
if(!Precision::IsInfinite(u22)) {
GeomAPI_ProjectPointOnCurve proj(P22, myC1.Curve(), u11, u12);
if(proj.NbPoints() > 0) {
Standard_Real dmin = proj.LowerDistance();
if(myTotalDist > dmin) {
myTotalDist = dmin;
myTotalPoints[0] = proj.NearestPoint();
myTotalPars[0] = proj.LowerDistanceParameter();
myTotalPoints[1] = P22;
myTotalPars[1] = u22;
}
}
}
}