Files
EgtGeomKernel/DistPointCrvBezier.cpp
Daniele Bariletti e87ef178c2 EgtGeomKernel :
- correzione alla distanza punto- curva di bezier.
2026-02-10 15:42:03 +01:00

142 lines
4.3 KiB
C++

//----------------------------------------------------------------------------
// EgalTech 2013-2014
//----------------------------------------------------------------------------
// File : DistPointCrvBezier.cpp Data : 02.01.14 Versione : 1.5a1
// Contenuto : Implementazione della classe distanza punto da curva di Bezier.
//
//
//
// Modifiche : 02.01.14 DS Creazione modulo.
//
//
//----------------------------------------------------------------------------
//--------------------------- Include ----------------------------------------
#include "stdafx.h"
#include "DistPointCrvBezier.h"
#include "DistPointCrvAux.h"
#include "GeoConst.h"
#include <algorithm>
using namespace std ;
//----------------------------------------------------------------------------
DistPointCrvBezier::DistPointCrvBezier( const Point3d& ptP, const ICurveBezier& CrvBez)
{
// distanza non calcolata
m_dDist = - 1 ;
if ( ! CrvBez.IsValid())
return ;
// determino tolleranza di approssimazione in base a ingombro curva
BBox3d b3Crv ;
CrvBez.GetLocalBBox( b3Crv, BBF_STANDARD) ;
double dRad = INFINITO ;
b3Crv.GetRadius( dRad) ;
const double FRAZ = 0.2 ;
double dLinTol = ( ( FRAZ * dRad > LIN_TOL_APPROX) ? LIN_TOL_APPROX : FRAZ * dRad) ;
// creo una polilinea di approssimazione
PolyLine PL ;
if ( ! CrvBez.ApproxWithLines( dLinTol, ANG_TOL_APPROX_DEG, ICurve::APL_STD, PL))
return ;
int nDeg = CrvBez.GetDegree() ;
if ( PL.GetPointNbr() < nDeg + 1) {
// costruisco una polilinea con un numero di curve scelto in base al grado della curva
PL.Clear() ;
for ( int i = 0 ; i <= nDeg + 1 ; ++i) {
double dU = double(i) / (nDeg + 1) ;
Point3d ptBez ;
CrvBez.GetPointD1D2( dU, ICurve::Side::FROM_MINUS, ptBez) ;
PL.AddUPoint( dU, ptBez) ;
}
}
// cerco la minima distanza per la polilinea
MDCVECTOR vApproxMin ;
if ( ! CalcMinDistPointPolyLine( ptP, PL, dLinTol, vApproxMin))
return ;
// verifico presenza singolarità agli estremi degli intervalli trovati
double dSingP ;
if ( CrvBez.GetSingularParam( dSingP) == 0)
dSingP = - 1 ;
for ( auto Iter = vApproxMin.begin() ; Iter != vApproxMin.end() ; ++Iter) {
// imposto flag per singolarità agli estremi
(*Iter).bParMinSing = abs( (*Iter).dParMin - dSingP) < EPS_SMALL ;
(*Iter).bParMaxSing = abs( (*Iter).dParMax - dSingP) < EPS_SMALL ;
}
// raffino i punti trovati
double dPolishedPar ;
Point3d ptPolishedQ ;
for ( auto Iter = vApproxMin.begin() ; Iter != vApproxMin.end() ; ++Iter) {
// eseguo raffinamento
if ( PolishMinDistPointCurve( ptP, CrvBez, *Iter, dPolishedPar, ptPolishedQ)) {
(*Iter).dDist = Dist( ptP, ptPolishedQ) ;
(*Iter).dPar = dPolishedPar ;
(*Iter).ptQ = ptPolishedQ ;
}
else
(*Iter).dDist = INFINITO ;
}
// determino i minimi raffinati da tenere
double dMinDist ;
if ( FilterMinDistPointCurve( ptP, CrvBez, vApproxMin, dMinDist, m_Info))
m_dDist = dMinDist ;
}
//----------------------------------------------------------------------------
bool
DistPointCrvBezier::GetSqDist( double& dSqDist) const
{
if ( m_dDist < 0)
return false ;
dSqDist = m_dDist * m_dDist ;
return true ;
}
//----------------------------------------------------------------------------
bool
DistPointCrvBezier::GetDist( double& dDist) const
{
if ( m_dDist < 0)
return false ;
dDist = m_dDist ;
return true ;
}
//----------------------------------------------------------------------------
bool
DistPointCrvBezier::GetMinDistPoint( int nInd, Point3d& ptMinDist, int& nFlag) const
{
if ( m_dDist < 0)
return false ;
if ( nInd < 0 || nInd >= (int) m_Info.size())
return false ;
ptMinDist = m_Info[nInd].ptQ ;
nFlag = m_Info[nInd].nFlag ;
return true ;
}
//----------------------------------------------------------------------------
bool
DistPointCrvBezier::GetParamAtMinDistPoint( int nInd, double& dParam, int& nFlag) const
{
if ( m_dDist < 0)
return false ;
if ( nInd < 0 || nInd >= (int) m_Info.size())
return false ;
dParam = m_Info[nInd].dPar ;
nFlag = m_Info[nInd].nFlag ;
return true ;
}