07b1f21ecd
- aggiunta IntersSurfTmSurfTm - correzioni a HashGrids.
149 lines
5.3 KiB
C++
149 lines
5.3 KiB
C++
//----------------------------------------------------------------------------
|
|
// 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 <array>
|
|
|
|
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 ;
|
|
}
|