diff --git a/IntersLineTria.cpp b/IntersLineTria.cpp index 7365212..09136b0 100644 --- a/IntersLineTria.cpp +++ b/IntersLineTria.cpp @@ -1,13 +1,13 @@ //---------------------------------------------------------------------------- -// EgalTech 2015-2017 +// EgalTech 2015-2020 //---------------------------------------------------------------------------- -// File : IntersLineTria.cpp Data : 16.10.17 Versione : 1.8j4 +// File : IntersLineTria.cpp Data : 16.06.20 Versione : 2.2f4 // Contenuto : Implementazione della intersezione linea/triangolo. // // // // Modifiche : 18.02.15 DS Creazione modulo. -// +// 16.06.20 LM Migliorie a IntersCoplanarLineTria quando linea finita. // //---------------------------------------------------------------------------- @@ -83,7 +83,7 @@ IntersCoplanarLineTria( const Point3d& ptL, const Vector3d& vtL, double dLen, co for ( int i = 0 ; i < 3 ; ++i) vDist[i] = ( trTria.GetP( i) - ptL) * vtN ; // verifico posizione del triangolo rispetto alla retta - array vPos = { 0, 0, 0} ; + array< int, 3> vPos = { 0, 0, 0} ; int nVertPos = 0 ; int nVertNeg = 0 ; for ( int i = 0 ; i < 3 ; ++i) { if ( vDist[i] > EPS_SMALL) { @@ -95,6 +95,29 @@ IntersCoplanarLineTria( const Point3d& ptL, const Vector3d& vtL, double dLen, co ++ nVertNeg ; } } + // Se segmento, calcolo le distanze dei suoi estremi dai lati del triangolo + int nSegOnSide = -1 ; + // if ( bFinite) { + if ( false) { + for ( int i = 0 ; i < 3 ; ++ i) { + // Versore del lato del triangolo + Vector3d vtSideDir = trTria.GetP( ( i + 1) % 3) - trTria.GetP( i) ; + vtSideDir.Normalize() ; + // Versore che punta verso l'esterno del triangolo + Vector3d vtExtN = vtSideDir ^ trTria.GetN() ; + vtExtN.Normalize() ; + // Estremi del segmento + Point3d ptSt = ptL ; + Point3d ptEn = ptL + dLen * vtL ; + // Distanze con segno degli estremi del segmento dal lato del triangolo + double dDistSt = ( ptSt - trTria.GetP( i)) * vtExtN ; + double dDistEn = ( ptEn - trTria.GetP( i)) * vtExtN ; + if ( abs( dDistSt) < EPS_SMALL && abs( dDistEn) < EPS_SMALL && abs( vtL * vtExtN) < COS_ORTO_ANG_SMALL) { + nSegOnSide = i ; + break ; + } + } + } // Se il triangolo giace tutto da una parte della retta, nessuna intersezione if ( nVertPos == 3 || nVertNeg == 3) { return ILTT_NO ; @@ -144,6 +167,47 @@ IntersCoplanarLineTria( const Point3d& ptL, const Vector3d& vtL, double dLen, co } } } + // se altrimenti due estremi del segmento giacciono su un lato del triangolo + else if ( nSegOnSide == 0 || nSegOnSide == 1 || nSegOnSide == 2) { + // Punto iniziale e versore del segmento del triangolo orientato secondo il segmento + Point3d ptT ; + Vector3d vtT ; + if ( vtL * ( trTria.GetP( ( nSegOnSide + 1) % 3) - trTria.GetP( nSegOnSide)) > 0.) { + ptT = trTria.GetP( nSegOnSide) ; + vtT = trTria.GetP( ( nSegOnSide + 1) % 3) - trTria.GetP( nSegOnSide) ; + } + else { + ptT = trTria.GetP( ( nSegOnSide + 1) % 3) ; + vtT = trTria.GetP( nSegOnSide) - trTria.GetP( ( nSegOnSide + 1) % 3) ; + } + double dTriaSegLen = vtT.Len() ; + vtT /= dTriaSegLen ; + ptInt = ptL ; + ptInt2 = ptL + dLen * vtL ; + double dUmin = ( ptInt - ptT) * vtT ; + double dUmax = ( ptInt2 - ptT) * vtT ; + // se massimo coincide con inizio segmento di retta + if ( abs( dUmax) < EPS_SMALL) { + ptInt = ptInt2 ; + return ILTT_VERT ; + } + // se minimo coincide con fine segmento di retta + else if ( abs( dUmin - dTriaSegLen) < EPS_SMALL) { + return ILTT_VERT ; + } + // se segmento non si sovrappone + else if ( dUmax < 0 || dUmin > dTriaSegLen) { + return ILTT_NO ; + } + // altrimenti sovrapposizione parziale + else { + if ( dUmin < 0) + ptInt = ptT ; + if ( dUmax > dTriaSegLen) + ptInt2 = ptT + vtT * dTriaSegLen ; + return ILTT_SEGM_ON_EDGE ; + } + } // se altrimenti due vertici del triangolo giacciono sulla linea else if ( nVertPos + nVertNeg == 1) { // Determino i vertici sulla linea