EgtGeomKernel 1.6t3 :
- migliorata velocità di esecuzione di FindNearest di PointGrid3d per ChainCurves - a PolyLine aggiunte GetConvexHullXY e GetMinAreaRectangleXY.
This commit is contained in:
+91
-60
@@ -27,11 +27,11 @@ struct IBox {
|
||||
int nYmin, nYmax ;
|
||||
int nZmin, nZmax ;
|
||||
IBox( void) : nXmin( INT_MAX), nXmax( INT_MIN),
|
||||
nYmin( INT_MAX), nYmax( INT_MIN),
|
||||
nZmin( INT_MAX), nZmax( INT_MIN) {}
|
||||
nYmin( INT_MAX), nYmax( INT_MIN),
|
||||
nZmin( INT_MAX), nZmax( INT_MIN) {}
|
||||
void Reset( void)
|
||||
{ nXmin = nYmin = nZmin = INT_MAX ;
|
||||
nXmax = nYmax = nZmax = INT_MIN ; }
|
||||
nXmax = nYmax = nZmax = INT_MIN ; }
|
||||
bool Encloses( int nX, int nY, int nZ)
|
||||
{ return ( nX >= nXmin && nX <= nXmax &&
|
||||
nY >= nYmin && nY <= nYmax &&
|
||||
@@ -255,72 +255,103 @@ bool
|
||||
PointGrid3d::FindNearest( const Point3d& ptTest, INTVECTOR& vnIds)
|
||||
{
|
||||
const double NEAR_TOL = 100 * EPS_SMALL ;
|
||||
const int SIZE_LIMIT = 1000 ;
|
||||
// pulisco il risultato
|
||||
vnIds.clear() ;
|
||||
// raggio di ricerca
|
||||
double dRad = max( m_BBox.DistFromPoint( ptTest), NEAR_TOL) ;
|
||||
// delta di incremento per raggio di ricerca
|
||||
const int N_CELL = 10 ;
|
||||
double dDelta = N_CELL * m_dCellDim ;
|
||||
// massimo numero di step di ricerca basato su raggio box di ingombro
|
||||
double dBoxRad ;
|
||||
if ( ! m_BBox.GetRadius( dBoxRad))
|
||||
return false ;
|
||||
int nMaxSteps = int( 2 * ceil( dBoxRad / dDelta)) ;
|
||||
nMaxSteps = max( nMaxSteps, 1) ;
|
||||
// ciclo di ricerca con raggio crescente
|
||||
IBox iBoxPrev ;
|
||||
IBox ibR[N_SUBIBOX] ;
|
||||
bool bFound = false ;
|
||||
double dMinDist ;
|
||||
double dSqMinDist ;
|
||||
for ( int m = 0 ; m <= nMaxSteps ; ++ m) {
|
||||
// determino il range di celle sui tre assi
|
||||
IBox iBox ;
|
||||
if ( ! Get3dRangeNbr( ptTest, dRad, iBox))
|
||||
continue ;
|
||||
// tolgo il range precedente
|
||||
SubtractIBox( iBox, iBoxPrev, ibR) ;
|
||||
// ciclo su tutte le celle dei range rimanenti
|
||||
for ( int l = 0 ; l < N_SUBIBOX ; ++ l) {
|
||||
for ( int i = ibR[l].nXmin ; i <= ibR[l].nXmax ; ++ i) {
|
||||
for ( int j = ibR[l].nYmin ; j <= ibR[l].nYmax ; ++ j) {
|
||||
for ( int k = ibR[l].nZmin ; k <= ibR[l].nZmax ; ++ k) {
|
||||
// ciclo sui punti della cella
|
||||
IPNTI_UMMAP_CRANGE MMrange = m_MMap.equal_range( PointHash( i, j, k)) ;
|
||||
for ( ; MMrange.first != MMrange.second ; ++ MMrange.first) {
|
||||
// se distanza inferiore al minimo, aggiorno...
|
||||
double dSqDist = SqDist( (*MMrange.first).second.first, ptTest) ;
|
||||
// altro punto con la stessa minima distanza già trovata
|
||||
if ( bFound && fabs( dSqDist - dSqMinDist) < 2 * dMinDist * NEAR_TOL + NEAR_TOL * NEAR_TOL) {
|
||||
// inserisco il punto nel vettore dei risultati
|
||||
vnIds.push_back( (*MMrange.first).second.second) ;
|
||||
}
|
||||
// primo punto o punto con minima distanza più bassa
|
||||
else if ( ! bFound || dSqDist < dSqMinDist) {
|
||||
bFound = true ;
|
||||
// aggiorno i minimi
|
||||
dSqMinDist = dSqDist ;
|
||||
dMinDist = sqrt( dSqMinDist) ;
|
||||
// pulisco il vettore dei risultati ed inserisco questo
|
||||
vnIds.clear() ;
|
||||
vnIds.push_back( (*MMrange.first).second.second) ;
|
||||
// se ci sono pochi elementi, eseguo direttamente la ricerca sugli stessi
|
||||
if ( m_MMap.size() < SIZE_LIMIT) {
|
||||
// ciclo di ricerca sugli elementi
|
||||
bool bFound = false ;
|
||||
double dMinDist ;
|
||||
double dSqMinDist ;
|
||||
for each ( const auto& PntI in m_MMap) {
|
||||
// quadrato della distanza
|
||||
double dSqDist = SqDist( ptTest, PntI.second.first) ;
|
||||
// altro punto con la stessa minima distanza già trovata
|
||||
if ( bFound && fabs( dSqDist - dSqMinDist) < 2 * dMinDist * NEAR_TOL + NEAR_TOL * NEAR_TOL) {
|
||||
// inserisco il punto nel vettore dei risultati
|
||||
vnIds.push_back( PntI.second.second) ;
|
||||
}
|
||||
// primo punto o punto con minima distanza più bassa
|
||||
else if ( ! bFound || dSqDist < dSqMinDist) {
|
||||
bFound = true ;
|
||||
// aggiorno i minimi
|
||||
dSqMinDist = dSqDist ;
|
||||
dMinDist = sqrt( dSqMinDist) ;
|
||||
// pulisco il vettore dei risultati ed inserisco questo
|
||||
vnIds.clear() ;
|
||||
vnIds.push_back( PntI.second.second) ;
|
||||
}
|
||||
}
|
||||
return bFound ;
|
||||
}
|
||||
// altrimenti, verifico cerchi concentrici di celle
|
||||
else {
|
||||
// raggio di ricerca
|
||||
double dRad = max( m_BBox.DistFromPoint( ptTest), NEAR_TOL) ;
|
||||
// delta di incremento per raggio di ricerca
|
||||
const int N_CELL = 10 ;
|
||||
double dDelta = N_CELL * m_dCellDim ;
|
||||
// massimo numero di step di ricerca basato su raggio box di ingombro
|
||||
double dBoxRad ;
|
||||
if ( ! m_BBox.GetRadius( dBoxRad))
|
||||
return false ;
|
||||
int nMaxSteps = int( 2 * ceil( dBoxRad / dDelta)) ;
|
||||
nMaxSteps = max( nMaxSteps, 1) ;
|
||||
// ciclo di ricerca con raggio crescente
|
||||
IBox iBoxPrev ;
|
||||
IBox ibR[N_SUBIBOX] ;
|
||||
bool bFound = false ;
|
||||
double dMinDist ;
|
||||
double dSqMinDist ;
|
||||
for ( int m = 0 ; m <= nMaxSteps ; ++ m) {
|
||||
// determino il range di celle sui tre assi
|
||||
IBox iBox ;
|
||||
if ( ! Get3dRangeNbr( ptTest, dRad, iBox))
|
||||
continue ;
|
||||
// tolgo il range precedente
|
||||
SubtractIBox( iBox, iBoxPrev, ibR) ;
|
||||
// ciclo su tutte le celle dei range rimanenti
|
||||
for ( int l = 0 ; l < N_SUBIBOX ; ++ l) {
|
||||
for ( int i = ibR[l].nXmin ; i <= ibR[l].nXmax ; ++ i) {
|
||||
for ( int j = ibR[l].nYmin ; j <= ibR[l].nYmax ; ++ j) {
|
||||
for ( int k = ibR[l].nZmin ; k <= ibR[l].nZmax ; ++ k) {
|
||||
// ciclo sui punti della cella
|
||||
IPNTI_UMMAP_CRANGE MMrange = m_MMap.equal_range( PointHash( i, j, k)) ;
|
||||
for ( ; MMrange.first != MMrange.second ; ++ MMrange.first) {
|
||||
// se distanza inferiore al minimo, aggiorno...
|
||||
double dSqDist = SqDist( (*MMrange.first).second.first, ptTest) ;
|
||||
// altro punto con la stessa minima distanza già trovata
|
||||
if ( bFound && fabs( dSqDist - dSqMinDist) < 2 * dMinDist * NEAR_TOL + NEAR_TOL * NEAR_TOL) {
|
||||
// inserisco il punto nel vettore dei risultati
|
||||
vnIds.push_back( (*MMrange.first).second.second) ;
|
||||
}
|
||||
// primo punto o punto con minima distanza più bassa
|
||||
else if ( ! bFound || dSqDist < dSqMinDist) {
|
||||
bFound = true ;
|
||||
// aggiorno i minimi
|
||||
dSqMinDist = dSqDist ;
|
||||
dMinDist = sqrt( dSqMinDist) ;
|
||||
// pulisco il vettore dei risultati ed inserisco questo
|
||||
vnIds.clear() ;
|
||||
vnIds.push_back( (*MMrange.first).second.second) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// se trovato, inutile continuare perchè ci si allontanerà
|
||||
if ( bFound)
|
||||
return true ;
|
||||
// incremento il raggio di ricerca
|
||||
dRad += dDelta ;
|
||||
// salvo box di precedente ricerca
|
||||
iBoxPrev = iBox ;
|
||||
}
|
||||
// se trovato, inutile continuare perchè ci si allontanerà
|
||||
if ( bFound)
|
||||
return true ;
|
||||
// incremento il raggio di ricerca
|
||||
dRad += dDelta ;
|
||||
// salvo box di precedente ricerca
|
||||
iBoxPrev = iBox ;
|
||||
}
|
||||
|
||||
return bFound ;
|
||||
return bFound ;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user