EgtGeomKernel 2.5f4 :

- corretta IntersSegmentCylinder (qui come cilindro si intende solo la superficie dello stesso)
- corretta e velocizzata AvoidSurfTm di VolZmap nel caso di test con singola map.
This commit is contained in:
DarioS
2023-06-21 08:26:21 +02:00
parent c4f1a7f97b
commit 8a3d46416d
4 changed files with 72 additions and 61 deletions
BIN
View File
Binary file not shown.
+10 -8
View File
@@ -800,7 +800,7 @@ IntersLineCylinder( const Point3d& ptPLine, const Vector3d& vtVLine,
// Parte della retta appartenente al cilindro
if ( nIntType == CC_INF_INT) {
dU1 = ( ptPCyl- ptPLine) * vtVLine ;
dU1 = ( ptPCyl - ptPLine) * vtVLine ;
// Retta e cilindro equiversi
if ( vtVCyl * vtVLine > 0)
dU2 = dU1 + dCylHeigth ;
@@ -819,8 +819,7 @@ IntersLineCylinder( const Point3d& ptPLine, const Vector3d& vtVLine,
}
// Caso di due intersezioni
else if ( nIntType == CC_TWO_INT) {
// Rigetto le soluzioni fuori dalla
// regione ammissibile del cilindro.
// Elimino le soluzioni fuori dal cilindro finito
Point3d ptInt1 = ptPLine + dU1 * vtVLine ;
Point3d ptInt2 = ptPLine + dU2 * vtVLine ;
int nSolNum = 2 ;
@@ -832,8 +831,7 @@ IntersLineCylinder( const Point3d& ptPLine, const Vector3d& vtVLine,
if ( ( ptInt2 - ptPCyl) * vtVCyl < 0 ||
( ptInt2 - ptPCyl) * vtVCyl > dCylHeigth)
-- nSolNum ;
// Dal numero di soluzioni rimaste
// aggiorno la tipologia di interferenza.
// Aggiorno il tipo di intersezione
if ( nSolNum == 1)
nIntType = CC_ONE_INT_SEC ;
else if ( nSolNum == 0)
@@ -896,8 +894,7 @@ IntersSegmentCylinder( const Point3d& ptPLine, const Vector3d& vtVLine, double d
if ( nIntType == CC_ERROR_INT)
return nIntType ;
// Parte della retta associata
// appartiene al cilindro
// Parte della retta associata appartiene al cilindro
if ( nIntType == CC_INF_INT) {
// Segmento non interferisce
if ( dU1 > dLen + EPS_SMALL)
@@ -925,7 +922,7 @@ IntersSegmentCylinder( const Point3d& ptPLine, const Vector3d& vtVLine, double d
if ( dU1 < - EPS_SMALL || dU1 > dLen + EPS_SMALL)
nIntType = CC_NO_INTERS ;
}
// Retta associata è secante
// Retta associata è secante con due punti di intersezione
else if ( nIntType == CC_TWO_INT) {
// Il segmento non interferisce
if ( dU1 > dLen + EPS_SMALL)
@@ -951,6 +948,11 @@ IntersSegmentCylinder( const Point3d& ptPLine, const Vector3d& vtVLine, double d
nIntType = CC_NO_INTERS ;
}
}
// Retta associata è secante con un punto di intersezione
else if ( nIntType == CC_ONE_INT_SEC) {
if ( dU1 < -EPS_SMALL || dU1 > dLen + EPS_SMALL)
nIntType = CC_NO_INTERS ;
}
return nIntType ;
}
+4 -5
View File
@@ -17,12 +17,11 @@
// In tutte le funzioni dichiarate i punti e i vettori che definiscono gli oggetti geometrici
// devono essere espressi nel medesimo sistema di riferimento. I vettori devono essere normalizzati.
// Il valore di ritorno è una costante intera che individua la tipologia di interferenza.
// Il valore di ritorno è una costante intera che individua la tipologia di intersezione.
// Se si verificano irregolarità, essa vale ERROR_INT.
// Per riferimento vengono restituiti i parametri lungo la retta a cui avvengono le
// intersezioni. Se non vi sono intersezioni i valori di dU1 e dU2 non hanno senso,
// se vi è un'intersezione solo il valore di dU1 ha senso. Se vi sono più intersezioni,
// dU1 e dU2 hanno entrambi senso.
// intersezioni. Se non vi sono intersezioni i valori di dU1 e dU2 non sono definiti,
// se vi è un'intersezione vale solo dU1, con due soluzioni valgono entrambi.
// Nelle routine per la semi-sfera come argomento appare un versore, che ne individua l'orientazione
// nello spazio. Si immagini uno spazio con origine nel centro della sfera e asse Z diretto come tale
// versore. La sfera è divisa in due parti: una nel semi spazio Z+ e una in quello Z-.
@@ -130,7 +129,7 @@ int IntersRayInfiniteCylinder( const Point3d& ptPLine, const Vector3d& vtVLine,
//----------------------------------------------------------------------------
// Valuta la posizione reciproca fra un cilindro infinito e un segmento.
// Nel caso in cui il sgmento giaccia sul cilindro, nIntType vale INF_INT e dU1 e dU2
// Nel caso in cui il segmento giaccia sul cilindro, nIntType vale INF_INT e dU1 e dU2
// valgono rispettivamente 0 e dLen (lunghezza del segmento).
int IntersSegmentInfiniteCylinder( const Point3d& ptPLine, const Vector3d& vtVLine, double dLen,
const Point3d& ptPCyl, const Vector3d& vtVCyl, double dCylRad,
+58 -48
View File
@@ -19,6 +19,7 @@
#include "IntersLineBox.h"
#include "IntersLineCyl.h"
#include "IntersLineCone.h"
#include "IntersLineCaps.h"
#include "IntersLineSurfStd.h"
#include "/EgtDev/Include/EGkIntersLineTria.h"
#include "/EgtDev/Include/EGkIntersLinePlane.h"
@@ -451,7 +452,9 @@ VolZmap::AvoidSimpleBox( const Frame3d& frBox, const Vector3d& vtDiag, bool bPre
for ( int j = nStJ ; j <= nEnJ ; ++ j) {
int nPos = j * m_nNx[0] + i ;
int nSize = int( m_Values[0][nPos].size()) ;
if ( nSize == 0)
if ( nSize == 0 ||
m_Values[0][nPos][0].dMin > b3Int.GetMax().z ||
m_Values[0][nPos][nSize-1].dMax < b3Int.GetMin().z)
continue ;
for ( int k = 0 ; k < 5 ; ++ k) {
Point3d ptT = ptO + ( i + 0.5) * m_dStep * vtX + ( j + 0.5) * m_dStep * vtY ;
@@ -668,7 +671,9 @@ VolZmap::AvoidSimpleSphere( const Point3d& ptCenter, double dRad, bool bPrecise)
for ( int j = nStJ ; j <= nEnJ ; ++ j) {
int nPos = j * m_nNx[0] + i ;
int nSize = int( m_Values[0][nPos].size()) ;
if ( nSize == 0)
if ( nSize == 0 ||
m_Values[0][nPos][0].dMin > b3Int.GetMax().z ||
m_Values[0][nPos][nSize-1].dMax < b3Int.GetMin().z)
continue ;
if ( m_Values[0][nPos][nSize-1].dMax < b3Int.GetMin().z || m_Values[0][nPos][0].dMin > b3Int.GetMax().z)
continue ;
@@ -841,7 +846,9 @@ VolZmap::AvoidSimpleCylinder( const Frame3d& frCyl, double dR, double dH, bool b
for ( int j = nStJ ; j <= nEnJ ; ++ j) {
int nPos = j * m_nNx[0] + i ;
int nSize = int( m_Values[0][nPos].size()) ;
if ( nSize == 0)
if ( nSize == 0 ||
m_Values[0][nPos][0].dMin > b3Int.GetMax().z ||
m_Values[0][nPos][nSize-1].dMax < b3Int.GetMin().z)
continue ;
if ( m_Values[0][nPos][nSize-1].dMax < b3Int.GetMin().z || m_Values[0][nPos][0].dMin > b3Int.GetMax().z)
continue ;
@@ -1041,7 +1048,9 @@ VolZmap::AvoidSimpleConeFrustum( const Frame3d& frCone, double dMinRad, double d
for ( int j = nStJ ; j <= nEnJ ; ++ j) {
int nPos = j * m_nNx[0] + i ;
int nSize = int( m_Values[0][nPos].size()) ;
if ( nSize == 0)
if ( nSize == 0 ||
m_Values[0][nPos][0].dMin > b3Int.GetMax().z ||
m_Values[0][nPos][nSize-1].dMax < b3Int.GetMin().z)
continue ;
if ( m_Values[0][nPos][nSize-1].dMax < b3Int.GetMin().z || m_Values[0][nPos][0].dMin > b3Int.GetMax().z)
continue ;
@@ -1423,7 +1432,9 @@ VolZmap::AvoidSimpleRectPrismoid( const Frame3d& frPrismoid, double dLenghtBaseX
for ( int j = nStJ ; j <= nEnJ ; ++ j) {
int nPos = j * m_nNx[0] + i ;
int nSize = int( m_Values[0][nPos].size()) ;
if ( nSize == 0)
if ( nSize == 0 ||
m_Values[0][nPos][0].dMin > b3Int.GetMax().z ||
m_Values[0][nPos][nSize-1].dMax < b3Int.GetMin().z)
continue ;
double dParMin = m_Values[0][nPos][0].dMin ;
double dParMax = m_Values[0][nPos][nSize-1].dMax ;
@@ -1701,7 +1712,9 @@ VolZmap::AvoidSimpleTorus( const Frame3d& frTorus, double dMaxRad, double dMinRa
for ( int j = nStJ ; j <= nEnJ ; ++ j) {
int nPos = j * m_nNx[0] + i ;
int nSize = int( m_Values[0][nPos].size()) ;
if ( nSize == 0)
if ( nSize == 0 ||
m_Values[0][nPos][0].dMin > b3Int.GetMax().z ||
m_Values[0][nPos][nSize-1].dMax < b3Int.GetMin().z)
continue ;
double dParMin = m_Values[0][nPos][0].dMin ;
double dParMax = m_Values[0][nPos][nSize-1].dMax ;
@@ -1856,6 +1869,12 @@ VolZmap::AvoidSurfTm( const ISurfTriMesh& tmSurf, double dSafeDist, bool bPrecis
// Se verifico solo prima mappa
if ( ! bPrecise || m_nMapNum == 1) {
// Vettore direzione dei dexel nel riferimento locale Zmap
Vector3d vtK = GetToGlob( Z_AX, m_MapFrame) ;
// Riferimento intrinseco dei dexel nel riferimento locale Zmap
Point3d ptO = GetToGlob( ORIG, m_MapFrame) ;
Vector3d vtX = GetToGlob( X_AX, m_MapFrame) ;
Vector3d vtY = GetToGlob( Y_AX, m_MapFrame) ;
// Ciclo sui triangoli che cadono nel box
for ( int nT : vTriaIndex) {
Triangle3d trTria ;
@@ -1882,52 +1901,43 @@ VolZmap::AvoidSurfTm( const ISurfTriMesh& tmSurf, double dSafeDist, bool bPrecis
for ( int j = nStJ ; j <= nEnJ ; ++ j) {
int nPos = j * m_nNx[0] + i ;
int nSize = int( m_Values[0][nPos].size()) ;
if ( nSize == 0)
if ( nSize == 0 ||
m_Values[0][nPos][0].dMin > b3TriaBox.GetMax().z ||
m_Values[0][nPos][nSize-1].dMax < b3TriaBox.GetMin().z)
continue ;
for ( int k = 0 ; k < 5 ; ++ k) {
Point3d ptLineSt = ORIG + ( i + 0.5) * m_dStep * X_AX + ( j + 0.5) * m_dStep * Y_AX ;
if ( k == 0)
;
else if ( k == 1)
ptLineSt += - 0.4 * m_dStep * X_AX - 0.4 * m_dStep * Y_AX ;
else if ( k == 2)
ptLineSt += + 0.4 * m_dStep * X_AX - 0.4 * m_dStep * Y_AX ;
else if ( k == 3)
ptLineSt += + 0.4 * m_dStep * X_AX + 0.4 * m_dStep * Y_AX ;
else if ( k == 4)
ptLineSt += - 0.4 * m_dStep * X_AX + 0.4 * m_dStep * Y_AX ;
Vector3d vtLineDir = Z_AX ;
// Porto punto iniziale e vettore nel sistema locale
ptLineSt.ToGlob( m_MapFrame) ;
vtLineDir.ToGlob( m_MapFrame) ;
for ( int nIndex = 0 ; nIndex < nSize ; nIndex += 1) {
// Segmento ormai nel sistema locale
Point3d ptSegSt = ptLineSt + m_Values[0][nPos][nIndex].dMin * vtLineDir ;
double dSegLen = m_Values[0][nPos][nIndex].dMax - m_Values[0][nPos][nIndex].dMin ;
// Se la distanza di sicurezza è significativa
if ( dSafeDist > EPS_SMALL) {
// Valuto sfere nei vertici e cilindri lungo gli edge.
for ( int nV = 0 ; nV < 3 ; ++ nV) {
Point3d ptVertP = trTria.GetP( nV) ;
Vector3d vtEdgeV = trTria.GetP( ( nV + 1) % 3) - ptVertP ;
double dEdgeLen = vtEdgeV.Len() ;
vtEdgeV /= dEdgeLen ;
double dU1, dU2 ;
int nIntersType = SegmentSphere( ptSegSt, vtLineDir, dSegLen, ptVertP, dSafeDist, dU1, dU2) ;
if ( nIntersType != LinCompSphereIntersType::S_NO_INTERS)
return false ;
nIntersType = IntersSegmentCylinder( ptSegSt, vtLineDir, dSegLen, ptVertP, vtEdgeV,
dSafeDist, dEdgeLen, dU1, dU2) ;
if ( nIntersType != LinCompCCIntersType::CC_NO_INTERS)
return false ;
Point3d ptT = ptO + ( i + 0.5) * m_dStep * vtX + ( j + 0.5) * m_dStep * vtY ;
switch ( k) {
case 0 : break ;
case 1 : ptT += - 0.4 * m_dStep * vtX - 0.4 * m_dStep * vtY ; break ;
case 2 : ptT += + 0.4 * m_dStep * vtX - 0.4 * m_dStep * vtY ; break ;
case 3 : ptT += + 0.4 * m_dStep * vtX + 0.4 * m_dStep * vtY ; break ;
case 4 : ptT += - 0.4 * m_dStep * vtX + 0.4 * m_dStep * vtY ; break ;
}
// Se la distanza di sicurezza è significativa
if ( dSafeDist > EPS_SMALL) {
// Intersezione della linea con i capsule dei lati
for ( int nV = 0 ; nV < 3 ; ++ nV) {
double dZmin, dZmax ;
if ( IntersLineCaps( ptT, vtK, trTria.GetP( nV), trTria.GetP( ( nV + 1) % 3), dSafeDist, dZmin, dZmax)) {
for ( int nIndex = 0 ; nIndex < nSize ; nIndex += 1) {
if ( dZmax > m_Values[0][nPos][nIndex].dMin - EPS_SMALL &&
dZmin < m_Values[0][nPos][nIndex].dMax + EPS_SMALL)
return false ;
}
}
}
// Intersezione segmento con triangolo eventualmente offsettato
Point3d ptInt, ptInt2 ;
int nIntersType = IntersLineTria( ptSegSt, vtLineDir, dSegLen, trNewTria, ptInt, ptInt2) ;
// Collisione
if ( nIntersType != IntLineTriaType::ILTT_NO)
return false ;
}
// Intersezione della linea con triangolo eventualmente offsettato
Point3d ptInt, ptInt2 ;
if ( IntersLineTria( ptT, vtK, 1, trNewTria, ptInt, ptInt2, false) != IntLineTriaType::ILTT_NO) {
double dZmin = ( ptInt - ptT) * vtK ;
double dZmax = ( ptInt2 - ptT) * vtK ;
for ( int nIndex = 0 ; nIndex < nSize ; nIndex += 1) {
if ( dZmax > m_Values[0][nPos][nIndex].dMin - EPS_SMALL &&
dZmin < m_Values[0][nPos][nIndex].dMax + EPS_SMALL)
return false ;
}
}
}
}