From 2d8c815032fd34ac03482cf72837d228ad0f615f Mon Sep 17 00:00:00 2001 From: DarioS Date: Sun, 14 May 2023 11:58:48 +0200 Subject: [PATCH] =?UTF-8?q?EgtGeomKernel=202.5e3=20:=20-=20a=20BBox3d=20ag?= =?UTF-8?q?giunto=202=C2=B0=20metodo=20Overlaps=20con=20box=20aventi=20div?= =?UTF-8?q?erso=20orientamento=20-=20nelle=20funzioni=20di=20Collision=20D?= =?UTF-8?q?etection=20migliorato=20controllo=20non=20interne=20-=20nele=20?= =?UTF-8?q?funzioni=20Avoid=20di=20Zmap=20si=20utilizza=20confronto=20box?= =?UTF-8?q?=20con=20diverso=20orientamento.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BBox3d.cpp | 130 +++++++++++++---- CAvToolSurfTm.cpp | 6 +- CDeBoxClosedSurfTm.cpp | 19 +-- CDeClosedSurfTmClosedSurfTm.cpp | 51 +++---- CDeConeFrustumClosedSurfTm.cpp | 16 ++- CDeConvexTorusClosedSurfTm.cpp | 34 ++--- CDeCylClosedSurfTm.cpp | 30 ++-- CDeRectPrismoidClosedSurfTm.cpp | 18 ++- CDeSpheClosedSurfTm.cpp | 13 +- EgtGeomKernel.rc | Bin 11710 -> 11710 bytes VolZmapCalculus.cpp | 243 ++++++++++++++++++-------------- VolZmapGraphics.cpp | 12 +- 12 files changed, 341 insertions(+), 231 deletions(-) diff --git a/BBox3d.cpp b/BBox3d.cpp index 12b14fe..2d67e7f 100644 --- a/BBox3d.cpp +++ b/BBox3d.cpp @@ -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 ; } diff --git a/CAvToolSurfTm.cpp b/CAvToolSurfTm.cpp index d03bc8a..ba73ba0 100644 --- a/CAvToolSurfTm.cpp +++ b/CAvToolSurfTm.cpp @@ -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) ; diff --git a/CDeBoxClosedSurfTm.cpp b/CDeBoxClosedSurfTm.cpp index ca39b66..6b29905 100644 --- a/CDeBoxClosedSurfTm.cpp +++ b/CDeBoxClosedSurfTm.cpp @@ -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) ; diff --git a/CDeClosedSurfTmClosedSurfTm.cpp b/CDeClosedSurfTmClosedSurfTm.cpp index d625dc6..81bdc5a 100644 --- a/CDeClosedSurfTmClosedSurfTm.cpp +++ b/CDeClosedSurfTmClosedSurfTm.cpp @@ -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) ; diff --git a/CDeConeFrustumClosedSurfTm.cpp b/CDeConeFrustumClosedSurfTm.cpp index b01fcb3..f425e18 100644 --- a/CDeConeFrustumClosedSurfTm.cpp +++ b/CDeConeFrustumClosedSurfTm.cpp @@ -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) ; diff --git a/CDeConvexTorusClosedSurfTm.cpp b/CDeConvexTorusClosedSurfTm.cpp index c8ef0b0..280cd13 100644 --- a/CDeConvexTorusClosedSurfTm.cpp +++ b/CDeConvexTorusClosedSurfTm.cpp @@ -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()) ; diff --git a/CDeCylClosedSurfTm.cpp b/CDeCylClosedSurfTm.cpp index 6bbe5d2..f8feab3 100644 --- a/CDeCylClosedSurfTm.cpp +++ b/CDeCylClosedSurfTm.cpp @@ -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()) ; diff --git a/CDeRectPrismoidClosedSurfTm.cpp b/CDeRectPrismoidClosedSurfTm.cpp index 62e9da8..0c1d1e0 100644 --- a/CDeRectPrismoidClosedSurfTm.cpp +++ b/CDeRectPrismoidClosedSurfTm.cpp @@ -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()) ; } diff --git a/CDeSpheClosedSurfTm.cpp b/CDeSpheClosedSurfTm.cpp index cfbdec9..e6ab0c8 100644 --- a/CDeSpheClosedSurfTm.cpp +++ b/CDeSpheClosedSurfTm.cpp @@ -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()) ; } diff --git a/EgtGeomKernel.rc b/EgtGeomKernel.rc index 50d8062ddc566051bbd4be8078da6498feab407a..f04937a9fbeea82f9a67ba1720cb87e0af740d31 100644 GIT binary patch delta 94 zcmdlNy)SyhFE&Qw&A-_cnHh~ID{|{@_Trkr0u;H;XNwSVW8B;$>;>dw2zN+>g;Df- LFmBFL4&ed-W11TR delta 94 zcmdlNy)SyhFE&P_&A-_cnHh~HD{|{@_Trkr0u;H;XNwSVW8B;$>;>dw2zN+>g;Df- LFmBFL4&ed-Vf-5U diff --git a/VolZmapCalculus.cpp b/VolZmapCalculus.cpp index 9f4f8cd..c24fd29 100644 --- a/VolZmapCalculus.cpp +++ b/VolZmapCalculus.cpp @@ -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 diff --git a/VolZmapGraphics.cpp b/VolZmapGraphics.cpp index 077f084..fb5b8eb 100644 --- a/VolZmapGraphics.cpp +++ b/VolZmapGraphics.cpp @@ -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 ; } }