//---------------------------------------------------------------------------- // EgalTech 2018-2018 //---------------------------------------------------------------------------- // File : IntersTriaTria.cpp Data : 27.08.18 Versione : 1.9h3 // Contenuto : Implementazione della intersezione triangolo/triangolo. // // // // Modifiche : 27.08.18 DS Creazione modulo. // // //---------------------------------------------------------------------------- //--------------------------- Include ---------------------------------------- #include "stdafx.h" #include "ProjPlane.h" #include "IntersLineTria.h" #include "/EgtDev/Include/EGkIntersTriaTria.h" #include "/EgtDev/Include/EGkIntersPlanePlane.h" #include using namespace std ; //---------------------------------------------------------------------------- static int IntersCoplanarTriaTria( const Triangle3d& trTria1, const Triangle3d& trTria2, PNTVECTOR& vPnt) ; //---------------------------------------------------------------------------- int IntersTriaTria( const Triangle3d& trTria1, const Triangle3d& trTria2, Point3d& ptInt, Point3d& ptInt2, PNTVECTOR& vPnt) { // piano del secondo triangolo Plane3d plTria2 ; plTria2.Set( trTria2.GetCentroid(), trTria2.GetN()) ; // calcolo le distanze dei vertici del primo triangolo dal piano del secondo array< double, 3> vDist1 ; for ( int i = 0 ; i < 3 ; ++i) vDist1[i] = DistPointPlane( trTria1.GetP( i), plTria2) ; // verifico posizione del primo triangolo rispetto al piano del secondo int nVertPos1 = 0 ; int nVertNeg1 = 0 ; for ( const auto& dDist : vDist1) { if ( dDist > EPS_SMALL) ++ nVertPos1 ; else if ( dDist < -EPS_SMALL) ++ nVertNeg1 ; } // se il triangolo giace tutto da una parte del piano, nessuna intersezione if ( nVertPos1 == 3 || nVertNeg1 == 3) return ITTT_NO ; // piano del primo triangolo Plane3d plTria1 ; plTria1.Set( trTria1.GetCentroid(), trTria1.GetN()) ; // calcolo le distanze dei vertici del secondo triangolo dal piano del primo array< double, 3> vDist2 ; for ( int i = 0 ; i < 3 ; ++i) vDist2[i] = DistPointPlane( trTria2.GetP( i), plTria1) ; // verifico posizione del secondo triangolo rispetto al piano del primo int nVertPos2 = 0 ; int nVertNeg2 = 0 ; for ( const auto& dDist : vDist2) { if ( dDist > EPS_SMALL) ++ nVertPos2 ; else if ( dDist < -EPS_SMALL) ++ nVertNeg2 ; } // se il triangolo giace tutto da una parte del piano, nessuna intersezione if ( nVertPos2 == 3 || nVertNeg2 == 3) return ITTT_NO ; // se i triangoli sono complanari if ( ( nVertPos1 == 0 && nVertNeg1 == 0) || ( nVertPos2 == 0 && nVertNeg2 == 0)) return IntersCoplanarTriaTria( trTria1, trTria2, vPnt) ; // intersezione tra i piani dei due triangoli Point3d ptL1 ; Vector3d vtL1 ; if ( IntersPlanePlane( plTria1, plTria2, ptL1, vtL1) != IPPT_YES) return ITTT_NO ; // limito la linea di intersezione con il primo triangolo int nRes1 = IntersCoplanarLineTria( ptL1, vtL1, 100.0, trTria1, ptInt, ptInt2, false) ; switch ( nRes1) { case ILTT_SEGM : case ILTT_SEGM_ON_EDGE : break ; case ILTT_VERT : return ( PointInTria( ptInt, trTria2) ? ITTT_VERT : ITTT_NO) ; default : return ITTT_NO ; } // il segmento calcolato va limitato col secondo triangolo Point3d ptL2 = ptInt ; Vector3d vtL2 = ptInt2 - ptInt ; double dLen = vtL2.Len() ; vtL2 /= dLen ; int nRes2 = IntersCoplanarLineTria( ptL2, vtL2, dLen, trTria2, ptInt, ptInt2, true) ; switch( nRes2) { case ILTT_NO : return ITTT_NO ; case ILTT_SEGM : return ITTT_YES ; case ILTT_SEGM_ON_EDGE : return ITTT_EDGE ; case ILTT_VERT : return ITTT_VERT ; case ILTT_EDGE : return ITTT_PNT ; default : return ITTT_NO ; } #if 0 // interseco il primo triangolo con il piano del secondo Plane3d plPlane2 ; plPlane2.Set( trTria2.GetCentroid(), trTria2.GetN()) ; int nPtRes = IntersPlaneTria( plPlane2, trTria1, ptInt, ptInt2) ; // se non c'è intersezione if ( nPtRes == IPTT_NO) return ITTT_NO ; // se altrimenti complanari else if ( nPtRes == IPTT_OVERLAPS) return IntersCoplanarTriaTria( trTria1, trTria2, vPnt) ; // se intersezione in un vertice else if ( nPtRes == IPTT_VERT) { // se l'intersezione sta anche nel secondo triangolo if ( PointInTria( ptInt, trTria2)) return ITTT_VERT ; else return ITTT_NO ; } // altrimenti è un segmento, va limitato col secondo triangolo Point3d ptL = ptInt ; Vector3d vtL = ptInt2 - ptInt ; double dLen = vtL.Len() ; vtL /= dLen ; int nRes = IntersCoplanarLineTria( ptL, vtL, dLen, trTria2, ptInt, ptInt2, true) ; switch( nRes) { case ILTT_NO : return ITTT_NO ; case ILTT_SEGM : return ITTT_YES ; case ILTT_SEGM_ON_EDGE : return ITTT_EDGE ; case ILTT_VERT : return ITTT_VERT ; case ILTT_EDGE : return ITTT_PNT ; default : return ITTT_NO ; } #endif } //---------------------------------------------------------------------------- int IntersCoplanarTriaTria( const Triangle3d& trTria1, const Triangle3d& trTria2, PNTVECTOR& vPnt) { // !!! PROVVISORIO !!! return ITTT_NO ; }