EgtGeomKernel 1.9l3 :

- modifiche a ApproxWithArcsEx di CurveComposite per eliminare le parti allineate in tolleranza
- migliorate RemoveAlignedPoints di PolyLine e PolyArc
- migliorata GetSurfFlatRegionFromFatCurve.
This commit is contained in:
Dario Sassi
2018-12-19 08:45:59 +00:00
parent 92e3cc70a4
commit a149384fbb
6 changed files with 126 additions and 17 deletions
+89 -1
View File
@@ -13,9 +13,13 @@
//--------------------------- Include ----------------------------------------
#include "stdafx.h"
#include "DistPointLine.h"
#include "GeoConst.h"
#include "/EgtDev/Include/EGkPolyArc.h"
#include "/EgtDev/Include/EGkFrame3d.h"
#include <algorithm>
using namespace std ;
//----------------------------------------------------------------------------
PolyArc::PolyArc( void)
@@ -508,4 +512,88 @@ PolyArc::Invert( bool bInvertU)
}
}
return true ;
}
}
//----------------------------------------------------------------------------
static bool
PointsInTolerance( const PNTVECTOR& vRPT, const Point3d& ptP1, const Point3d& ptP2, double dSqTol)
{
for ( const auto& ptQ : vRPT) {
double dSqDist ;
if ( ! DistPointLine( ptQ, ptP1, ptP2).GetSqDist( dSqDist) || dSqDist > dSqTol)
return false ;
}
return true ;
}
//----------------------------------------------------------------------------
bool
PolyArc::RemoveAlignedPoints( double dToler)
{
// se non ci sono almeno 3 punti, esco subito
if ( m_lUPointBs.size() < 3)
return true ;
// 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_lUPointBs.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_lUPointBs.end()) {
double dSqDist = 2 * dSqTol ;
// se precedente e corrente non hanno bulge (non sono archi i due tratti)
if ( abs( precP->dB) < EPS_SMALL && abs( currP->dB) < EPS_SMALL) {
// distanza del punto corrente dal segmento che unisce gli adiacenti
DistPointLine( currP->ptP, precP->ptP, nextP->ptP).GetSqDist( dSqDist) ;
}
// se da eliminare e gli altri eliminati stanno nella tolleranza
if ( dSqDist < dSqTol && PointsInTolerance( vRPT, precP->ptP, nextP->ptP, dSqTol)) {
// aggiungo il punto nella lista dei rimossi
vRPT.emplace_back( currP->ptP) ;
// elimino il punto
m_lUPointBs.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 ;
}
}
// se curva chiusa con almeno 4 punti, devo analizzare il terzetto attorno alla chiusura
if ( IsClosed() && m_lUPointBs.size() >= 4) {
// precP e currP sono già corretti
// il primo punto ripete l'ultimo (geometricamente coincide con currP)
auto firstP = m_lUPointBs.begin() ;
// questo è il vero successivo
nextP = next( firstP) ;
double dSqDist = 2 * dSqTol ;
// se precedente e corrente non hanno bulge (non sono archi i due tratti)
if ( abs( precP->dB) < EPS_SMALL && abs( firstP->dB) < EPS_SMALL) {
// distanza del punto corrente dal segmento che unisce gli adiacenti
DistPointLine( currP->ptP, precP->ptP, nextP->ptP).GetSqDist( dSqDist) ;
}
// se da eliminare
if ( dSqDist < dSqTol && PointsInTolerance( vRPT, precP->ptP, nextP->ptP, dSqTol)) {
// faccio coincidere il primo punto con il precedente
firstP->ptP = precP->ptP ;
// elimino il punto corrente
m_lUPointBs.erase( currP) ;
}
}
return true ;
}