//---------------------------------------------------------------------------- // EgalTech 2020-2020 //---------------------------------------------------------------------------- // File : CDePyramidTria.cpp Data : 29.10.20 Versione : 2.2k1 // Contenuto : Implementazione della verifica di collisione tra // Pyramid e Triangle3d. // // // Modifiche : 29.10.20 LM Creazione modulo. // // //---------------------------------------------------------------------------- //--------------------------- Include ---------------------------------------- #include "stdafx.h" #include "EgtDev/Include/EGkCDePyramidTria.h" #include "EgtDev/Include/EGkIntersTriaTria.h" //---------------------------------------------------------------------------- // Il sistema di riferimento deve avere l'origine nel centro della base Base, asse X lungo // un segmento della stessa e asse Z ortogonale alle basi e diretta verso la base Top. bool CDePyramidTria( const Frame3d& frPyrFrame, double dLenghtBaseX, double dLenghtBaseY, double dLenghtTopX, double dLenghtTopY, double dHeight, double dSafeDist, const Triangle3d& trTria) { // Se il tronco di piramide o il triangolo non sono ben definiti non procedo if ( dLenghtBaseX < EPS_SMALL || dLenghtBaseY < EPS_SMALL || dLenghtTopX < EPS_SMALL || dLenghtTopY < EPS_SMALL || dHeight < EPS_SMALL || ! trTria.IsValid()) return false ; Frame3d frMyFrame = frPyrFrame ; // Se la distanza di sicurezza è maggiore di epsilon aumento le dimensioni del tronco di piramide. if ( dSafeDist > EPS_SMALL) { dLenghtBaseX += dSafeDist ; dLenghtBaseY += dSafeDist ; dLenghtTopX += dSafeDist ; dLenghtTopY += dSafeDist ; dHeight += ( 2 * dSafeDist) ; frMyFrame.Translate( - dSafeDist * frMyFrame.VersZ()) ; } // Porto il triangolo nel sistema di riferimento del tronco di cono Triangle3d trMyTria = trTria ; trMyTria.ToLoc( frMyFrame) ; // Se almeno un vertice collide ho finito for ( int nV = 0 ; nV < 3 ; ++ nV) { Point3d ptVert = trMyTria.GetP( nV) ; if ( ptVert.z > - EPS_SMALL && ptVert.z < dHeight + EPS_SMALL && ( ptVert.x + dLenghtBaseX + EPS_SMALL) * dHeight > ( dLenghtBaseX - dLenghtTopX) * ptVert.z && ( ptVert.x - dLenghtBaseX - EPS_SMALL) * dHeight < ( dLenghtTopX - dLenghtBaseX) * ptVert.z && ( ptVert.y + dLenghtBaseY + EPS_SMALL) * dHeight > ( dLenghtBaseY - dLenghtTopY) * ptVert.z && ( ptVert.y - dLenghtBaseY - EPS_SMALL) * dHeight < ( dLenghtTopY - dLenghtBaseY) * ptVert.z) return true ; } // Se c'è collisione con almeno un triangolo delle facce ho finito double dHalfBaseX = 0.5 * dLenghtBaseX ; double dHalfBaseY = 0.5 * dLenghtBaseY ; double dHalfTopX = 0.5 * dLenghtTopX ; double dHalfTopY = 0.5 * dLenghtTopY ; Triangle3d trFaceTria1, trFaceTria2 ; // Faccia base trFaceTria1.Set( Point3d( - dHalfBaseX, - dHalfBaseY, 0.), Point3d( - dHalfBaseX, dHalfBaseY, 0.), Point3d( dHalfBaseX, dHalfBaseY, 0.)) ; trFaceTria1.Validate() ; trFaceTria2.Set( Point3d( - dHalfBaseX, - dHalfBaseY, 0.), Point3d( dHalfBaseX, dHalfBaseY, 0.), Point3d( dHalfBaseX, - dHalfBaseY, 0.)) ; trFaceTria2.Validate() ; if ( IntersTriaTria( trMyTria, trFaceTria1, Point3d(), Point3d(), TRIA3DVECTOR()) != ITTT_NO || IntersTriaTria( trMyTria, trFaceTria2, Point3d(), Point3d(), TRIA3DVECTOR()) != ITTT_NO) return true ; // Faccia top trFaceTria1.Set( Point3d( - dHalfTopX, - dHalfTopY, dHeight), Point3d( dHalfTopX, dHalfTopY, dHeight), Point3d( - dHalfTopX, dHalfTopY, dHeight)) ; trFaceTria1.Validate() ; trFaceTria2.Set( Point3d( - dHalfTopX, - dHalfTopY, dHeight), Point3d( dHalfTopX, - dHalfTopY, dHeight), Point3d( dHalfTopX, dHalfTopY, dHeight)) ; trFaceTria2.Validate() ; if ( IntersTriaTria( trMyTria, trFaceTria1, Point3d(), Point3d(), TRIA3DVECTOR()) != ITTT_NO || IntersTriaTria( trMyTria, trFaceTria2, Point3d(), Point3d(), TRIA3DVECTOR()) != ITTT_NO) return true ; // Faccia laterale 1 trFaceTria1.Set( Point3d( - dHalfBaseX, - dHalfBaseY, 0.), Point3d( dHalfTopX , - dHalfTopY , dHeight), Point3d( - dHalfTopX , - dHalfTopY , dHeight)) ; trFaceTria1.Validate() ; trFaceTria2.Set( Point3d( - dHalfBaseX, - dHalfBaseY, 0.), Point3d( dHalfBaseX, - dHalfBaseY, 0.), Point3d( dHalfTopX, - dHalfTopY , dHeight)) ; trFaceTria2.Validate() ; if ( IntersTriaTria( trMyTria, trFaceTria1, Point3d(), Point3d(), TRIA3DVECTOR()) != ITTT_NO || IntersTriaTria( trMyTria, trFaceTria2, Point3d(), Point3d(), TRIA3DVECTOR()) != ITTT_NO) return true ; // Faccia laterale 2 trFaceTria1.Set( Point3d( dHalfBaseX, - dHalfBaseY, 0.), Point3d( dHalfTopX , dHalfTopY , dHeight), Point3d( dHalfTopX , - dHalfTopY , dHeight)) ; trFaceTria1.Validate() ; trFaceTria2.Set( Point3d( dHalfBaseX, - dHalfBaseY, 0.), Point3d( dHalfBaseX, dHalfBaseY, 0.), Point3d( dHalfTopX , dHalfTopY , dHeight)) ; trFaceTria2.Validate() ; if ( IntersTriaTria(trMyTria, trFaceTria1, Point3d(), Point3d(), TRIA3DVECTOR()) != ITTT_NO || IntersTriaTria(trMyTria, trFaceTria2, Point3d(), Point3d(), TRIA3DVECTOR()) != ITTT_NO) return true ; // Faccia laterale 3 trFaceTria1.Set( Point3d( dHalfBaseX, dHalfBaseY, 0.), Point3d( - dHalfTopX , dHalfTopY , dHeight), Point3d( dHalfTopX , dHalfTopY , dHeight)) ; trFaceTria1.Validate() ; trFaceTria2.Set( Point3d( dHalfBaseX, dHalfBaseY, 0.), Point3d( - dHalfBaseX, dHalfBaseY, 0.), Point3d( - dHalfTopX , dHalfTopY , dHeight)) ; trFaceTria2.Validate() ; if ( IntersTriaTria( trMyTria, trFaceTria1, Point3d(), Point3d(), TRIA3DVECTOR()) != ITTT_NO || IntersTriaTria( trMyTria, trFaceTria2, Point3d(), Point3d(), TRIA3DVECTOR()) != ITTT_NO) return true ; // Faccia laterale 4 trFaceTria1.Set( Point3d( - dHalfBaseX, dHalfBaseY, 0.), Point3d( - dHalfTopX , - dHalfTopY , dHeight), Point3d( - dHalfTopX , dHalfTopY , dHeight)) ; trFaceTria1.Validate() ; trFaceTria2.Set( Point3d( - dHalfBaseX, dHalfBaseY, 0.), Point3d( - dHalfBaseX, - dHalfBaseY, 0.), Point3d( - dHalfTopX , - dHalfTopY , dHeight)) ; trFaceTria2.Validate() ; if ( IntersTriaTria( trMyTria, trFaceTria1, Point3d(), Point3d(), TRIA3DVECTOR()) != ITTT_NO || IntersTriaTria( trMyTria, trFaceTria2, Point3d(), Point3d(), TRIA3DVECTOR()) != ITTT_NO) return true ; return false ; }