//---------------------------------------------------------------------------- // EgalTech 2020-2024 //---------------------------------------------------------------------------- // File : CDeCylClosedSurfTm.cpp Data : 24.03.24 Versione : 2.6c2 // Contenuto : Implementazione della verifica di collisione tra // Cylinder e Closed SurftriMesh. // // // Modifiche : 09.01.20 DS Creazione modulo. // 24.03.24 DS Aggiunta TestCylSurfTm. // //---------------------------------------------------------------------------- //--------------------------- Include ---------------------------------------- #include "stdafx.h" #include "CDeCylTria.h" #include "/EgtDev/Include/EGkCDeCylClosedSurfTm.h" #include "/EgtDev/Include/EGkDistPointSurfTm.h" using namespace std ; //---------------------------------------------------------------------------- // Il sistema di riferimento deve avere l'asse di simmetria del cilindro come asse Z e origine nel centro della base o del top. // La distanza di sicurezza ha effetto solo se maggiore di EPS_SMALL, altrimenti è ignorata ed è ininfluente. // Il sistema di riferimento del cilindro è riferito a quello della superficie. // La funzione restituisce : // - true in caso di collisione o inconsistenza dei parametri di input // - false in caso di assenza di collisione. //---------------------------------------------------------------------------- bool CDeCylClosedSurfTm( const Frame3d& frCyl, double dR, double dH, const ISurfTriMesh& Stm, double dSafeDist) { // Il cilindro deve essere ben definito if ( dR < EPS_SMALL || dH < EPS_SMALL) return true ; // Se superficie non valida o aperta, non ha senso proseguire if ( ! Stm.IsValid() || ! Stm.IsClosed()) return true ; // Recupero BBox del poliedro BBox3d b3Poly = Stm.GetAllTriaBox() ; // Sistemazioni cilindro Frame3d frMyCyl = frCyl ; if ( dH < 0) { frMyCyl.Translate( dH * frMyCyl.VersZ()) ; dH = -dH ; } // Calcolo il BBox del cilindro BBox3d b3CylL( Point3d( -dR, -dR, 0), Point3d( dR, dR, dH)) ; if ( dSafeDist > EPS_SMALL) b3CylL.Expand( dSafeDist) ; BBox3d b3Cyl = GetToGlob( b3CylL, frMyCyl) ; // Se i BBox non interferiscono, non c'è collisione if ( ! b3Poly.Overlaps( b3Cyl) || ! b3Poly.Overlaps( frMyCyl, b3CylL)) return false ; // 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( frMyCyl, dR, dH, Tria, dSafeDist)) return true ; } } // 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( frMyCyl) ; DistPointSurfTm DistCylCenSurfCalc( ptCylCen, Stm) ; // Se il cilindro è interno c'è collisione return ( DistCylCenSurfCalc.IsPointInside()) ; } //---------------------------------------------------------------------------- // Verifica l'interferenza tra il cilindro e la superficie : restituisce true in caso di interferenza //---------------------------------------------------------------------------- bool TestCylSurfTm( const Frame3d& frCyl, double dR, double dH, const ISurfTriMesh& Stm, double dSafeDist) { // Il cilindro deve essere ben definito if ( dR < EPS_SMALL || dH < EPS_SMALL) return true ; // Se superficie non valida, non ha senso proseguire if ( ! Stm.IsValid()) return true ; // Recupero BBox della superficie poligonale BBox3d b3Poly = Stm.GetAllTriaBox() ; // Sistemazioni cilindro Frame3d frMyCyl = frCyl ; if ( dH < 0) { frMyCyl.Translate( dH * frMyCyl.VersZ()) ; dH = -dH ; } // Calcolo il BBox del cilindro BBox3d b3CylL( Point3d( -dR, -dR, 0), Point3d( dR, dR, dH)) ; if ( dSafeDist > EPS_SMALL) b3CylL.Expand( dSafeDist) ; BBox3d b3Cyl = GetToGlob( b3CylL, frMyCyl) ; // Se i BBox non interferiscono, non c'è interferenza if ( ! b3Poly.Overlaps( b3Cyl) || ! b3Poly.Overlaps( frMyCyl, b3CylL)) return false ; // 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( frMyCyl, dR, dH, Tria, dSafeDist)) return true ; } } // Non c'è interferenza return false ; }