//---------------------------------------------------------------------------- // EgalTech 2013-2014 //---------------------------------------------------------------------------- // File : DistPointCrvCompo.cpp Data : 15.01.14 Versione : 1.5a4 // Contenuto : Implementazione della classe distanza punto da curva Composita. // // // // Modifiche : 15.01.14 DS Creazione modulo. // // //---------------------------------------------------------------------------- //--------------------------- Include ---------------------------------------- #include "stdafx.h" #include "DistPointCrvComposite.h" #include "DistPointCrvAux.h" //---------------------------------------------------------------------------- DistPointCrvComposite::DistPointCrvComposite( const Point3d& ptP, const ICurveComposite& CrvCompo) { // distanza non calcolata m_dDist = - 1 ; if ( &CrvCompo == nullptr || ! CrvCompo.IsValid()) return ; // ciclo su ogni curva double dIniCrvPar = 0 ; const ICurve* pCrvSmpl ; pCrvSmpl = CrvCompo.GetFirstCurve() ; while ( pCrvSmpl != nullptr) { // se prima curva if ( m_dDist < 0) { // calcolo distanza minima dal punto alla curva DistPointCurve dstPC( ptP, *pCrvSmpl) ; double dCurrDist ; if ( ! dstPC.GetDist( dCurrDist)) return ; // assegno i risultati m_dDist = dCurrDist ; int i = 0 ; MinDistPCInfo aInfo ; while ( dstPC.GetMinDistInfo( i, aInfo)) { aInfo.dPar += dIniCrvPar ; m_Info.push_back( aInfo) ; ++ i ; } } // altrimenti, per curve successive else { // verifico se la distanza minima dal box è superiore al minimo già trovato BBox3d b3B ; if ( pCrvSmpl->GetLocalBBox( b3B) && b3B.SqDistFromPoint( ptP) <= m_dDist * m_dDist) { // calcolo distanza minima dal punto alla curva DistPointCurve dstPC( ptP, *pCrvSmpl) ; double dCurrDist ; if ( ! dstPC.GetDist( dCurrDist)) return ; // con la stessa minima distanza if ( abs( dCurrDist - m_dDist) < EPS_SMALL) { // aggiungo int i = 0 ; MinDistPCInfo aInfo ; while ( dstPC.GetMinDistInfo( i, aInfo)) { // porto la parametrizzazione da locale a globale aInfo.dPar += dIniCrvPar ; // se il primo nuovo punto coincide con l'ultimo dei precedenti if ( i == 0 && abs( m_Info.back().dPar - aInfo.dPar) < EPS_SMALL && AreSamePointApprox( m_Info.back().ptQ, aInfo.ptQ)) { if ( m_Info.back().nFlag == MDPCI_NORMAL) { // START deve sostituire il vecchio if ( aInfo.nFlag == MDPCI_START_CONT) m_Info.back() = aInfo ; // negli altri casi non devo inserire il nuovo } else if ( m_Info.back().nFlag == MDPCI_END_CONT) { // START fa eliminare il precedente e non va inserito (continua) if ( aInfo.nFlag == MDPCI_START_CONT) m_Info.pop_back() ; // negli altri casi non devo inserire il nuovo } else if ( m_Info.back().nFlag == MDPCI_START_CONT) { // non dovrebbe mai capitare, va rimosso il precedente e inserito il nuovo m_Info.pop_back() ; m_Info.push_back( aInfo) ; } } // altrimenti aggiungo else { if ( dCurrDist < m_dDist) { // aggiorno i minimi m_dDist = dCurrDist ; // inserisco in testa m_Info.insert( m_Info.begin(), aInfo) ; } else { // inserisco in coda m_Info.push_back( aInfo) ; } } // passo al successivo ++ i ; } } // con minima distanza più bassa else if ( dCurrDist < m_dDist) { // aggiorno i minimi m_dDist = dCurrDist ; // il nuovo vettore deve contenere solo quest'ultimo minimo m_Info.clear() ; int i = 0 ; MinDistPCInfo aInfo ; while ( dstPC.GetMinDistInfo( i, aInfo)) { aInfo.dPar += dIniCrvPar ; m_Info.push_back( aInfo) ; ++ i ; } } } } // passo alla successiva ++ dIniCrvPar ; pCrvSmpl = CrvCompo.GetNextCurve() ; } } //---------------------------------------------------------------------------- bool DistPointCrvComposite::GetSqDist( double& dSqDist) const { if ( m_dDist < 0) return false ; dSqDist = m_dDist * m_dDist ; return true ; } //---------------------------------------------------------------------------- bool DistPointCrvComposite::GetDist( double& dDist) const { if ( m_dDist < 0) return false ; dDist = m_dDist ; return true ; } //---------------------------------------------------------------------------- bool DistPointCrvComposite::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 DistPointCrvComposite::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 ; }