Files
EgtGeomKernel/DistPointCrvBezier.cpp
T
Dario Sassi 650540e573 EgtGeomKernel :
- semplificata e ottimizzata creazione di superficie trimesh box standard
- miglioramenti sintattici vari.
2023-12-29 12:55:24 +01:00

131 lines
3.9 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 == nullptr || ! 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 ;
// 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 ;
}