//---------------------------------------------------------------------------- // EgalTech 2020-2020 //---------------------------------------------------------------------------- // File : EGkCDeConvexTorusTria.cpp Data : 10.11.20 Versione : // Contenuto : Implementazione funzione verifica collisione tra // toro convesso e Triangle3d. // // Modifiche : 10.11.20 LM Creazione modulo. // // //---------------------------------------------------------------------------- #include "stdafx.h" #include "GeoConst.h" #include "CurveArc.h" #include "CDeConvexTorusTria.h" #include "CDeConeFrustumTria.h" using namespace std ; //---------------------------------------------------------------------------- // Il toro convesso è il disco limitato dalla sola parte esterna del toro. // Raggio principale R1, raggio secondario R2. // Il toro è posto nel piano XY del suo riferimento, centrato sull'origine. // Si può considerare la sola parte inferiore, quella superiore o tutto il toro. // La funzione restituisce true in caso di collisione. //---------------------------------------------------------------------------- bool CDeSimpleConvexTorusTria( const Frame3d& frTorus, double dRad1, double dRad2, int nCtType, const Triangle3d& trTria) { // I raggi devono essere non nulli e il triangolo ben definito. if ( dRad1 < EPS_SMALL || dRad2 < EPS_SMALL || ! trTria.IsValid()) return false ; // Definisco il profilo esterno ad arco CurveArc crvOutLine ; switch ( nCtType) { case CT_INF : crvOutLine.Set( Point3d( dRad1, 0, 0), -Y_AX, dRad2, -Z_AX, 90, 0) ; break ; case CT_SUP : crvOutLine.Set( Point3d( dRad1, 0, 0), -Y_AX, dRad2, X_AX, 90, 0) ; break ; case CT_TOT : crvOutLine.Set( Point3d( dRad1, 0, 0), -Y_AX, dRad2, -Z_AX, 180, 0) ; break ; default : return false ; } // Porto il triangolo nel sistema di riferimento del toro. Triangle3d trMyTria = trTria ; trMyTria.ToLoc( frTorus) ; // Approssimo il profilo con una polilinea PolyLine plyApprox ; if ( ! crvOutLine.ApproxWithLines( LIN_TOL_STD, ANG_TOL_APPROX_DEG, ICurve::APL_STD, plyApprox)) return false ; // Verifico la collisione approssimando con tronchi di cono bool bCollision = false ; Frame3d frConus ; Point3d ptSt, ptEn ; bool bContinue = plyApprox.GetFirstPoint( ptSt) && plyApprox.GetNextPoint( ptEn) ; while ( bContinue && ! bCollision) { frConus.Set( Point3d( 0., 0., ptSt.z), Frame3d::TOP) ; bCollision = CDeSimpleConeFrustumTria( frConus, ptSt.x, ptEn.x, ptEn.z - ptSt.z, trMyTria) ; ptSt = ptEn ; bContinue = plyApprox.GetNextPoint( ptEn) ; } return bCollision ; } //---------------------------------------------------------------------------- bool CDeConvexTorusTria( const Frame3d& frTorus, double dRad1, double dRad2, int nCtType, const Triangle3d& trTria, double dSafeDist) { // I raggi devono essere non nulli e il triangolo ben definito. if ( dRad1 < EPS_SMALL || dRad2 < EPS_SMALL || ! trTria.IsValid()) return false ; return CDeSimpleConvexTorusTria( frTorus, dRad1, dRad2 + max( 0., dSafeDist), nCtType, trTria) ; }