e87ef178c2
- correzione alla distanza punto- curva di bezier.
142 lines
4.3 KiB
C++
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 ;
|
|
}
|