Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6bfb5c619f | |||
| 8be2246249 | |||
| 56cff98cf3 | |||
| 3168bee865 | |||
| 3d2f8c1495 |
+88
-51
@@ -733,6 +733,45 @@ PointsInTolerance( const PNTVECTOR& vRPT, const Point3d& ptP1, const Point3d& pt
|
||||
return true ;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
static bool
|
||||
douglasPeuckerSimplification( const PNTUVECTOR& vPtU, const double dSqTol, const int nIndStart,
|
||||
const int nIndEnd, PNTUVECTOR& vPtU_simple)
|
||||
{
|
||||
// se indici uguali, ritorno
|
||||
if ( nIndStart == nIndEnd)
|
||||
return true ;
|
||||
|
||||
// distanza massima e indice del punto associato
|
||||
double dMaxSqDist = 0. ;
|
||||
int nMaxInd = 0 ;
|
||||
|
||||
// scorro i punti intermedi tra nIndStart e nIndEnd
|
||||
for ( int i = nIndStart + 1 ; i < nIndEnd ; ++ i) {
|
||||
double dCurrSqDist = 0. ;
|
||||
// distanza tra il punto attuale e la retta tra i punti di indici nIndStart ed nIndEnd
|
||||
DistPointLine DPL( vPtU[i].first, vPtU[nIndStart].first, vPtU[nIndEnd].first) ;
|
||||
if ( DPL.GetSqDist( dCurrSqDist) && dCurrSqDist > dMaxSqDist) {
|
||||
// aggiorno i parametri
|
||||
dMaxSqDist = dCurrSqDist ;
|
||||
nMaxInd = i ;
|
||||
}
|
||||
}
|
||||
|
||||
// se la distanza massima trovata è sopra la tolleranza, allora controllo la parte di PolyLine tra
|
||||
// (nIndStart, nMaxInd) e quella tra (nMaxInd, nIndEnd)
|
||||
if ( dMaxSqDist > dSqTol) {
|
||||
// inserisco il punto
|
||||
vPtU_simple.push_back( vPtU[nMaxInd]) ;
|
||||
// split
|
||||
if ( ! douglasPeuckerSimplification( vPtU, dSqTol, nIndStart, nMaxInd, vPtU_simple) ||
|
||||
! douglasPeuckerSimplification( vPtU, dSqTol, nMaxInd, nIndEnd, vPtU_simple))
|
||||
return false ;
|
||||
}
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool
|
||||
PolyLine::RemoveAlignedPoints( double dToler)
|
||||
@@ -743,59 +782,57 @@ PolyLine::RemoveAlignedPoints( double dToler)
|
||||
// controllo minimo valore di tolleranza
|
||||
dToler = max( dToler, LIN_TOL_MIN) ;
|
||||
double dSqTol = dToler * dToler ;
|
||||
// si analizza la distanza di un punto dal segmento che unisce precedente e successivo
|
||||
// punto precedente
|
||||
auto precP = m_lUPoints.begin() ;
|
||||
// punto corrente
|
||||
auto currP = next( precP) ;
|
||||
// punto successivo
|
||||
auto nextP = next( currP) ;
|
||||
// lista dei punti appena rimossi
|
||||
PNTVECTOR vRPT ; vRPT.reserve( 20) ;
|
||||
// mentre esiste un successivo
|
||||
while ( nextP != m_lUPoints.end()) {
|
||||
// distanza del punto corrente dal segmento che unisce gli adiacenti
|
||||
DistPointLine dPL( currP->first, precP->first, nextP->first) ;
|
||||
double dSqDist ;
|
||||
// se da eliminare
|
||||
if ( dPL.GetSqDist( dSqDist) && dSqDist < dSqTol && PointsInTolerance( vRPT, precP->first, nextP->first, dSqTol)) {
|
||||
// aggiungo il punto nella lista dei rimossi
|
||||
vRPT.emplace_back( currP->first) ;
|
||||
// elimino il punto
|
||||
m_lUPoints.erase( currP) ;
|
||||
// avanzo con corrente e successivo
|
||||
currP = nextP ;
|
||||
++ nextP ;
|
||||
}
|
||||
// altrimenti da tenere
|
||||
else {
|
||||
// cancello la lista dei rimossi
|
||||
vRPT.clear() ;
|
||||
// avanzo il terzetto di uno step
|
||||
precP = currP ;
|
||||
currP = nextP ;
|
||||
++ nextP ;
|
||||
}
|
||||
// vettore contenente i punti della polyline
|
||||
PNTUVECTOR vPtU ; vPtU.resize( int( m_lUPoints.size())) ;
|
||||
// interatore primo punto
|
||||
auto ptAct = m_lUPoints.begin() ;
|
||||
for ( int i = 0 ; i < int( m_lUPoints.size()) ; ++ i) {
|
||||
vPtU[i] = *ptAct;
|
||||
ptAct = next( ptAct) ; // incremento iteratore
|
||||
}
|
||||
// se curva chiusa con almeno 4 punti, devo analizzare il terzetto attorno alla chiusura
|
||||
if ( IsClosed() && m_lUPoints.size() >= 4) {
|
||||
// precP e currP sono già corretti
|
||||
// il primo punto ripete l'ultimo (geometricamente coincide con currP)
|
||||
auto firstP = m_lUPoints.begin() ;
|
||||
// questo è il vero successivo
|
||||
nextP = next( firstP) ;
|
||||
// distanza del punto corrente dal segmento che unisce gli adiacenti
|
||||
DistPointLine dPL( currP->first, precP->first, nextP->first) ;
|
||||
double dSqDist ;
|
||||
// se da eliminare
|
||||
if ( dPL.GetSqDist( dSqDist) && dSqDist < dSqTol && PointsInTolerance( vRPT, precP->first, nextP->first, dSqTol)) {
|
||||
// faccio coincidere il primo punto con il precedente
|
||||
firstP->first = precP->first ;
|
||||
// elimino il punto corrente
|
||||
m_lUPoints.erase( currP) ;
|
||||
}
|
||||
|
||||
// vettore indice dei punti semplificati
|
||||
PNTUVECTOR vPtU_simple ;
|
||||
|
||||
// POLYLINE APERTA
|
||||
if ( ! IsClosed()) {
|
||||
// considero tutti i punti della PolyLine
|
||||
vPtU_simple.push_back( vPtU.front()) ;
|
||||
if ( ! douglasPeuckerSimplification( vPtU, dSqTol, 0, int( vPtU.size()) - 1, vPtU_simple))
|
||||
return false ;
|
||||
vPtU_simple.push_back( vPtU.back()) ;
|
||||
}
|
||||
|
||||
// POLYLINE CHIUSA
|
||||
else {
|
||||
// cerco il punto più distante dal primo
|
||||
double dMaxDist = 0. ;
|
||||
int nMaxInd = 0 ;
|
||||
for ( int i = 1 ; i < int( vPtU.size()) ; ++ i) {
|
||||
double dCurrDist = Dist( vPtU[0].first, vPtU[i].first) ;
|
||||
if ( dCurrDist > dMaxDist) {
|
||||
dMaxDist = dCurrDist ;
|
||||
nMaxInd = i ;
|
||||
}
|
||||
}
|
||||
// recupero due PolyLine di approssimazione
|
||||
vPtU_simple.push_back( vPtU.front()) ;
|
||||
if ( ! douglasPeuckerSimplification( vPtU, dSqTol, 0, nMaxInd, vPtU_simple))
|
||||
return false ;
|
||||
vPtU_simple.push_back( vPtU[ nMaxInd]) ;
|
||||
if ( ! douglasPeuckerSimplification( vPtU, dSqTol, nMaxInd, int( vPtU.size()) - 1, vPtU_simple))
|
||||
return false ;
|
||||
vPtU_simple.push_back( vPtU.back()) ;
|
||||
}
|
||||
|
||||
// ordino
|
||||
sort( vPtU_simple.begin(), vPtU_simple.end(),
|
||||
[]( const POINTU& a , const POINTU& b) { return ( a.second < b.second) ; }) ;
|
||||
|
||||
// pulisco e aggiungo i parametri ricavati
|
||||
m_lUPoints.clear() ;
|
||||
for ( int i = 0 ; i < int( vPtU_simple.size()) ; ++ i)
|
||||
m_lUPoints.push_back( vPtU_simple[i]) ;
|
||||
|
||||
return true ;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user