Files
EgtGeomKernel/RemoveCurveSpikes.cpp
T
Dario Sassi e60e853816 EgtGeomKernel :
- aggiunta funzione per rimozione spikes da curve
- utilizzo rimozione spikes in creazione regioni
- migliorata gestione linee quasi parallele in intersezione.
2017-10-03 08:21:50 +00:00

74 lines
2.9 KiB
C++

//----------------------------------------------------------------------------
// 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 <algorithm>
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 ;
}