//---------------------------------------------------------------------------- // EgalTech 2017-2017 //---------------------------------------------------------------------------- // File : RemoveCurveSpikes.cpp Data : 02.10.17 Versione : 1.8j1 // Contenuto : Implementazione rimozione spikes di curva. // // // // Modifiche : 02.10.17 DS Creazione modulo. // // //---------------------------------------------------------------------------- //--------------------------- Include ---------------------------------------- #include "stdafx.h" #include "GeoConst.h" #include "CurveComposite.h" #include "DistPointLine.h" #include "RemoveCurveSpikes.h" #include using namespace std ; //---------------------------------------------------------------------------- bool RemoveCurveSpikes( ICurveComposite* pCurve) { // verifico validità curva if ( pCurve == nullptr) return false ; // recupero il numero di curve semplici componenti la composta int nCrvCount = pCurve->GetCurveCount() ; if ( nCrvCount < 2 || ( nCrvCount < 3 && pCurve->IsClosed())) return true ; // ciclo sulle curve elementari della composita int nStart = pCurve->IsClosed() ? 0 : 1 ; for ( int i = nStart ; i < nCrvCount ; ++ i) { // recupero due curve consecutive const ICurve* pPrevCrv = pCurve->GetCurve( ( i > 0 ? i - 1 : nCrvCount - 1)) ; const ICurve* pNextCrv = pCurve->GetCurve( i) ; // se sono entrambe rette if ( pPrevCrv->GetType() == CRV_LINE && pNextCrv->GetType() == CRV_LINE) { // recupero i punti estremi Point3d ptStart ; pPrevCrv->GetStartPoint( ptStart) ; Point3d ptMid ; pPrevCrv->GetEndPoint( ptMid) ; Point3d ptEnd ; pNextCrv->GetEndPoint( ptEnd) ; // recupero le direzioni negli estremi Vector3d vtPrev ; pPrevCrv->GetStartDir( vtPrev) ; Vector3d vtNext ; pNextCrv->GetStartDir( vtNext) ; // verifico se spike double dPrevDist, dNextDist ; if ( vtPrev * vtNext < cos( 175 * DEGTORAD) && (( DistPointLine( ptStart, ptMid, ptEnd).GetDist( dPrevDist) && dPrevDist < EPS_SMALL) || ( DistPointLine( ptEnd, ptStart, ptMid).GetDist( dNextDist) && dNextDist < EPS_SMALL))) { // se spike ha base abbastanza larga, basta togliere uno dei due lati if ( SqDist( ptStart, ptEnd) > SQ_EPS_SMALL) { pCurve->RemoveJoint( i) ; -- nCrvCount ; -- i ; } // altrimenti bisogna togliere entrambi else { pCurve->RemoveJoint( i - 1) ; pCurve->RemoveJoint( i) ; nCrvCount -= 2 ; i = max( i - 2, nStart - 1) ; } } } // !!! Aggiungere la gestione degli altri tipi di curve !!! } return true ; }