//---------------------------------------------------------------------------- // 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 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 ; MDCVECTOR::iterator Iter ; 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 ( 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 ( 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) { if ( m_dDist < 0) return false ; dSqDist = m_dDist * m_dDist ; return true ; } //---------------------------------------------------------------------------- bool DistPointCrvBezier::GetDist( double& dDist) { if ( m_dDist < 0) return false ; dDist = m_dDist ; return true ; } //---------------------------------------------------------------------------- bool DistPointCrvBezier::GetMinDistPoint( int nInd, Point3d& ptMinDist, int& nFlag) { 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) { 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 ; }