From 8a3d46416d4987c475d90d2ed53d97e56f0ac14f Mon Sep 17 00:00:00 2001 From: DarioS Date: Wed, 21 Jun 2023 08:26:21 +0200 Subject: [PATCH] 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. --- EgtGeomKernel.rc | Bin 11710 -> 11710 bytes IntersLineSurfStd.cpp | 18 +++---- IntersLineSurfStd.h | 9 ++-- VolZmapCalculus.cpp | 106 +++++++++++++++++++++++------------------- 4 files changed, 72 insertions(+), 61 deletions(-) diff --git a/EgtGeomKernel.rc b/EgtGeomKernel.rc index a4940f0294c04e58e67ea0338a74f889aa0d92b6..7ebcefaba13f50b36a66683d270b5c87ec1fec31 100644 GIT binary patch delta 94 zcmdlNy)SyhFE&P#&A-_cnHfzcD{|{@_Trkr0u;H;XNwSVW8B;$>;>dw2zN+>g;Df- LFmBFL4&ed-WjGrO delta 94 zcmdlNy)SyhFE&Qw&A-_cnHh~ID{|{@_Trkr0u;H;XNwSVW8B;$>;>dw2zN+>g;Df- LFmBFL4&ed-W11TR diff --git a/IntersLineSurfStd.cpp b/IntersLineSurfStd.cpp index 7657f19..41a2ae8 100644 --- a/IntersLineSurfStd.cpp +++ b/IntersLineSurfStd.cpp @@ -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 ; } diff --git a/IntersLineSurfStd.h b/IntersLineSurfStd.h index 4a0dee0..2a76d2d 100644 --- a/IntersLineSurfStd.h +++ b/IntersLineSurfStd.h @@ -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, diff --git a/VolZmapCalculus.cpp b/VolZmapCalculus.cpp index 86215da..a4db450 100644 --- a/VolZmapCalculus.cpp +++ b/VolZmapCalculus.cpp @@ -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 ; + } } } }