EgtGeomKernel 2.5e3 :

- a BBox3d aggiunto 2° metodo Overlaps con box aventi diverso orientamento
- nelle funzioni di Collision Detection migliorato controllo non interne
- nele funzioni Avoid di Zmap si utilizza confronto box con diverso orientamento.
This commit is contained in:
DarioS
2023-05-14 11:58:48 +02:00
parent 7023d721f4
commit 2d8c815032
12 changed files with 341 additions and 231 deletions
+134 -109
View File
@@ -411,15 +411,18 @@ bool
VolZmap::AvoidSimpleBox( const Frame3d& frBox, const Vector3d& vtDiag, bool bPrecise) const
{
// BBox
BBox3d b3Box( ORIG, ORIG + vtDiag) ;
BBox3d b3BoxL( ORIG, ORIG + vtDiag) ;
// Porto il box nel riferimento intrinseco dello Zmap
b3Box.LocToLoc( frBox, m_MapFrame) ;
Frame3d frBoxInt = GetToLoc( frBox, m_MapFrame) ;
BBox3d b3Box = GetToGlob( b3BoxL, frBoxInt) ;
// BBox dello Zmap nel suo riferimento intrinseco
BBox3d b3Zmap( ORIG, Point3d( m_nNx[0] * m_dStep, m_nNy[0] * m_dStep, m_dMaxZ[0])) ;
// Se non interferiscono, posso uscire
if ( ! b3Zmap.Overlaps( b3Box) || ! b3Zmap.Overlaps( frBoxInt, b3BoxL))
return true ;
BBox3d b3Int ;
if ( ! b3Zmap.FindIntersection( b3Box, b3Int))
return true ;
@@ -434,12 +437,12 @@ VolZmap::AvoidSimpleBox( const Frame3d& frBox, const Vector3d& vtDiag, bool bPre
int nEnJ = Clamp( int( b3Int.GetMax().y / m_dStep), 0, m_nNy[0] - 1) ;
// Vettore direzione dei dexel nel riferimento del Box
Vector3d vtK = Z_AX ; vtK.LocToLoc( m_MapFrame, frBox) ;
Vector3d vtK = Z_AX ; vtK.ToLoc( frBoxInt) ;
// Riferimento intrinseco dei dexel nel riferimento del box
Point3d ptO = ORIG ; ptO.LocToLoc( m_MapFrame, frBox) ;
Vector3d vtX = X_AX ; vtX.LocToLoc( m_MapFrame, frBox) ;
Vector3d vtY = Y_AX ; vtY.LocToLoc( m_MapFrame, frBox) ;
Point3d ptO = ORIG ; ptO.ToLoc( frBoxInt) ;
Vector3d vtX = X_AX ; vtX.ToLoc( frBoxInt) ;
Vector3d vtY = Y_AX ; vtY.ToLoc( frBoxInt) ;
// Ciclo di intersezione dei dexel con il BBox
for ( int i = nStI ; i <= nEnI ; ++ i) {
@@ -503,10 +506,10 @@ VolZmap::AvoidSimpleBox( const Frame3d& frBox, const Vector3d& vtDiag, bool bPre
vtK = Y_AX ;
}
// Passo da sistema griglia a sistema BBox
ptO.ToLoc( frBox) ;
vtX.ToLoc( frBox) ;
vtY.ToLoc( frBox) ;
vtK.ToLoc( frBox) ;
ptO.ToLoc( frBoxInt) ;
vtX.ToLoc( frBoxInt) ;
vtY.ToLoc( frBoxInt) ;
vtK.ToLoc( frBoxInt) ;
// Limiti su indici
int nStI = Clamp( int( ptBoxInf.x / m_dStep), 0, m_nNx[nMap] - 1) ;
int nEnI = Clamp( int( ptBoxSup.x / m_dStep), 0, m_nNx[nMap] - 1) ;
@@ -780,33 +783,41 @@ VolZmap::AvoidSphere( const Point3d& ptCenter, double dRad, double dSafeDist, bo
bool
VolZmap::AvoidSimpleCylinder( const Frame3d& frCyl, double dR, double dH, bool bPrecise) const
{
// Porto il cilindro nel riferimento intrinseco dello Zmap
Frame3d frC = frCyl ;
frC.ToLoc( m_MapFrame) ;
// BBox del cilindro in locale
BBox3d b3CylL( Point3d( -dR, -dR, 0), Point3d( dR, dR, dH)) ;
// BBox del cilindro
Vector3d vtDirL = frC.VersZ() ;
BBox3d b3Box( frC.Orig()) ;
b3Box.Add( frC.Orig() + frC.VersZ() * dH) ;
if ( vtDirL.IsXplus() || vtDirL.IsXminus())
b3Box.Expand( 0, dR, dR) ;
else if ( vtDirL.IsYplus() || vtDirL.IsYminus())
b3Box.Expand( dR, 0, dR) ;
else if ( vtDirL.IsZplus() || vtDirL.IsZminus())
b3Box.Expand( dR, dR, 0) ;
else {
double dExpandX = dR * sqrt( 1 - vtDirL.x * vtDirL.x) ;
double dExpandY = dR * sqrt( 1 - vtDirL.y * vtDirL.y) ;
double dExpandZ = dR * sqrt( 1 - vtDirL.z * vtDirL.z) ;
b3Box.Expand( dExpandX, dExpandY, dExpandZ) ;
}
// BBox del cilindro nel riferimento intrinseco dello Zmap
Frame3d frCylInt = GetToLoc( frCyl, m_MapFrame) ;
BBox3d b3CylI = GetToGlob( b3CylL, frCylInt) ;
// BBox dello Zmap nel suo riferimento intrinseco
BBox3d b3Zmap( ORIG, Point3d( m_nNx[0] * m_dStep, m_nNy[0] * m_dStep, m_dMaxZ[0])) ;
// Se non interferiscono, posso uscire
if ( ! b3Zmap.Overlaps( b3CylI) || ! b3Zmap.Overlaps( frCylInt, b3CylL))
return true ;
// BBox del cilindro ottimizzato nel riferimento intrinseco dello Zmap
Point3d ptMyCen = frCylInt.Orig() ;
Vector3d vtMyAx = frCylInt.VersZ() ;
BBox3d b3Cyl( ptMyCen) ;
b3Cyl.Add( ptMyCen + vtMyAx * dH) ;
if ( vtMyAx.IsX())
b3Cyl.Expand( 0, dR, dR) ;
else if ( vtMyAx.IsY())
b3Cyl.Expand( dR, 0, dR) ;
else if ( vtMyAx.IsZ())
b3Cyl.Expand( dR, dR, 0) ;
else {
double dExpandX = dR * sqrt( 1 - vtMyAx.x * vtMyAx.x) ;
double dExpandY = dR * sqrt( 1 - vtMyAx.y * vtMyAx.y) ;
double dExpandZ = dR * sqrt( 1 - vtMyAx.z * vtMyAx.z) ;
b3Cyl.Expand( dExpandX, dExpandY, dExpandZ) ;
}
// Se non interferiscono, posso uscire
BBox3d b3Int ;
if ( ! b3Zmap.FindIntersection( b3Box, b3Int))
if ( ! b3Zmap.FindIntersection( b3Cyl, b3Int))
return true ;
// Se verifico solo prima mappa
@@ -838,7 +849,7 @@ VolZmap::AvoidSimpleCylinder( const Frame3d& frCyl, double dR, double dH, bool b
}
Point3d ptI1, ptI2 ;
Vector3d vtN1, vtN2 ;
if ( IntersLineCylinder( ptT, Z_AX, frC, dH, dR, true, true, ptI1, vtN1, ptI2, vtN2)) {
if ( IntersLineCylinder( ptT, Z_AX, frCylInt, dH, dR, true, true, ptI1, vtN1, ptI2, vtN2)) {
double dZmin = min( ptI1.z, ptI2.z) ;
double dZmax = max( ptI1.z, ptI2.z) ;
for ( int nIndex = 0 ; nIndex < nSize ; nIndex += 1) {
@@ -898,7 +909,7 @@ VolZmap::AvoidSimpleCylinder( const Frame3d& frCyl, double dR, double dH, bool b
Point3d ptI1, ptI2 ;
Vector3d vtN1, vtN2 ;
// La linea del dexel interseca il cilindro.
if ( IntersLineCylinder( ptT, vtK, frC, dH, dR, true, true, ptI1, vtN1, ptI2, vtN2)) {
if ( IntersLineCylinder( ptT, vtK, frCylInt, dH, dR, true, true, ptI1, vtN1, ptI2, vtN2)) {
double dMinU, dMaxU ;
if ( nMap == 0) {
dMinU = min( ptI1.z, ptI2.z) ;
@@ -933,33 +944,33 @@ bool
VolZmap::AvoidCylinder( const Frame3d& frCyl, double dR, double dH, double dSafeDist, bool bPrecise) const
{
// Se altezza negativa, sposto riferimento da faccia sopra a quella sotto
Frame3d frC = frCyl ;
Frame3d frMyCyl = frCyl ;
if ( dH < 0) {
frC.Translate( dH * frC.VersZ()) ;
frMyCyl.Translate( dH * frMyCyl.VersZ()) ;
dH = - dH ;
}
// Se distanza di sicurezza nulla
if ( dSafeDist < EPS_SMALL)
return AvoidSimpleCylinder( frC, dR, dH, bPrecise) ;
return AvoidSimpleCylinder( frMyCyl, dR, dH, bPrecise) ;
// Verifica preliminare con cilindro esteso
Frame3d frEst = frC ; frEst.Translate( -dSafeDist * frC.VersZ()) ;
Frame3d frEst = frMyCyl ; frEst.Translate( -dSafeDist * frMyCyl.VersZ()) ;
if ( AvoidSimpleCylinder( frEst, dR + dSafeDist, dH + 2 * dSafeDist, bPrecise))
return true ;
// Cilindro allargato
if ( ! AvoidSimpleCylinder( frC, dR + dSafeDist, dH, bPrecise))
if ( ! AvoidSimpleCylinder( frMyCyl, dR + dSafeDist, dH, bPrecise))
return false ;
// Cilindro allungato
Frame3d frTmp = frC ; frTmp.Translate( - dSafeDist * frC.VersZ()) ;
Frame3d frTmp = frMyCyl ; frTmp.Translate( - dSafeDist * frMyCyl.VersZ()) ;
if ( ! AvoidSimpleCylinder( frTmp, dR, dH + 2 * dSafeDist, bPrecise))
return false ;
// Toro inferiore
if ( ! AvoidSimpleTorus( frC, dR, dSafeDist, bPrecise))
if ( ! AvoidSimpleTorus( frMyCyl, dR, dSafeDist, bPrecise))
return false ;
// Toro superiore
frTmp = frC ; frTmp.Translate( dH * frC.VersZ()) ;
frTmp = frMyCyl ; frTmp.Translate( dH * frMyCyl.VersZ()) ;
if ( ! AvoidSimpleTorus( frTmp, dR, dSafeDist, bPrecise))
return false ;
@@ -1065,34 +1076,41 @@ VolZmap::SingleMapDexelConeCollision( int nStI, int nEnI, int nStJ, int nEnJ, co
bool
VolZmap::AvoidSimpleConeFrustum( const Frame3d& frCone, double dMinRad, double dMaxRad, double dHeight, bool bPrecise) const
{
// Porto il tronco di cono nel sistema intrinseco e normalizzo il vettore.
Point3d ptRefPoint = frCone.Orig() ;
Vector3d vtRefAx = frCone.VersZ() ;
ptRefPoint.ToLoc( m_MapFrame) ;
vtRefAx.ToLoc( m_MapFrame) ;
// BBox del tronco di cono in locale
BBox3d b3ConeL( Point3d( -dMaxRad, -dMaxRad, 0), Point3d( dMaxRad, dMaxRad, dHeight)) ;
// BBox del tronco di cono
BBox3d b3Box( ptRefPoint) ;
b3Box.Add( ptRefPoint + vtRefAx * dHeight) ;
if ( vtRefAx.IsXplus() || vtRefAx.IsXminus())
b3Box.Expand( 0, dMaxRad, dMaxRad) ;
else if ( vtRefAx.IsYplus() || vtRefAx.IsYminus())
b3Box.Expand( dMaxRad, 0, dMaxRad) ;
else if ( vtRefAx.IsZplus() || vtRefAx.IsZminus())
b3Box.Expand( dMaxRad, dMaxRad, 0) ;
else {
double dExpandX = dMaxRad * sqrt( 1 - vtRefAx.x * vtRefAx.x) ;
double dExpandY = dMaxRad * sqrt( 1 - vtRefAx.y * vtRefAx.y) ;
double dExpandZ = dMaxRad * sqrt( 1 - vtRefAx.z * vtRefAx.z) ;
b3Box.Expand( dExpandX, dExpandY, dExpandZ) ;
}
// BBox del tronco di cono nel riferimento intrinseco dello Zmap
Frame3d frConeInt = GetToLoc( frCone, m_MapFrame) ;
BBox3d b3ConeI = GetToGlob( b3ConeL, frConeInt) ;
// BBox dello Zmap nel suo riferimento intrinseco
BBox3d b3Zmap( ORIG, Point3d( m_nNx[0] * m_dStep, m_nNy[0] * m_dStep, m_dMaxZ[0])) ;
// Se non interferiscono, posso uscire
if ( ! b3Zmap.Overlaps( b3ConeI) || ! b3Zmap.Overlaps( frConeInt, b3ConeL))
return true ;
// BBox del tronco di cono ottimizzato nel riferimento intrinseco dello Zmap
Point3d ptRefPoint = frConeInt.Orig() ;
Vector3d vtRefAx = frConeInt.VersZ() ;
BBox3d b3Cone( ptRefPoint) ;
b3Cone.Add( ptRefPoint + vtRefAx * dHeight) ;
if ( vtRefAx.IsX())
b3Cone.Expand( 0, dMaxRad, dMaxRad) ;
else if ( vtRefAx.IsY())
b3Cone.Expand( dMaxRad, 0, dMaxRad) ;
else if ( vtRefAx.IsZ())
b3Cone.Expand( dMaxRad, dMaxRad, 0) ;
else {
double dExpandX = dMaxRad * sqrt( 1 - vtRefAx.x * vtRefAx.x) ;
double dExpandY = dMaxRad * sqrt( 1 - vtRefAx.y * vtRefAx.y) ;
double dExpandZ = dMaxRad * sqrt( 1 - vtRefAx.z * vtRefAx.z) ;
b3Cone.Expand( dExpandX, dExpandY, dExpandZ) ;
}
// Se non interferiscono, posso uscire
BBox3d b3Int ;
if ( ! b3Zmap.FindIntersection( b3Box, b3Int))
if ( ! b3Zmap.FindIntersection( b3Cone, b3Int))
return true ;
// Uso solo la prima mappa
@@ -1638,34 +1656,33 @@ bool
VolZmap::AvoidSimpleRectPrismoid( const Frame3d& frPrismoid, double dLenghtBaseX, double dLenghtBaseY,
double dLenghtTopX, double dLenghtTopY, double dHeight, bool bPrecise) const
{
// IL sistema del tronco di piramide generalizzato è definito nel sistema locale.
// Lo porto nel sistema intrinseco.
Frame3d frMyFrame = frPrismoid ;
frMyFrame.ToLoc( m_MapFrame) ;
// Box del tronco nel suo sistema
// Box del tronco di prismoide nel suo sistema locale
double dMaxLenX = max( dLenghtBaseX, dLenghtTopX) ;
double dMaxLenY = max( dLenghtBaseY, dLenghtTopY) ;
BBox3d b3GenPyrBox( Point3d( -dMaxLenX / 2, -dMaxLenY / 2, 0.),
Point3d( dMaxLenX / 2, dMaxLenY / 2, dHeight)) ;
// Porto il box nel sistema intrinseco dello Zmap
b3GenPyrBox.ToGlob( frMyFrame) ;
BBox3d b3PrismL( Point3d( -dMaxLenX / 2, -dMaxLenY / 2, 0.),
Point3d( dMaxLenX / 2, dMaxLenY / 2, dHeight)) ;
// Box del solido
// BBox del tronco di prismoide nel riferimento intrinseco dello Zmap
Frame3d frPrismInt = GetToLoc( frPrismoid, m_MapFrame) ;
BBox3d b3PrismI = GetToGlob( b3PrismL, frPrismInt) ;
// BBox dello Zmap nel suo riferimento intrinseco
BBox3d b3Zmap( ORIG, Point3d( m_nNx[0] * m_dStep, m_nNy[0] * m_dStep, m_dMaxZ[0])) ;
BBox3d b3Int ;
// Se i box non si si sovrappongono, ho finito.
if ( ! b3Zmap.FindIntersection( b3GenPyrBox, b3Int))
// Se i box non interferiscono, posso uscire
if ( ! b3Zmap.Overlaps( b3PrismI) || ! b3Zmap.Overlaps( frPrismInt, b3PrismL))
return true ;
BBox3d b3Int ;
if ( ! b3Zmap.FindIntersection( b3PrismI, b3Int))
return true ;
if ( ! bPrecise) {
// Limiti su indici
// Limiti su indici
int nStI = Clamp( int( b3Int.GetMin().x / m_dStep), 0, m_nNx[0] - 1) ;
int nEnI = Clamp( int( b3Int.GetMax().x / m_dStep), 0, m_nNx[0] - 1) ;
int nStJ = Clamp( int( b3Int.GetMin().y / m_dStep), 0, m_nNy[0] - 1) ;
int nEnJ = Clamp( int( b3Int.GetMax().y / m_dStep), 0, m_nNy[0] - 1) ;
// Ciclo di intersezione dei dexel con il cilindro (nel riferimento intrinseco)
// Ciclo di intersezione dei dexel con il cilindro (nel riferimento intrinseco)
for ( int i = nStI ; i <= nEnI ; ++ i) {
for ( int j = nStJ ; j <= nEnJ ; ++ j) {
int nPos = j * m_nNx[0] + i ;
@@ -1688,7 +1705,7 @@ VolZmap::AvoidSimpleRectPrismoid( const Frame3d& frPrismoid, double dLenghtBaseX
double dStU, dEnU ;
Point3d ptSegSt = ptLineSt + m_Values[0][nPos][0].dMin * Z_AX ;
Point3d ptSegEn = ptLineSt + m_Values[0][nPos][nSize-1].dMax * Z_AX ;
if ( RectPrismoidSegmentCollisionPlus( frMyFrame, dLenghtBaseX, dLenghtBaseY, dLenghtTopX, dLenghtTopY,
if ( RectPrismoidSegmentCollisionPlus( frPrismInt, dLenghtBaseX, dLenghtBaseY, dLenghtTopX, dLenghtTopY,
dHeight, ptSegSt, ptSegEn, dStU, dEnU)) {
for ( int nIndex = 0 ; nIndex < nSize ; nIndex += 1) {
if ( m_Values[0][nPos][nIndex].dMax >= dStU && m_Values[0][nPos][nIndex].dMin <= dEnU)
@@ -1700,11 +1717,11 @@ VolZmap::AvoidSimpleRectPrismoid( const Frame3d& frPrismoid, double dLenghtBaseX
}
}
else {
// Ciclo sulle mappe
// Ciclo sulle mappe
for ( int nMap = 0 ; nMap < m_nMapNum ; ++ nMap) {
Point3d ptInfIntBox = b3Int.GetMin();
Point3d ptSupIntBox = b3Int.GetMax();
// Dal sistema intrinseco al sistema griglia (per la prima griglia coincidono).
// Dal sistema intrinseco al sistema griglia (per la prima griglia coincidono).
if ( nMap == 1) {
swap( ptInfIntBox.x, ptInfIntBox.z) ;
swap( ptInfIntBox.x, ptInfIntBox.y) ;
@@ -1717,7 +1734,7 @@ VolZmap::AvoidSimpleRectPrismoid( const Frame3d& frPrismoid, double dLenghtBaseX
swap( ptSupIntBox.y, ptSupIntBox.z) ;
swap( ptSupIntBox.x, ptSupIntBox.y) ;
}
// Limiti su indici
// Limiti su indici
int nStI = Clamp( int( ptInfIntBox.x / m_dStep), 0, m_nNx[nMap] - 1) ;
int nEnI = Clamp( int( ptSupIntBox.x / m_dStep), 0, m_nNx[nMap] - 1) ;
int nStJ = Clamp( int( ptInfIntBox.y / m_dStep), 0, m_nNy[nMap] - 1) ;
@@ -1726,18 +1743,18 @@ VolZmap::AvoidSimpleRectPrismoid( const Frame3d& frPrismoid, double dLenghtBaseX
int nSize = int( m_Values[nMap][nDex].size()) ;
if ( nSize == 0)
continue ;
// Indici del dexel
// Indici del dexel
int nI = nDex % m_nNx[nMap] ;
int nJ = nDex / m_nNx[nMap] ;
// Se fuori dalla regione ammissibile salto l'iterazione
// Se fuori dalla regione ammissibile salto l'iterazione
if ( nI < nStI || nI > nEnI || nJ < nStJ || nJ > nEnJ)
continue ;
// Posizione del dexel
// Posizione del dexel
double dX = ( nI + 0.5) * m_dStep ;
double dY = ( nJ + 0.5) * m_dStep ;
Point3d ptLineSt( dX, dY, 0.) ;
Vector3d vtLineDir( 0., 0., 1.) ;
// Dal sistema griglia al sistema intrinseco (per la prima griglia coincidono).
// Dal sistema griglia al sistema intrinseco (per la prima griglia coincidono).
if ( nMap == 1) {
swap( ptLineSt.x, ptLineSt.y) ;
swap( ptLineSt.x, ptLineSt.z) ;
@@ -1753,7 +1770,7 @@ VolZmap::AvoidSimpleRectPrismoid( const Frame3d& frPrismoid, double dLenghtBaseX
double dStU, dEnU ;
Point3d ptSegSt = ptLineSt + m_Values[nMap][nDex][0].dMin * vtLineDir ;
Point3d ptSegEn = ptLineSt + m_Values[nMap][nDex][nSize-1].dMax * vtLineDir ;
if ( RectPrismoidSegmentCollisionPlus( frMyFrame, dLenghtBaseX, dLenghtBaseY, dLenghtTopX, dLenghtTopY,
if ( RectPrismoidSegmentCollisionPlus( frPrismInt, dLenghtBaseX, dLenghtBaseY, dLenghtTopX, dLenghtTopY,
dHeight, ptSegSt, ptSegEn, dStU, dEnU)) {
for ( int nIndex = 0 ; nIndex < nSize ; nIndex += 1) {
if ( m_Values[nMap][nDex][nIndex].dMax >= dStU && m_Values[nMap][nDex][nIndex].dMin <= dEnU)
@@ -1893,36 +1910,44 @@ VolZmap::AvoidRectPrismoid( const Frame3d& frPrismoid, double dLenghtBaseX, doub
bool
VolZmap::AvoidSimpleTorus( const Frame3d& frTorus, double dMaxRad, double dMinRad, bool bPrecise) const
{
// Porto il toro nel sistema intrinseco dello Zmap.
Point3d ptMyCen = frTorus.Orig() ;
Vector3d vtMyAx = frTorus.VersZ() ;
ptMyCen.ToLoc( m_MapFrame) ;
vtMyAx.ToLoc( m_MapFrame) ;
// BBox del toro in locale
BBox3d b3TorusL( Point3d( -dMaxRad - dMinRad, -dMaxRad - dMinRad, -dMinRad),
Point3d( dMaxRad + dMinRad, dMaxRad + dMinRad, dMinRad)) ;
// BBox del toro
BBox3d b3Box( ptMyCen) ;
b3Box.Add( ptMyCen + vtMyAx * dMinRad) ;
b3Box.Add( ptMyCen - vtMyAx * dMinRad) ;
double dTotRad = dMaxRad + dMinRad ;
if ( vtMyAx.IsXplus() || vtMyAx.IsXminus())
b3Box.Expand( 0, dTotRad, dTotRad) ;
else if ( vtMyAx.IsYplus() || vtMyAx.IsYminus())
b3Box.Expand( dTotRad, 0, dTotRad) ;
else if ( vtMyAx.IsZplus() || vtMyAx.IsZminus())
b3Box.Expand( dTotRad, dTotRad, 0) ;
else {
double dExpandX = dTotRad * sqrt( 1 - vtMyAx.x * vtMyAx.x) ;
double dExpandY = dTotRad * sqrt( 1 - vtMyAx.y * vtMyAx.y) ;
double dExpandZ = dTotRad * sqrt( 1 - vtMyAx.z * vtMyAx.z) ;
b3Box.Expand( dExpandX, dExpandY, dExpandZ) ;
}
// BBox del toro nel riferimento intrinseco dello Zmap
Frame3d frTorusInt = GetToLoc( frTorus, m_MapFrame) ;
BBox3d b3TorusI = GetToGlob( b3TorusL, frTorusInt) ;
// BBox dello Zmap nel suo riferimento intrinseco
BBox3d b3Zmap( ORIG, Point3d( m_nNx[0] * m_dStep, m_nNy[0] * m_dStep, m_dMaxZ[0])) ;
// Se non interferiscono, posso uscire
if ( ! b3Zmap.Overlaps( b3TorusI) || ! b3Zmap.Overlaps( frTorusInt, b3TorusL))
return true ;
// BBox del toro ottimizzato nel riferimento intrinseco dello Zmap
Point3d ptMyCen = frTorusInt.Orig() ;
Vector3d vtMyAx = frTorusInt.VersZ() ;
BBox3d b3Torus( ptMyCen) ;
b3Torus.Add( ptMyCen + vtMyAx * dMinRad) ;
b3Torus.Add( ptMyCen - vtMyAx * dMinRad) ;
double dTotRad = dMaxRad + dMinRad ;
if ( vtMyAx.IsX())
b3Torus.Expand( 0, dTotRad, dTotRad) ;
else if ( vtMyAx.IsY())
b3Torus.Expand( dTotRad, 0, dTotRad) ;
else if ( vtMyAx.IsZ())
b3Torus.Expand( dTotRad, dTotRad, 0) ;
else {
double dExpandX = dTotRad * sqrt( 1 - vtMyAx.x * vtMyAx.x) ;
double dExpandY = dTotRad * sqrt( 1 - vtMyAx.y * vtMyAx.y) ;
double dExpandZ = dTotRad * sqrt( 1 - vtMyAx.z * vtMyAx.z) ;
b3Torus.Expand( dExpandX, dExpandY, dExpandZ) ;
}
// Se non interferiscono, posso uscire
BBox3d b3Int ;
if ( ! b3Zmap.FindIntersection( b3Box, b3Int))
if ( ! b3Zmap.FindIntersection( b3Torus, b3Int))
return true ;
// Se verifico solo prima mappa