EgtGeomKernel 2.5e3 :

- a BBox3d aggiunto 2° metodo Overlaps con box aventi diverso orientamento
- nelle funzioni di Collision Detection migliorato controllo non interne
- nele funzioni Avoid di Zmap si utilizza confronto box con diverso orientamento.
This commit is contained in:
DarioS
2023-05-14 11:58:48 +02:00
parent 7023d721f4
commit 2d8c815032
12 changed files with 341 additions and 231 deletions
+101 -29
View File
@@ -447,69 +447,141 @@ BBox3d::EnclosesXY( const BBox3d& b3Box) const
//----------------------------------------------------------------------------
bool
BBox3d::Overlaps( const BBox3d& b3B) const
BBox3d::Overlaps( const BBox3d& b3Box) const
{
if ( m_ptMax.x < b3B.m_ptMin.x - EPS_SMALL || m_ptMin.x > b3B.m_ptMax.x + EPS_SMALL)
if ( m_ptMax.x < b3Box.m_ptMin.x - EPS_SMALL || m_ptMin.x > b3Box.m_ptMax.x + EPS_SMALL)
return false ;
if ( m_ptMax.y < b3B.m_ptMin.y - EPS_SMALL || m_ptMin.y > b3B.m_ptMax.y + EPS_SMALL)
if ( m_ptMax.y < b3Box.m_ptMin.y - EPS_SMALL || m_ptMin.y > b3Box.m_ptMax.y + EPS_SMALL)
return false ;
if ( m_ptMax.z < b3B.m_ptMin.z - EPS_SMALL || m_ptMin.z > b3B.m_ptMax.z + EPS_SMALL)
if ( m_ptMax.z < b3Box.m_ptMin.z - EPS_SMALL || m_ptMin.z > b3Box.m_ptMax.z + EPS_SMALL)
return false ;
return true ;
}
//----------------------------------------------------------------------------
bool
BBox3d::OverlapsXY( const BBox3d& b3B) const
BBox3d::OverlapsXY( const BBox3d& b3Box) const
{
if ( m_ptMax.x < b3B.m_ptMin.x - EPS_SMALL || m_ptMin.x > b3B.m_ptMax.x + EPS_SMALL)
if ( m_ptMax.x < b3Box.m_ptMin.x - EPS_SMALL || m_ptMin.x > b3Box.m_ptMax.x + EPS_SMALL)
return false ;
if ( m_ptMax.y < b3B.m_ptMin.y - EPS_SMALL || m_ptMin.y > b3B.m_ptMax.y + EPS_SMALL)
if ( m_ptMax.y < b3Box.m_ptMin.y - EPS_SMALL || m_ptMin.y > b3Box.m_ptMax.y + EPS_SMALL)
return false ;
return true ;
}
//----------------------------------------------------------------------------
bool
BBox3d::FindIntersection( const BBox3d& b3B, BBox3d& b3Int) const
inline bool
TestSeparatingAxis( const Vector3d& vtAx, const Vector3d& vtDiff, const Vector3d& vtHe,
const Vector3d& vtHe2X, const Vector3d& vtHe2Y, const Vector3d& vtHe2Z)
{
if ( ! IsValid() || ! b3B.IsValid())
if ( vtAx.IsSmall())
return false ;
double dLen = ( vtAx.IsNormalized() ? 1 : vtAx.Len()) ;
return ( abs( vtDiff * vtAx) >
abs( vtHe.x * vtAx.x) + abs( vtHe.y * vtAx.y) + abs( vtHe.z * vtAx.z) +
abs( vtHe2X * vtAx) + abs( vtHe2Y * vtAx) + abs( vtHe2Z * vtAx) + EPS_SMALL * dLen) ;
}
//----------------------------------------------------------------------------
bool
BBox3d::Overlaps( const Frame3d& frBox, const BBox3d& b3Box) const
{
// Verifico validità di entrambi i box
if ( ! IsValid() || ! b3Box.IsValid())
return false ;
// Centro e semiampiezza del box
Point3d ptCen = ( m_ptMin + m_ptMax) / 2 ;
Vector3d vtHe = ( m_ptMax - m_ptMin) / 2 ;
// Centro e semiampiezza dell'altro box
Point3d ptCen2 = GetToGlob( ( b3Box.m_ptMin + b3Box.m_ptMax) / 2, frBox) ;
Vector3d vtHe2X = GetToGlob( Vector3d( ( b3Box.GetDimX()) / 2, 0, 0), frBox) ;
Vector3d vtHe2Y = GetToGlob( Vector3d( 0, ( b3Box.GetDimY()) / 2, 0), frBox) ;
Vector3d vtHe2Z = GetToGlob( Vector3d( 0, 0, ( b3Box.GetDimZ()) / 2), frBox) ;
// Vettore tra i due centri
Vector3d vtDiff = ptCen2 - ptCen ;
// Verifico separazione sulle normali ai piani principali del riferimento globale
if ( TestSeparatingAxis( X_AX, vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
return false ;
if ( TestSeparatingAxis( Y_AX, vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
return false ;
if ( TestSeparatingAxis( Z_AX, vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
return false ;
// Verifico separazione sulle normali ai piani principali del secondo riferimento
if ( TestSeparatingAxis( frBox.VersX(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
return false ;
if ( TestSeparatingAxis( frBox.VersY(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
return false ;
if ( TestSeparatingAxis( frBox.VersZ(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
return false ;
// Verifico separazione sulle altre normali ottenute come prodotto vettoriali di quelle precedenti
if ( TestSeparatingAxis( X_AX ^ frBox.VersX(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
return false ;
if ( TestSeparatingAxis( X_AX ^ frBox.VersY(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
return false ;
if ( TestSeparatingAxis( X_AX ^ frBox.VersZ(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
return false ;
if ( TestSeparatingAxis( Y_AX ^ frBox.VersX(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
return false ;
if ( TestSeparatingAxis( Y_AX ^ frBox.VersY(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
return false ;
if ( TestSeparatingAxis( Y_AX ^ frBox.VersZ(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
return false ;
if ( TestSeparatingAxis( Z_AX ^ frBox.VersX(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
return false ;
if ( TestSeparatingAxis( Z_AX ^ frBox.VersY(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
return false ;
if ( TestSeparatingAxis( Z_AX ^ frBox.VersZ(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
return false ;
// Si sovrappongono
return true ;
}
//----------------------------------------------------------------------------
bool
BBox3d::FindIntersection( const BBox3d& b3Box, BBox3d& b3Int) const
{
if ( ! IsValid() || ! b3Box.IsValid())
return false ;
// verifico direttamente la sovrapposizione
if ( m_ptMax.x < b3B.m_ptMin.x - EPS_SMALL || m_ptMin.x > b3B.m_ptMax.x + EPS_SMALL)
if ( m_ptMax.x < b3Box.m_ptMin.x - EPS_SMALL || m_ptMin.x > b3Box.m_ptMax.x + EPS_SMALL)
return false ;
if ( m_ptMax.y < b3B.m_ptMin.y - EPS_SMALL || m_ptMin.y > b3B.m_ptMax.y + EPS_SMALL)
if ( m_ptMax.y < b3Box.m_ptMin.y - EPS_SMALL || m_ptMin.y > b3Box.m_ptMax.y + EPS_SMALL)
return false ;
if ( m_ptMax.z < b3B.m_ptMin.z - EPS_SMALL || m_ptMin.z > b3B.m_ptMax.z + EPS_SMALL)
if ( m_ptMax.z < b3Box.m_ptMin.z - EPS_SMALL || m_ptMin.z > b3Box.m_ptMax.z + EPS_SMALL)
return false ;
// calcolo il box intersezione
b3Int.m_ptMin.x = (( m_ptMin.x >= b3B.m_ptMin.x) ? m_ptMin.x : b3B.m_ptMin.x) ;
b3Int.m_ptMin.y = (( m_ptMin.y >= b3B.m_ptMin.y) ? m_ptMin.y : b3B.m_ptMin.y) ;
b3Int.m_ptMin.z = (( m_ptMin.z >= b3B.m_ptMin.z) ? m_ptMin.z : b3B.m_ptMin.z) ;
b3Int.m_ptMax.x = (( m_ptMax.x <= b3B.m_ptMax.x) ? m_ptMax.x : b3B.m_ptMax.x) ;
b3Int.m_ptMax.y = (( m_ptMax.y <= b3B.m_ptMax.y) ? m_ptMax.y : b3B.m_ptMax.y) ;
b3Int.m_ptMax.z = (( m_ptMax.z <= b3B.m_ptMax.z) ? m_ptMax.z : b3B.m_ptMax.z) ;
b3Int.m_ptMin.x = (( m_ptMin.x >= b3Box.m_ptMin.x) ? m_ptMin.x : b3Box.m_ptMin.x) ;
b3Int.m_ptMin.y = (( m_ptMin.y >= b3Box.m_ptMin.y) ? m_ptMin.y : b3Box.m_ptMin.y) ;
b3Int.m_ptMin.z = (( m_ptMin.z >= b3Box.m_ptMin.z) ? m_ptMin.z : b3Box.m_ptMin.z) ;
b3Int.m_ptMax.x = (( m_ptMax.x <= b3Box.m_ptMax.x) ? m_ptMax.x : b3Box.m_ptMax.x) ;
b3Int.m_ptMax.y = (( m_ptMax.y <= b3Box.m_ptMax.y) ? m_ptMax.y : b3Box.m_ptMax.y) ;
b3Int.m_ptMax.z = (( m_ptMax.z <= b3Box.m_ptMax.z) ? m_ptMax.z : b3Box.m_ptMax.z) ;
return true ;
}
//----------------------------------------------------------------------------
bool
BBox3d::FindIntersectionXY( const BBox3d& b3B, BBox3d& b3Int) const
BBox3d::FindIntersectionXY( const BBox3d& b3Box, BBox3d& b3Int) const
{
if ( ! IsValid() || ! b3B.IsValid())
if ( ! IsValid() || ! b3Box.IsValid())
return false ;
// verifico direttamente la sovrapposizione
if ( m_ptMax.x < b3B.m_ptMin.x - EPS_SMALL || m_ptMin.x > b3B.m_ptMax.x + EPS_SMALL)
if ( m_ptMax.x < b3Box.m_ptMin.x - EPS_SMALL || m_ptMin.x > b3Box.m_ptMax.x + EPS_SMALL)
return false ;
if ( m_ptMax.y < b3B.m_ptMin.y - EPS_SMALL || m_ptMin.y > b3B.m_ptMax.y + EPS_SMALL)
if ( m_ptMax.y < b3Box.m_ptMin.y - EPS_SMALL || m_ptMin.y > b3Box.m_ptMax.y + EPS_SMALL)
return false ;
// calcolo il box intersezione
b3Int.m_ptMin.x = (( m_ptMin.x >= b3B.m_ptMin.x) ? m_ptMin.x : b3B.m_ptMin.x) ;
b3Int.m_ptMin.y = (( m_ptMin.y >= b3B.m_ptMin.y) ? m_ptMin.y : b3B.m_ptMin.y) ;
b3Int.m_ptMin.z = 0.5 * ( m_ptMin.z + b3B.m_ptMin.z) ;
b3Int.m_ptMax.x = (( m_ptMax.x <= b3B.m_ptMax.x) ? m_ptMax.x : b3B.m_ptMax.x) ;
b3Int.m_ptMax.y = (( m_ptMax.y <= b3B.m_ptMax.y) ? m_ptMax.y : b3B.m_ptMax.y) ;
b3Int.m_ptMax.z = 0.5 * ( m_ptMax.z + b3B.m_ptMax.z) ;
b3Int.m_ptMin.x = (( m_ptMin.x >= b3Box.m_ptMin.x) ? m_ptMin.x : b3Box.m_ptMin.x) ;
b3Int.m_ptMin.y = (( m_ptMin.y >= b3Box.m_ptMin.y) ? m_ptMin.y : b3Box.m_ptMin.y) ;
b3Int.m_ptMin.z = 0.5 * ( m_ptMin.z + b3Box.m_ptMin.z) ;
b3Int.m_ptMax.x = (( m_ptMax.x <= b3Box.m_ptMax.x) ? m_ptMax.x : b3Box.m_ptMax.x) ;
b3Int.m_ptMax.y = (( m_ptMax.y <= b3Box.m_ptMax.y) ? m_ptMax.y : b3Box.m_ptMax.y) ;
b3Int.m_ptMax.z = 0.5 * ( m_ptMax.z + b3Box.m_ptMax.z) ;
return true ;
}
+3 -3
View File
@@ -301,11 +301,11 @@ CAvToolSurfTm::MyTestPositionHG( Point3d& ptT, const Vector3d& vtDir)
Vector3d vtDirL = vtDir ; vtDirL.ToLoc( m_frMove) ;
b3Tool.Add( ptTL) ;
b3Tool.Add( ptTL - vtDirL * m_Tool.GetHeigth()) ;
if ( vtDirL.IsXplus() || vtDirL.IsXminus())
if ( vtDirL.IsX())
b3Tool.Expand( 0, m_Tool.GetRadius(), m_Tool.GetRadius()) ;
else if ( vtDirL.IsYplus() || vtDirL.IsYminus())
else if ( vtDirL.IsY())
b3Tool.Expand( m_Tool.GetRadius(), 0, m_Tool.GetRadius()) ;
else if ( vtDirL.IsZplus() || vtDirL.IsZminus())
else if ( vtDirL.IsZ())
b3Tool.Expand( m_Tool.GetRadius(), m_Tool.GetRadius(), 0) ;
else {
double dExpandX = m_Tool.GetRadius() * sqrt( 1 - vtDirL.x * vtDirL.x) ;
+11 -8
View File
@@ -23,17 +23,17 @@ using namespace std ;
bool
CDeBoxClosedSurfTm( const Frame3d& frBox, const Vector3d& vtDiag, double dSafeDist, const ISurfTriMesh& Stm)
{
// recupero BBox del poliedro
// Recupero BBox del poliedro
BBox3d b3Poly = Stm.GetAllTriaBox() ;
// calcolo il BBox del parallelepipedo
BBox3d b3Box( ORIG, ORIG + vtDiag) ;
// Calcolo il BBox del parallelepipedo
BBox3d b3BoxL( ORIG, ORIG + vtDiag) ;
if ( dSafeDist > EPS_SMALL)
b3Box.Expand( dSafeDist) ;
b3Box.ToGlob( frBox) ;
b3BoxL.Expand( dSafeDist) ;
BBox3d b3Box = GetToGlob( b3BoxL, frBox) ;
// Se i BBox non interferiscono, non c'è collisione
if ( ! b3Box.Overlaps( b3Poly))
if ( ! b3Poly.Overlaps( b3Box) || ! b3Poly.Overlaps( frBox, b3BoxL))
return false ;
// recupero i triangoli che interferiscono con il box
// Verifico se il parallelepipedo interferisce con i triangoli del poliedro presenti nel suo BBox
INTVECTOR vT ;
Stm.GetAllTriaOverlapBox( b3Box, vT) ;
for ( int nT : vT) {
@@ -46,7 +46,10 @@ CDeBoxClosedSurfTm( const Frame3d& frBox, const Vector3d& vtDiag, double dSafeDi
// Se superficie aperta, non c'è collisione
if ( ! Stm.IsClosed())
return false ;
// Verifico se il box è dentro la superficie tramite calcolo distanza minima.
// Se il BBox del parallelepipedo non è interno a quello del poliedro e viceversa, non c'è collisione
if ( ! b3Poly.Encloses( b3Box) && ! b3Box.Encloses( b3Poly))
return false ;
// Verifico se il box è dentro la superficie tramite calcolo distanza minima del suo centro
Point3d ptBoxCen = ORIG + vtDiag / 2 ;
ptBoxCen.ToGlob( frBox) ;
DistPointSurfTm DistBoxCenSurfCalc( ptBoxCen, Stm) ;
+27 -24
View File
@@ -35,60 +35,60 @@ using namespace std ;
bool
CDeClosedSurfTmClosedSurfTm( const SurfTriMesh& SurfA, const SurfTriMesh& SurfB, double dSafeDist)
{
// Se le superfici non sono valide o non sono chiuse, non ha senso proseguire.
// Se le superfici non sono valide o non sono chiuse, non ha senso proseguire.
if ( ! ( SurfA.IsValid() && SurfB.IsValid()) || ! ( SurfA.IsClosed() && SurfB.IsClosed()))
return false ;
// Se i box delle superfici non si intersecano, ho finito.
// Se i box delle superfici non si intersecano, ho finito.
BBox3d b3BoxA, b3BoxB ;
SurfA.GetLocalBBox( b3BoxA) ;
SurfB.GetLocalBBox( b3BoxB) ;
// Se è necessario, espando il box di una costante additiva pari alla distanza di sicurezza.
// Se è necessario, espando il box di una costante additiva pari alla distanza di sicurezza.
if ( dSafeDist > EPS_SMALL)
b3BoxA.Expand( dSafeDist) ;
// Se i box non si sovrappongono, non c'è collisione. Ho finito.
// Se i box non si sovrappongono, non c'è collisione. Ho finito.
if ( ! b3BoxA.Overlaps( b3BoxB))
return false ;
// Recupero i triangoli di B che interferiscono col box del triangolo di A
// Recupero i triangoli di B che interferiscono col box del triangolo di A
INTVECTOR vTriaIndex ;
SurfA.GetAllTriaOverlapBox( b3BoxB, vTriaIndex) ;
// Ciclo sui triangoli della superficie A che cadono nel box della superficie B.
// Ciclo sui triangoli della superficie A che cadono nel box della superficie B.
for ( int nTA : vTriaIndex) {
Triangle3d trTriaA ;
if ( ! ( SurfA.GetTriangle( nTA, trTriaA) && trTriaA.Validate()))
continue ;
BBox3d b3BoxTriaA ;
trTriaA.GetLocalBBox( b3BoxTriaA) ;
// Se è necessario, espando il box di una costante additiva pari alla distanza di sicurezza.
// Se è necessario, espando il box di una costante additiva pari alla distanza di sicurezza.
if ( dSafeDist > EPS_SMALL)
b3BoxTriaA.Expand( dSafeDist) ;
// Recupero i triangoli di B che interferiscono col box del triangolo di A
// Recupero i triangoli di B che interferiscono col box del triangolo di A
INTVECTOR vNearTria ;
SurfB.GetAllTriaOverlapBox( b3BoxTriaA, vNearTria) ;
// Settare tutti i triangoli come già processati.
// Al termine della chiamata i TFlags dei triangoli valgono 0.
// Settare tutti i triangoli come già processati.
// Al termine della chiamata i TFlags dei triangoli valgono 0.
SurfB.ResetTempInt() ;
// Ciclo sui triangoli della superficie B che cadono nel box del triangolo corrente della Superficie A.
// Ciclo sui triangoli della superficie B che cadono nel box del triangolo corrente della Superficie A.
for ( int nTB : vNearTria) {
// Recupero il triangolo corrente della superficie B.
// Se triangolo non valido salto al successivo.
// Recupero il triangolo corrente della superficie B.
// Se triangolo non valido salto al successivo.
Triangle3d trTriaB ;
if ( ! ( SurfB.GetTriangle( nTB, trTriaB) && trTriaB.Validate()))
continue ;
// Se necessario considero l'offset
// Se necessario considero l'offset
if ( dSafeDist > EPS_SMALL) {
int nAdjTriaId[3] ;
SurfB.GetTriangleAdjacencies( nTB, nAdjTriaId) ;
// Ciclo sui vertici del triangolo.
// Ciclo sui vertici del triangolo.
for ( int nVB = 0 ; nVB < 3 ; ++ nVB) {
// Se il triangolo adiacente al triangolo corrente su questo edge
// non è stato processato, processo il vertice e l'edge.
// Se il triangolo adiacente al triangolo corrente su questo edge
// non è stato processato, processo il vertice e l'edge.
int nAdjTriaTempFlag ;
if ( ! ( SurfB.GetTriangleTempInt( nAdjTriaId[nVB], nAdjTriaTempFlag) || nAdjTriaTempFlag == 0))
continue ;
// Processo il vertice: se c'è collisione fra triangolo A e sfera ho finito.
// Processo il vertice: se c'è collisione fra triangolo A e sfera ho finito.
if ( CDeSimpleSpheTria( trTriaB.GetP( nVB), dSafeDist, trTriaA))
return true ;
// Processo l'edge: se c'è collisione fra triangolo A e cilindro ho finito.
// Processo l'edge: se c'è collisione fra triangolo A e cilindro ho finito.
Vector3d vtEdgeV = trTriaB.GetP( nVB) - trTriaB.GetP( ( nVB + 1) % 3) ;
double dEdgeLen = vtEdgeV.Len() ;
vtEdgeV /= dEdgeLen ;
@@ -97,18 +97,21 @@ CDeClosedSurfTmClosedSurfTm( const SurfTriMesh& SurfA, const SurfTriMesh& SurfB,
if ( CDeSimpleCylTria( frCyl, dSafeDist, dEdgeLen, trTriaA))
return true ;
}
// Traslo il triangolo
// Traslo il triangolo
trTriaB.Translate( dSafeDist * trTriaB.GetN()) ;
}
// Processo il triangolo: se i due triangoli collidono ho finito.
// Processo il triangolo: se i due triangoli collidono ho finito.
if ( CDeTriaTria( trTriaA, trTriaB))
return true ;
// Segno il triangolo come processato: nTFlag = 1
// Segno il triangolo come processato: nTFlag = 1
SurfB.SetTempInt( nTB, 1) ;
}
}
// Non ho trovato collisioni fra triangoli delle superfici.
// La collisione c'è se una superficie è dentro l'altra.
// Non ho trovato collisioni fra triangoli delle superfici.
// Se il BBox della prima superficie non è interno a quello della seconda e viceversa, non c'è collisione
if ( ! b3BoxA.Encloses( b3BoxB) && ! b3BoxB.Encloses( b3BoxA))
return false ;
// La collisione c'è se una superficie è dentro l'altra.
Point3d ptPointA, ptPointB ;
SurfA.GetFirstVertex( ptPointA) ;
SurfB.GetFirstVertex( ptPointB) ;
+10 -6
View File
@@ -27,24 +27,25 @@ bool
CDeConeFrustumClosedSurfTm( const Frame3d& frCone, double dBaseRad, double dTopRad, double dHeight,
double dSafeDist, const ISurfTriMesh& Stm)
{
// Se il tronco di cono non è ben definito non ha senso proseguire.
// Se il tronco di cono non è ben definito non ha senso proseguire
if ( max( dBaseRad, dTopRad) < EPS_SMALL || dHeight < EPS_SMALL)
return false ;
// Recupero BBox della trimesh
BBox3d b3Surf = Stm.GetAllTriaBox() ;
// Calcolo il BBox del tronco di cono
double dMaxRad = max( dBaseRad, dTopRad) ;
BBox3d b3Cone( - dMaxRad, - dMaxRad, 0, dMaxRad, dMaxRad, dHeight) ;
BBox3d b3ConeL( Point3d( -dMaxRad, -dMaxRad, 0),
Point3d( dMaxRad, dMaxRad, dHeight)) ;
if ( dSafeDist > EPS_SMALL)
b3Cone.Expand( dSafeDist) ;
b3Cone.ToGlob( frCone) ;
b3ConeL.Expand( dSafeDist) ;
BBox3d b3Cone = GetToGlob( b3ConeL, frCone) ;
// Se i BBox non interferiscono, non c'è collisione
if ( ! b3Cone.Overlaps( b3Surf))
if ( ! b3Surf.Overlaps( b3Cone) || ! b3Surf.Overlaps( frCone, b3ConeL))
return false ;
// Recupero i triangoli che interferiscono con il box del cono
INTVECTOR vT ;
Stm.GetAllTriaOverlapBox( b3Cone, vT) ;
// Ciclo sui triangoli che interferiscono col box del cono
// Verifico se il tronco di cono interferisce con i triangoli del poliedro presenti nel suo BBox
for ( int nT : vT) {
Triangle3d trTria ;
if ( Stm.GetTriangle( nT, trTria)) {
@@ -55,6 +56,9 @@ CDeConeFrustumClosedSurfTm( const Frame3d& frCone, double dBaseRad, double dTopR
// Se superficie aperta, non c'è collisione
if ( ! Stm.IsClosed())
return false ;
// Se il BBox del tronco di cono non è interno a quello del poliedro e viceversa, non c'è collisione
if ( ! b3Surf.Encloses( b3Cone) && ! b3Cone.Encloses( b3Surf))
return false ;
// Verifico se il tronco di cono è dentro la superficie tramite calcolo distanza minima.
Point3d ptConeCen( 0, 0, dHeight / 2) ;
ptConeCen.ToGlob( frCone) ;
+17 -17
View File
@@ -23,42 +23,42 @@ using namespace std ;
// Il toro è posto nel piano XY del suo riferimento, centrato sull'origine.
// La funzione restituisce true in caso di collisione.
bool
CDeConvexTorusClosedSurfTm( const Frame3d& frTorusFrame, double dRad1, double dRad2,
CDeConvexTorusClosedSurfTm( const Frame3d& frTorus, double dRad1, double dRad2,
double dSafeDist, const ISurfTriMesh& Stm)
{
// I raggi devono essere non nulli e la superficie ben definita.
if ( dRad1 < EPS_SMALL || dRad2 < EPS_SMALL || ! Stm.IsValid())
return false ;
// Box del toro (sempre completo)
BBox3d b3ConvTorusBox ;
b3ConvTorusBox.Set( Point3d( - dRad1 - dRad2, - dRad1 - dRad2, - dRad2),
Point3d( dRad1 + dRad2, dRad1 + dRad2, dRad2)) ;
// Aggiungo eventuale distanza di sicurezza
if ( dSafeDist > EPS_SMALL)
b3ConvTorusBox.Expand( dSafeDist) ;
// Porto il box del toro nel riferimento della superficie (inteso some globale)
b3ConvTorusBox.ToGlob( frTorusFrame) ;
// Box della superficie
BBox3d b3SurfBox = Stm.GetAllTriaBox() ;
BBox3d b3Surf = Stm.GetAllTriaBox() ;
// Box del toro (sempre completo)
BBox3d b3TorusL( Point3d( -dRad1 - dRad2, -dRad1 - dRad2, -dRad2),
Point3d( dRad1 + dRad2, dRad1 + dRad2, dRad2)) ;
if ( dSafeDist > EPS_SMALL)
b3TorusL.Expand( dSafeDist) ;
BBox3d b3Torus = GetToGlob( b3TorusL, frTorus) ;
// Se i BBox non interferiscono, non c'è collisione
if ( ! b3ConvTorusBox.Overlaps( b3SurfBox))
if ( ! b3Surf.Overlaps( b3Torus) || ! b3Surf.Overlaps( frTorus, b3TorusL))
return false ;
// Recupero i triangoli che interferiscono con il box del toro
INTVECTOR vT ;
Stm.GetAllTriaOverlapBox( b3ConvTorusBox, vT) ;
// Ciclo sui triangoli recuperati
Stm.GetAllTriaOverlapBox( b3Torus, vT) ;
// Verifico se il toro interferisce con i triangoli del poliedro presenti nel suo BBox
for ( int nT : vT) {
Triangle3d trTria ;
if ( Stm.GetTriangle( nT, trTria)) {
if ( CDeConvexTorusTria( frTorusFrame, dRad1, dRad2, CT_TOT, dSafeDist, trTria))
if ( CDeConvexTorusTria( frTorus, dRad1, dRad2, CT_TOT, dSafeDist, trTria))
return true ;
}
}
// Se superficie aperta, non c'è collisione
if ( ! Stm.IsClosed())
return false ;
// Verifico se il toro è dentro la superficie tramite calcolo distanza minima.
Point3d ptTorusOrig = frTorusFrame.Orig() ;
// Se il BBox del toro non è interno a quello del poliedro e viceversa, non c'è collisione
if ( ! b3Surf.Encloses( b3Torus) && ! b3Torus.Encloses( b3Surf))
return false ;
// Verifico se il toro è dentro la superficie tramite calcolo distanza minima del suo centro
Point3d ptTorusOrig = frTorus.Orig() ;
DistPointSurfTm DistConeOrigSurfCalc( ptTorusOrig, Stm) ;
// Se il toro è interno c'è collisione
return ( DistConeOrigSurfCalc.IsPointInside()) ;
+17 -13
View File
@@ -23,38 +23,42 @@ using namespace std ;
bool
CDeCylClosedSurfTm( const Frame3d& frCyl, double dR, double dH, double dSafeDist, const ISurfTriMesh& Stm)
{
// recupero BBox del poliedro
// Recupero BBox del poliedro
BBox3d b3Poly = Stm.GetAllTriaBox() ;
// sistemazioni cilindro
Frame3d frC = frCyl ;
// Sistemazioni cilindro
Frame3d frMyCyl = frCyl ;
if ( dH < 0) {
frC.Translate( dH * frC.VersZ()) ;
frMyCyl.Translate( dH * frMyCyl.VersZ()) ;
dH = - dH ;
}
// calcolo il BBox del cilindro
BBox3d b3Cyl( -dR, -dR, 0, dR, dR, dH) ;
// Calcolo il BBox del cilindro
BBox3d b3CylL( Point3d( -dR, -dR, 0),
Point3d( dR, dR, dH)) ;
if ( dSafeDist > EPS_SMALL)
b3Cyl.Expand( dSafeDist) ;
b3Cyl.ToGlob( frC) ;
b3CylL.Expand( dSafeDist) ;
BBox3d b3Cyl = GetToGlob( b3CylL, frMyCyl) ;
// Se i BBox non interferiscono, non c'è collisione
if ( ! b3Cyl.Overlaps( b3Poly))
if ( ! b3Poly.Overlaps( b3Cyl) || ! b3Poly.Overlaps( frMyCyl, b3CylL))
return false ;
// recupero i triangoli che interferiscono con il box del Cilindro
// Verifico se il cilindro interferisce con i triangoli del poliedro presenti nel suo BBox
INTVECTOR vT ;
Stm.GetAllTriaOverlapBox( b3Cyl, vT) ;
for ( int nT : vT) {
Triangle3d Tria ;
if ( Stm.GetTriangle( nT, Tria)) {
if ( CDeCylTria( frC, dR, dH, dSafeDist, Tria))
if ( CDeCylTria( frMyCyl, dR, dH, dSafeDist, Tria))
return true ;
}
}
// Se superficie aperta, non c'è collisione
if ( ! Stm.IsClosed())
return false ;
// Verifico se il cilindro è dentro la superficie tramite calcolo distanza minima.
// Se il BBox del cilindro non è interno a quello del poliedro e viceversa, non c'è collisione
if ( ! b3Poly.Encloses( b3Cyl) && ! b3Cyl.Encloses( b3Poly))
return false ;
// Verifico se il cilindro è dentro la superficie tramite calcolo distanza minima del suo centro
Point3d ptCylCen( 0, 0, dH / 2) ;
ptCylCen.ToGlob( frC) ;
ptCylCen.ToGlob( frMyCyl) ;
DistPointSurfTm DistCylCenSurfCalc( ptCylCen, Stm) ;
// Se il cilindro è interno c'è collisione
return ( DistCylCenSurfCalc.IsPointInside()) ;
+11 -7
View File
@@ -37,17 +37,18 @@ CDeRectPrismoidClosedSurfTm( const Frame3d& frPrismoid, double dLenghtBaseX, dou
// Calcolo il BBox del tronco di piramide
double dMaxLenX = max( dLenghtBaseX, dLenghtTopX) ;
double dMaxLenY = max( dLenghtBaseY, dLenghtTopY) ;
BBox3d b3Pyr( -dMaxLenX / 2, -dMaxLenY / 2, 0., dMaxLenX / 2, dMaxLenY / 2, dHeight) ;
BBox3d b3PyrL( Point3d( -dMaxLenX / 2, -dMaxLenY / 2, 0.),
Point3d( dMaxLenX / 2, dMaxLenY / 2, dHeight)) ;
if ( dSafeDist > EPS_SMALL)
b3Pyr.Expand( dSafeDist) ;
b3Pyr.ToGlob( frPrismoid) ;
b3PyrL.Expand( dSafeDist) ;
BBox3d b3Pyr = GetToGlob( b3PyrL, frPrismoid) ;
// Se i BBox non interferiscono, non c'è collisione
if ( ! b3Pyr.Overlaps( b3Surf))
if ( ! b3Surf.Overlaps( b3Pyr) || ! b3Surf.Overlaps( frPrismoid, b3PyrL))
return false ;
// Recupero i triangoli che interferiscono con il box del tronco di piramide.
INTVECTOR vT ;
Stm.GetAllTriaOverlapBox( b3Pyr, vT) ;
// Ciclo sui triangoli che interferiscono col box del tronco di piramide.
// Verifico se il tronco di piramide interferisce con i triangoli del poliedro presenti nel suo BBox
for ( int nT : vT) {
Triangle3d trTria ;
if ( Stm.GetTriangle( nT, trTria)) {
@@ -59,10 +60,13 @@ CDeRectPrismoidClosedSurfTm( const Frame3d& frPrismoid, double dLenghtBaseX, dou
// Se superficie aperta, non c'è collisione
if ( ! Stm.IsClosed())
return false ;
// Verifico se il tronco di piramide è dentro la superficie tramite calcolo distanza minima.
// Se il BBox del tronco di piramide non è interno a quello del poliedro e viceversa, non c'è collisione
if ( ! b3Surf.Encloses( b3Pyr) && ! b3Pyr.Encloses( b3Surf))
return false ;
// Verifico se il tronco di piramide è dentro la superficie tramite calcolo distanza minima del suo centro
Point3d ptPyrCen( 0, 0, dHeight / 2) ;
ptPyrCen.ToGlob( frPrismoid) ;
DistPointSurfTm DistPyrCenSurfCalc( ptPyrCen, Stm) ;
// C'è collisione se il tronco di piramide è interno.
// C'è collisione se il tronco di piramide è interno
return ( DistPyrCenSurfCalc.IsPointInside()) ;
}
+8 -5
View File
@@ -23,16 +23,16 @@ using namespace std ;
bool
CDeSpheClosedSurfTm( const Point3d& ptCen, double dR, double dSafeDist, const ISurfTriMesh& Stm)
{
// recupero BBox del poliedro
// Recupero BBox del poliedro
BBox3d b3Poly = Stm.GetAllTriaBox() ;
// calcolo il BBox della sfera
// Calcolo il BBox della sfera
BBox3d b3Sphe( ptCen, dR) ;
if ( dSafeDist > EPS_SMALL)
b3Sphe.Expand( dSafeDist) ;
// Se i BBox non interferiscono, non c'è collisione
if ( ! b3Sphe.Overlaps( b3Poly))
return false ;
// recupero i triangoli che interferiscono con il box della Sfera
// Verifico se la sfera interferisce con i triangoli del poliedro presenti nel suo BBox
INTVECTOR vT ;
Stm.GetAllTriaOverlapBox( b3Sphe, vT) ;
for ( int nT : vT) {
@@ -45,8 +45,11 @@ CDeSpheClosedSurfTm( const Point3d& ptCen, double dR, double dSafeDist, const IS
// Se superficie aperta, non c'è collisione
if ( ! Stm.IsClosed())
return false ;
// Verifico se la sfera è dentro la superficie tramite calcolo distanza minima.
// Se il BBox della sfera non è interno a quello del poliedro e viceversa, non c'è collisione
if ( ! b3Sphe.Encloses( b3Poly) && ! b3Poly.Encloses( b3Sphe))
return false ;
// Verifico se la sfera è dentro la superficie tramite calcolo distanza minima del suo centro
DistPointSurfTm DistCenSurfCalc( ptCen, Stm) ;
// C'è collisione se la sfera è interna.
// C'è collisione se la sfera è interna.
return ( DistCenSurfCalc.IsPointInside()) ;
}
BIN
View File
Binary file not shown.
+134 -109
View File
@@ -411,15 +411,18 @@ bool
VolZmap::AvoidSimpleBox( const Frame3d& frBox, const Vector3d& vtDiag, bool bPrecise) const
{
// BBox
BBox3d b3Box( ORIG, ORIG + vtDiag) ;
BBox3d b3BoxL( ORIG, ORIG + vtDiag) ;
// Porto il box nel riferimento intrinseco dello Zmap
b3Box.LocToLoc( frBox, m_MapFrame) ;
Frame3d frBoxInt = GetToLoc( frBox, m_MapFrame) ;
BBox3d b3Box = GetToGlob( b3BoxL, frBoxInt) ;
// BBox dello Zmap nel suo riferimento intrinseco
BBox3d b3Zmap( ORIG, Point3d( m_nNx[0] * m_dStep, m_nNy[0] * m_dStep, m_dMaxZ[0])) ;
// Se non interferiscono, posso uscire
if ( ! b3Zmap.Overlaps( b3Box) || ! b3Zmap.Overlaps( frBoxInt, b3BoxL))
return true ;
BBox3d b3Int ;
if ( ! b3Zmap.FindIntersection( b3Box, b3Int))
return true ;
@@ -434,12 +437,12 @@ VolZmap::AvoidSimpleBox( const Frame3d& frBox, const Vector3d& vtDiag, bool bPre
int nEnJ = Clamp( int( b3Int.GetMax().y / m_dStep), 0, m_nNy[0] - 1) ;
// Vettore direzione dei dexel nel riferimento del Box
Vector3d vtK = Z_AX ; vtK.LocToLoc( m_MapFrame, frBox) ;
Vector3d vtK = Z_AX ; vtK.ToLoc( frBoxInt) ;
// Riferimento intrinseco dei dexel nel riferimento del box
Point3d ptO = ORIG ; ptO.LocToLoc( m_MapFrame, frBox) ;
Vector3d vtX = X_AX ; vtX.LocToLoc( m_MapFrame, frBox) ;
Vector3d vtY = Y_AX ; vtY.LocToLoc( m_MapFrame, frBox) ;
Point3d ptO = ORIG ; ptO.ToLoc( frBoxInt) ;
Vector3d vtX = X_AX ; vtX.ToLoc( frBoxInt) ;
Vector3d vtY = Y_AX ; vtY.ToLoc( frBoxInt) ;
// Ciclo di intersezione dei dexel con il BBox
for ( int i = nStI ; i <= nEnI ; ++ i) {
@@ -503,10 +506,10 @@ VolZmap::AvoidSimpleBox( const Frame3d& frBox, const Vector3d& vtDiag, bool bPre
vtK = Y_AX ;
}
// Passo da sistema griglia a sistema BBox
ptO.ToLoc( frBox) ;
vtX.ToLoc( frBox) ;
vtY.ToLoc( frBox) ;
vtK.ToLoc( frBox) ;
ptO.ToLoc( frBoxInt) ;
vtX.ToLoc( frBoxInt) ;
vtY.ToLoc( frBoxInt) ;
vtK.ToLoc( frBoxInt) ;
// Limiti su indici
int nStI = Clamp( int( ptBoxInf.x / m_dStep), 0, m_nNx[nMap] - 1) ;
int nEnI = Clamp( int( ptBoxSup.x / m_dStep), 0, m_nNx[nMap] - 1) ;
@@ -780,33 +783,41 @@ VolZmap::AvoidSphere( const Point3d& ptCenter, double dRad, double dSafeDist, bo
bool
VolZmap::AvoidSimpleCylinder( const Frame3d& frCyl, double dR, double dH, bool bPrecise) const
{
// Porto il cilindro nel riferimento intrinseco dello Zmap
Frame3d frC = frCyl ;
frC.ToLoc( m_MapFrame) ;
// BBox del cilindro in locale
BBox3d b3CylL( Point3d( -dR, -dR, 0), Point3d( dR, dR, dH)) ;
// BBox del cilindro
Vector3d vtDirL = frC.VersZ() ;
BBox3d b3Box( frC.Orig()) ;
b3Box.Add( frC.Orig() + frC.VersZ() * dH) ;
if ( vtDirL.IsXplus() || vtDirL.IsXminus())
b3Box.Expand( 0, dR, dR) ;
else if ( vtDirL.IsYplus() || vtDirL.IsYminus())
b3Box.Expand( dR, 0, dR) ;
else if ( vtDirL.IsZplus() || vtDirL.IsZminus())
b3Box.Expand( dR, dR, 0) ;
else {
double dExpandX = dR * sqrt( 1 - vtDirL.x * vtDirL.x) ;
double dExpandY = dR * sqrt( 1 - vtDirL.y * vtDirL.y) ;
double dExpandZ = dR * sqrt( 1 - vtDirL.z * vtDirL.z) ;
b3Box.Expand( dExpandX, dExpandY, dExpandZ) ;
}
// BBox del cilindro nel riferimento intrinseco dello Zmap
Frame3d frCylInt = GetToLoc( frCyl, m_MapFrame) ;
BBox3d b3CylI = GetToGlob( b3CylL, frCylInt) ;
// BBox dello Zmap nel suo riferimento intrinseco
BBox3d b3Zmap( ORIG, Point3d( m_nNx[0] * m_dStep, m_nNy[0] * m_dStep, m_dMaxZ[0])) ;
// Se non interferiscono, posso uscire
if ( ! b3Zmap.Overlaps( b3CylI) || ! b3Zmap.Overlaps( frCylInt, b3CylL))
return true ;
// BBox del cilindro ottimizzato nel riferimento intrinseco dello Zmap
Point3d ptMyCen = frCylInt.Orig() ;
Vector3d vtMyAx = frCylInt.VersZ() ;
BBox3d b3Cyl( ptMyCen) ;
b3Cyl.Add( ptMyCen + vtMyAx * dH) ;
if ( vtMyAx.IsX())
b3Cyl.Expand( 0, dR, dR) ;
else if ( vtMyAx.IsY())
b3Cyl.Expand( dR, 0, dR) ;
else if ( vtMyAx.IsZ())
b3Cyl.Expand( dR, dR, 0) ;
else {
double dExpandX = dR * sqrt( 1 - vtMyAx.x * vtMyAx.x) ;
double dExpandY = dR * sqrt( 1 - vtMyAx.y * vtMyAx.y) ;
double dExpandZ = dR * sqrt( 1 - vtMyAx.z * vtMyAx.z) ;
b3Cyl.Expand( dExpandX, dExpandY, dExpandZ) ;
}
// Se non interferiscono, posso uscire
BBox3d b3Int ;
if ( ! b3Zmap.FindIntersection( b3Box, b3Int))
if ( ! b3Zmap.FindIntersection( b3Cyl, b3Int))
return true ;
// Se verifico solo prima mappa
@@ -838,7 +849,7 @@ VolZmap::AvoidSimpleCylinder( const Frame3d& frCyl, double dR, double dH, bool b
}
Point3d ptI1, ptI2 ;
Vector3d vtN1, vtN2 ;
if ( IntersLineCylinder( ptT, Z_AX, frC, dH, dR, true, true, ptI1, vtN1, ptI2, vtN2)) {
if ( IntersLineCylinder( ptT, Z_AX, frCylInt, dH, dR, true, true, ptI1, vtN1, ptI2, vtN2)) {
double dZmin = min( ptI1.z, ptI2.z) ;
double dZmax = max( ptI1.z, ptI2.z) ;
for ( int nIndex = 0 ; nIndex < nSize ; nIndex += 1) {
@@ -898,7 +909,7 @@ VolZmap::AvoidSimpleCylinder( const Frame3d& frCyl, double dR, double dH, bool b
Point3d ptI1, ptI2 ;
Vector3d vtN1, vtN2 ;
// La linea del dexel interseca il cilindro.
if ( IntersLineCylinder( ptT, vtK, frC, dH, dR, true, true, ptI1, vtN1, ptI2, vtN2)) {
if ( IntersLineCylinder( ptT, vtK, frCylInt, dH, dR, true, true, ptI1, vtN1, ptI2, vtN2)) {
double dMinU, dMaxU ;
if ( nMap == 0) {
dMinU = min( ptI1.z, ptI2.z) ;
@@ -933,33 +944,33 @@ bool
VolZmap::AvoidCylinder( const Frame3d& frCyl, double dR, double dH, double dSafeDist, bool bPrecise) const
{
// Se altezza negativa, sposto riferimento da faccia sopra a quella sotto
Frame3d frC = frCyl ;
Frame3d frMyCyl = frCyl ;
if ( dH < 0) {
frC.Translate( dH * frC.VersZ()) ;
frMyCyl.Translate( dH * frMyCyl.VersZ()) ;
dH = - dH ;
}
// Se distanza di sicurezza nulla
if ( dSafeDist < EPS_SMALL)
return AvoidSimpleCylinder( frC, dR, dH, bPrecise) ;
return AvoidSimpleCylinder( frMyCyl, dR, dH, bPrecise) ;
// Verifica preliminare con cilindro esteso
Frame3d frEst = frC ; frEst.Translate( -dSafeDist * frC.VersZ()) ;
Frame3d frEst = frMyCyl ; frEst.Translate( -dSafeDist * frMyCyl.VersZ()) ;
if ( AvoidSimpleCylinder( frEst, dR + dSafeDist, dH + 2 * dSafeDist, bPrecise))
return true ;
// Cilindro allargato
if ( ! AvoidSimpleCylinder( frC, dR + dSafeDist, dH, bPrecise))
if ( ! AvoidSimpleCylinder( frMyCyl, dR + dSafeDist, dH, bPrecise))
return false ;
// Cilindro allungato
Frame3d frTmp = frC ; frTmp.Translate( - dSafeDist * frC.VersZ()) ;
Frame3d frTmp = frMyCyl ; frTmp.Translate( - dSafeDist * frMyCyl.VersZ()) ;
if ( ! AvoidSimpleCylinder( frTmp, dR, dH + 2 * dSafeDist, bPrecise))
return false ;
// Toro inferiore
if ( ! AvoidSimpleTorus( frC, dR, dSafeDist, bPrecise))
if ( ! AvoidSimpleTorus( frMyCyl, dR, dSafeDist, bPrecise))
return false ;
// Toro superiore
frTmp = frC ; frTmp.Translate( dH * frC.VersZ()) ;
frTmp = frMyCyl ; frTmp.Translate( dH * frMyCyl.VersZ()) ;
if ( ! AvoidSimpleTorus( frTmp, dR, dSafeDist, bPrecise))
return false ;
@@ -1065,34 +1076,41 @@ VolZmap::SingleMapDexelConeCollision( int nStI, int nEnI, int nStJ, int nEnJ, co
bool
VolZmap::AvoidSimpleConeFrustum( const Frame3d& frCone, double dMinRad, double dMaxRad, double dHeight, bool bPrecise) const
{
// Porto il tronco di cono nel sistema intrinseco e normalizzo il vettore.
Point3d ptRefPoint = frCone.Orig() ;
Vector3d vtRefAx = frCone.VersZ() ;
ptRefPoint.ToLoc( m_MapFrame) ;
vtRefAx.ToLoc( m_MapFrame) ;
// BBox del tronco di cono in locale
BBox3d b3ConeL( Point3d( -dMaxRad, -dMaxRad, 0), Point3d( dMaxRad, dMaxRad, dHeight)) ;
// BBox del tronco di cono
BBox3d b3Box( ptRefPoint) ;
b3Box.Add( ptRefPoint + vtRefAx * dHeight) ;
if ( vtRefAx.IsXplus() || vtRefAx.IsXminus())
b3Box.Expand( 0, dMaxRad, dMaxRad) ;
else if ( vtRefAx.IsYplus() || vtRefAx.IsYminus())
b3Box.Expand( dMaxRad, 0, dMaxRad) ;
else if ( vtRefAx.IsZplus() || vtRefAx.IsZminus())
b3Box.Expand( dMaxRad, dMaxRad, 0) ;
else {
double dExpandX = dMaxRad * sqrt( 1 - vtRefAx.x * vtRefAx.x) ;
double dExpandY = dMaxRad * sqrt( 1 - vtRefAx.y * vtRefAx.y) ;
double dExpandZ = dMaxRad * sqrt( 1 - vtRefAx.z * vtRefAx.z) ;
b3Box.Expand( dExpandX, dExpandY, dExpandZ) ;
}
// BBox del tronco di cono nel riferimento intrinseco dello Zmap
Frame3d frConeInt = GetToLoc( frCone, m_MapFrame) ;
BBox3d b3ConeI = GetToGlob( b3ConeL, frConeInt) ;
// BBox dello Zmap nel suo riferimento intrinseco
BBox3d b3Zmap( ORIG, Point3d( m_nNx[0] * m_dStep, m_nNy[0] * m_dStep, m_dMaxZ[0])) ;
// Se non interferiscono, posso uscire
if ( ! b3Zmap.Overlaps( b3ConeI) || ! b3Zmap.Overlaps( frConeInt, b3ConeL))
return true ;
// BBox del tronco di cono ottimizzato nel riferimento intrinseco dello Zmap
Point3d ptRefPoint = frConeInt.Orig() ;
Vector3d vtRefAx = frConeInt.VersZ() ;
BBox3d b3Cone( ptRefPoint) ;
b3Cone.Add( ptRefPoint + vtRefAx * dHeight) ;
if ( vtRefAx.IsX())
b3Cone.Expand( 0, dMaxRad, dMaxRad) ;
else if ( vtRefAx.IsY())
b3Cone.Expand( dMaxRad, 0, dMaxRad) ;
else if ( vtRefAx.IsZ())
b3Cone.Expand( dMaxRad, dMaxRad, 0) ;
else {
double dExpandX = dMaxRad * sqrt( 1 - vtRefAx.x * vtRefAx.x) ;
double dExpandY = dMaxRad * sqrt( 1 - vtRefAx.y * vtRefAx.y) ;
double dExpandZ = dMaxRad * sqrt( 1 - vtRefAx.z * vtRefAx.z) ;
b3Cone.Expand( dExpandX, dExpandY, dExpandZ) ;
}
// Se non interferiscono, posso uscire
BBox3d b3Int ;
if ( ! b3Zmap.FindIntersection( b3Box, b3Int))
if ( ! b3Zmap.FindIntersection( b3Cone, b3Int))
return true ;
// Uso solo la prima mappa
@@ -1638,34 +1656,33 @@ bool
VolZmap::AvoidSimpleRectPrismoid( const Frame3d& frPrismoid, double dLenghtBaseX, double dLenghtBaseY,
double dLenghtTopX, double dLenghtTopY, double dHeight, bool bPrecise) const
{
// IL sistema del tronco di piramide generalizzato è definito nel sistema locale.
// Lo porto nel sistema intrinseco.
Frame3d frMyFrame = frPrismoid ;
frMyFrame.ToLoc( m_MapFrame) ;
// Box del tronco nel suo sistema
// Box del tronco di prismoide nel suo sistema locale
double dMaxLenX = max( dLenghtBaseX, dLenghtTopX) ;
double dMaxLenY = max( dLenghtBaseY, dLenghtTopY) ;
BBox3d b3GenPyrBox( Point3d( -dMaxLenX / 2, -dMaxLenY / 2, 0.),
Point3d( dMaxLenX / 2, dMaxLenY / 2, dHeight)) ;
// Porto il box nel sistema intrinseco dello Zmap
b3GenPyrBox.ToGlob( frMyFrame) ;
BBox3d b3PrismL( Point3d( -dMaxLenX / 2, -dMaxLenY / 2, 0.),
Point3d( dMaxLenX / 2, dMaxLenY / 2, dHeight)) ;
// Box del solido
// BBox del tronco di prismoide nel riferimento intrinseco dello Zmap
Frame3d frPrismInt = GetToLoc( frPrismoid, m_MapFrame) ;
BBox3d b3PrismI = GetToGlob( b3PrismL, frPrismInt) ;
// BBox dello Zmap nel suo riferimento intrinseco
BBox3d b3Zmap( ORIG, Point3d( m_nNx[0] * m_dStep, m_nNy[0] * m_dStep, m_dMaxZ[0])) ;
BBox3d b3Int ;
// Se i box non si si sovrappongono, ho finito.
if ( ! b3Zmap.FindIntersection( b3GenPyrBox, b3Int))
// Se i box non interferiscono, posso uscire
if ( ! b3Zmap.Overlaps( b3PrismI) || ! b3Zmap.Overlaps( frPrismInt, b3PrismL))
return true ;
BBox3d b3Int ;
if ( ! b3Zmap.FindIntersection( b3PrismI, b3Int))
return true ;
if ( ! bPrecise) {
// Limiti su indici
// Limiti su indici
int nStI = Clamp( int( b3Int.GetMin().x / m_dStep), 0, m_nNx[0] - 1) ;
int nEnI = Clamp( int( b3Int.GetMax().x / m_dStep), 0, m_nNx[0] - 1) ;
int nStJ = Clamp( int( b3Int.GetMin().y / m_dStep), 0, m_nNy[0] - 1) ;
int nEnJ = Clamp( int( b3Int.GetMax().y / m_dStep), 0, m_nNy[0] - 1) ;
// Ciclo di intersezione dei dexel con il cilindro (nel riferimento intrinseco)
// Ciclo di intersezione dei dexel con il cilindro (nel riferimento intrinseco)
for ( int i = nStI ; i <= nEnI ; ++ i) {
for ( int j = nStJ ; j <= nEnJ ; ++ j) {
int nPos = j * m_nNx[0] + i ;
@@ -1688,7 +1705,7 @@ VolZmap::AvoidSimpleRectPrismoid( const Frame3d& frPrismoid, double dLenghtBaseX
double dStU, dEnU ;
Point3d ptSegSt = ptLineSt + m_Values[0][nPos][0].dMin * Z_AX ;
Point3d ptSegEn = ptLineSt + m_Values[0][nPos][nSize-1].dMax * Z_AX ;
if ( RectPrismoidSegmentCollisionPlus( frMyFrame, dLenghtBaseX, dLenghtBaseY, dLenghtTopX, dLenghtTopY,
if ( RectPrismoidSegmentCollisionPlus( frPrismInt, dLenghtBaseX, dLenghtBaseY, dLenghtTopX, dLenghtTopY,
dHeight, ptSegSt, ptSegEn, dStU, dEnU)) {
for ( int nIndex = 0 ; nIndex < nSize ; nIndex += 1) {
if ( m_Values[0][nPos][nIndex].dMax >= dStU && m_Values[0][nPos][nIndex].dMin <= dEnU)
@@ -1700,11 +1717,11 @@ VolZmap::AvoidSimpleRectPrismoid( const Frame3d& frPrismoid, double dLenghtBaseX
}
}
else {
// Ciclo sulle mappe
// Ciclo sulle mappe
for ( int nMap = 0 ; nMap < m_nMapNum ; ++ nMap) {
Point3d ptInfIntBox = b3Int.GetMin();
Point3d ptSupIntBox = b3Int.GetMax();
// Dal sistema intrinseco al sistema griglia (per la prima griglia coincidono).
// Dal sistema intrinseco al sistema griglia (per la prima griglia coincidono).
if ( nMap == 1) {
swap( ptInfIntBox.x, ptInfIntBox.z) ;
swap( ptInfIntBox.x, ptInfIntBox.y) ;
@@ -1717,7 +1734,7 @@ VolZmap::AvoidSimpleRectPrismoid( const Frame3d& frPrismoid, double dLenghtBaseX
swap( ptSupIntBox.y, ptSupIntBox.z) ;
swap( ptSupIntBox.x, ptSupIntBox.y) ;
}
// Limiti su indici
// Limiti su indici
int nStI = Clamp( int( ptInfIntBox.x / m_dStep), 0, m_nNx[nMap] - 1) ;
int nEnI = Clamp( int( ptSupIntBox.x / m_dStep), 0, m_nNx[nMap] - 1) ;
int nStJ = Clamp( int( ptInfIntBox.y / m_dStep), 0, m_nNy[nMap] - 1) ;
@@ -1726,18 +1743,18 @@ VolZmap::AvoidSimpleRectPrismoid( const Frame3d& frPrismoid, double dLenghtBaseX
int nSize = int( m_Values[nMap][nDex].size()) ;
if ( nSize == 0)
continue ;
// Indici del dexel
// Indici del dexel
int nI = nDex % m_nNx[nMap] ;
int nJ = nDex / m_nNx[nMap] ;
// Se fuori dalla regione ammissibile salto l'iterazione
// Se fuori dalla regione ammissibile salto l'iterazione
if ( nI < nStI || nI > nEnI || nJ < nStJ || nJ > nEnJ)
continue ;
// Posizione del dexel
// Posizione del dexel
double dX = ( nI + 0.5) * m_dStep ;
double dY = ( nJ + 0.5) * m_dStep ;
Point3d ptLineSt( dX, dY, 0.) ;
Vector3d vtLineDir( 0., 0., 1.) ;
// Dal sistema griglia al sistema intrinseco (per la prima griglia coincidono).
// Dal sistema griglia al sistema intrinseco (per la prima griglia coincidono).
if ( nMap == 1) {
swap( ptLineSt.x, ptLineSt.y) ;
swap( ptLineSt.x, ptLineSt.z) ;
@@ -1753,7 +1770,7 @@ VolZmap::AvoidSimpleRectPrismoid( const Frame3d& frPrismoid, double dLenghtBaseX
double dStU, dEnU ;
Point3d ptSegSt = ptLineSt + m_Values[nMap][nDex][0].dMin * vtLineDir ;
Point3d ptSegEn = ptLineSt + m_Values[nMap][nDex][nSize-1].dMax * vtLineDir ;
if ( RectPrismoidSegmentCollisionPlus( frMyFrame, dLenghtBaseX, dLenghtBaseY, dLenghtTopX, dLenghtTopY,
if ( RectPrismoidSegmentCollisionPlus( frPrismInt, dLenghtBaseX, dLenghtBaseY, dLenghtTopX, dLenghtTopY,
dHeight, ptSegSt, ptSegEn, dStU, dEnU)) {
for ( int nIndex = 0 ; nIndex < nSize ; nIndex += 1) {
if ( m_Values[nMap][nDex][nIndex].dMax >= dStU && m_Values[nMap][nDex][nIndex].dMin <= dEnU)
@@ -1893,36 +1910,44 @@ VolZmap::AvoidRectPrismoid( const Frame3d& frPrismoid, double dLenghtBaseX, doub
bool
VolZmap::AvoidSimpleTorus( const Frame3d& frTorus, double dMaxRad, double dMinRad, bool bPrecise) const
{
// Porto il toro nel sistema intrinseco dello Zmap.
Point3d ptMyCen = frTorus.Orig() ;
Vector3d vtMyAx = frTorus.VersZ() ;
ptMyCen.ToLoc( m_MapFrame) ;
vtMyAx.ToLoc( m_MapFrame) ;
// BBox del toro in locale
BBox3d b3TorusL( Point3d( -dMaxRad - dMinRad, -dMaxRad - dMinRad, -dMinRad),
Point3d( dMaxRad + dMinRad, dMaxRad + dMinRad, dMinRad)) ;
// BBox del toro
BBox3d b3Box( ptMyCen) ;
b3Box.Add( ptMyCen + vtMyAx * dMinRad) ;
b3Box.Add( ptMyCen - vtMyAx * dMinRad) ;
double dTotRad = dMaxRad + dMinRad ;
if ( vtMyAx.IsXplus() || vtMyAx.IsXminus())
b3Box.Expand( 0, dTotRad, dTotRad) ;
else if ( vtMyAx.IsYplus() || vtMyAx.IsYminus())
b3Box.Expand( dTotRad, 0, dTotRad) ;
else if ( vtMyAx.IsZplus() || vtMyAx.IsZminus())
b3Box.Expand( dTotRad, dTotRad, 0) ;
else {
double dExpandX = dTotRad * sqrt( 1 - vtMyAx.x * vtMyAx.x) ;
double dExpandY = dTotRad * sqrt( 1 - vtMyAx.y * vtMyAx.y) ;
double dExpandZ = dTotRad * sqrt( 1 - vtMyAx.z * vtMyAx.z) ;
b3Box.Expand( dExpandX, dExpandY, dExpandZ) ;
}
// BBox del toro nel riferimento intrinseco dello Zmap
Frame3d frTorusInt = GetToLoc( frTorus, m_MapFrame) ;
BBox3d b3TorusI = GetToGlob( b3TorusL, frTorusInt) ;
// BBox dello Zmap nel suo riferimento intrinseco
BBox3d b3Zmap( ORIG, Point3d( m_nNx[0] * m_dStep, m_nNy[0] * m_dStep, m_dMaxZ[0])) ;
// Se non interferiscono, posso uscire
if ( ! b3Zmap.Overlaps( b3TorusI) || ! b3Zmap.Overlaps( frTorusInt, b3TorusL))
return true ;
// BBox del toro ottimizzato nel riferimento intrinseco dello Zmap
Point3d ptMyCen = frTorusInt.Orig() ;
Vector3d vtMyAx = frTorusInt.VersZ() ;
BBox3d b3Torus( ptMyCen) ;
b3Torus.Add( ptMyCen + vtMyAx * dMinRad) ;
b3Torus.Add( ptMyCen - vtMyAx * dMinRad) ;
double dTotRad = dMaxRad + dMinRad ;
if ( vtMyAx.IsX())
b3Torus.Expand( 0, dTotRad, dTotRad) ;
else if ( vtMyAx.IsY())
b3Torus.Expand( dTotRad, 0, dTotRad) ;
else if ( vtMyAx.IsZ())
b3Torus.Expand( dTotRad, dTotRad, 0) ;
else {
double dExpandX = dTotRad * sqrt( 1 - vtMyAx.x * vtMyAx.x) ;
double dExpandY = dTotRad * sqrt( 1 - vtMyAx.y * vtMyAx.y) ;
double dExpandZ = dTotRad * sqrt( 1 - vtMyAx.z * vtMyAx.z) ;
b3Torus.Expand( dExpandX, dExpandY, dExpandZ) ;
}
// Se non interferiscono, posso uscire
BBox3d b3Int ;
if ( ! b3Zmap.FindIntersection( b3Box, b3Int))
if ( ! b3Zmap.FindIntersection( b3Torus, b3Int))
return true ;
// Se verifico solo prima mappa
+2 -10
View File
@@ -2047,14 +2047,6 @@ VolZmap::ExtMarchingCubes( int nBlock, VoxelContainer& vVox) const
else {
if ( nVertComp[nComp] == 5) {
double dDotAvarage = 0.;
for (int m = 0; m < nVertComp[nComp] - 1; ++m) {
for (int l = m + 1 ; l < nVertComp[nComp]; ++l) {
dDotAvarage += CompoVert[nComp][m].vtVec * CompoVert[nComp][l].vtVec;
}
}
dDotAvarage /= (( nVertComp[nComp] * ( nVertComp[nComp] - 1)) / 2) ;
int nNumPar = 0 ;
for ( int m = 0 ; m < nVertComp[nComp] - 1 ; ++ m) {
for ( int l = m + 1 ; l < nVertComp[nComp] ; ++ l) {
@@ -2062,9 +2054,9 @@ VolZmap::ExtMarchingCubes( int nBlock, VoxelContainer& vVox) const
++ nNumPar ;
}
}
bExtConfirmed = nNumPar == 3 ;
bExtConfirmed = ( nNumPar == 3) ;
}
else if (nVertComp[nComp] < 5) {
else if ( nVertComp[nComp] < 5) {
bExtConfirmed = false ;
}
}