7c6ddf2a6f
- aggiunto controllo validità coordinate di punti e vettori (isfinite).
651 lines
22 KiB
C++
651 lines
22 KiB
C++
//----------------------------------------------------------------------------
|
|
// EgalTech 2014-2022
|
|
//----------------------------------------------------------------------------
|
|
// File : BBox3d.cpp Data : 17.08.22 Versione : 2.4h1
|
|
// Contenuto : Implementazione della classe axis aligned bounding box BBox3d.
|
|
//
|
|
//
|
|
//
|
|
// Modifiche : 14.01.14 DS Creazione modulo.
|
|
//
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
//--------------------------- Include ----------------------------------------
|
|
#include "stdafx.h"
|
|
#include "/EgtDev/Include/EGkBBox3d.h"
|
|
#include "/EgtDev/Include/EGkFrame3d.h"
|
|
#include <algorithm>
|
|
|
|
using namespace std ;
|
|
|
|
//----------------------------------------------------------------------------
|
|
BBox3d::BBox3d( const Point3d& ptP1, const Point3d& ptP2)
|
|
{
|
|
m_ptMin.Set( min( ptP1.x, ptP2.x), min( ptP1.y, ptP2.y), min( ptP1.z, ptP2.z)) ;
|
|
m_ptMax.Set( max( ptP1.x, ptP2.x), max( ptP1.y, ptP2.y), max( ptP1.z, ptP2.z)) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
BBox3d::BBox3d( double dX1, double dY1, double dZ1, double dX2, double dY2, double dZ2)
|
|
{
|
|
m_ptMin.Set( min( dX1, dX2), min( dY1, dY2), min( dZ1, dZ2)) ;
|
|
m_ptMax.Set( max( dX1, dX2), max( dY1, dY2), max( dZ1, dZ2)) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void
|
|
BBox3d::Set( const Point3d& ptP1, const Point3d& ptP2)
|
|
{
|
|
m_ptMin.Set( min( ptP1.x, ptP2.x), min( ptP1.y, ptP2.y), min( ptP1.z, ptP2.z)) ;
|
|
m_ptMax.Set( max( ptP1.x, ptP2.x), max( ptP1.y, ptP2.y), max( ptP1.z, ptP2.z)) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void
|
|
BBox3d::Set( double dX1, double dY1, double dZ1, double dX2, double dY2, double dZ2)
|
|
{
|
|
m_ptMin.Set( min( dX1, dX2), min( dY1, dY2), min( dZ1, dZ2)) ;
|
|
m_ptMax.Set( max( dX1, dX2), max( dY1, dY2), max( dZ1, dZ2)) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
BBox3d::IsValid( void) const
|
|
{
|
|
return ( m_ptMin.IsValid() && m_ptMax.IsValid() &&
|
|
m_ptMin.x < ( m_ptMax.x + EPS_SMALL) &&
|
|
m_ptMin.y < ( m_ptMax.y + EPS_SMALL) &&
|
|
m_ptMin.z < ( m_ptMax.z + EPS_SMALL)) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
BBox3d::IsSmall( void) const
|
|
{
|
|
return ( ! IsValid() ||
|
|
m_ptMax.x - m_ptMin.x < EPS_SMALL ||
|
|
m_ptMax.y - m_ptMin.y < EPS_SMALL ||
|
|
m_ptMax.z - m_ptMin.z < EPS_SMALL) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
BBox3d::IsSmallXY( void) const
|
|
{
|
|
return ( ! IsValid() ||
|
|
m_ptMax.x - m_ptMin.x < EPS_SMALL ||
|
|
m_ptMax.y - m_ptMin.y < EPS_SMALL) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
BBox3d::IsSmallZ( void) const
|
|
{
|
|
return ( ! IsValid() ||
|
|
m_ptMax.z - m_ptMin.z < EPS_SMALL) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
BBox3d::IsEpsilon( double dToler) const
|
|
{
|
|
return ( ! IsValid() ||
|
|
m_ptMax.x - m_ptMin.x < dToler ||
|
|
m_ptMax.y - m_ptMin.y < dToler ||
|
|
m_ptMax.z - m_ptMin.z < dToler) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
BBox3d::IsEpsilonXY( double dToler) const
|
|
{
|
|
return ( ! IsValid() ||
|
|
m_ptMax.x - m_ptMin.x < dToler ||
|
|
m_ptMax.y - m_ptMin.y < dToler) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
BBox3d::IsEpsilonZ( double dToler) const
|
|
{
|
|
return ( ! IsValid() ||
|
|
m_ptMax.z - m_ptMin.z < dToler) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void
|
|
BBox3d::Add( const Point3d& ptP)
|
|
{
|
|
if ( ptP.x < m_ptMin.x)
|
|
m_ptMin.x = ptP.x ;
|
|
if ( ptP.y < m_ptMin.y)
|
|
m_ptMin.y = ptP.y ;
|
|
if ( ptP.z < m_ptMin.z)
|
|
m_ptMin.z = ptP.z ;
|
|
if ( ptP.x > m_ptMax.x)
|
|
m_ptMax.x = ptP.x ;
|
|
if ( ptP.y > m_ptMax.y)
|
|
m_ptMax.y = ptP.y ;
|
|
if ( ptP.z > m_ptMax.z)
|
|
m_ptMax.z = ptP.z ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void
|
|
BBox3d::Add( double dX, double dY, double dZ)
|
|
{
|
|
if ( dX < m_ptMin.x)
|
|
m_ptMin.x = dX ;
|
|
if ( dY < m_ptMin.y)
|
|
m_ptMin.y = dY ;
|
|
if ( dZ < m_ptMin.z)
|
|
m_ptMin.z = dZ ;
|
|
if ( dX > m_ptMax.x)
|
|
m_ptMax.x = dX ;
|
|
if ( dY > m_ptMax.y)
|
|
m_ptMax.y = dY ;
|
|
if ( dZ > m_ptMax.z)
|
|
m_ptMax.z = dZ ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void
|
|
BBox3d::Add( const BBox3d& b3B)
|
|
{
|
|
if ( b3B.m_ptMin.x < m_ptMin.x)
|
|
m_ptMin.x = b3B.m_ptMin.x ;
|
|
if ( b3B.m_ptMin.y < m_ptMin.y)
|
|
m_ptMin.y = b3B.m_ptMin.y ;
|
|
if ( b3B.m_ptMin.z < m_ptMin.z)
|
|
m_ptMin.z = b3B.m_ptMin.z ;
|
|
if ( b3B.m_ptMax.x > m_ptMax.x)
|
|
m_ptMax.x = b3B.m_ptMax.x ;
|
|
if ( b3B.m_ptMax.y > m_ptMax.y)
|
|
m_ptMax.y = b3B.m_ptMax.y ;
|
|
if ( b3B.m_ptMax.z > m_ptMax.z)
|
|
m_ptMax.z = b3B.m_ptMax.z ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void
|
|
BBox3d::Expand( double dDelta)
|
|
{
|
|
if ( IsValid()) {
|
|
m_ptMin -= Vector3d( dDelta, dDelta, dDelta) ;
|
|
m_ptMax += Vector3d( dDelta, dDelta, dDelta) ;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void
|
|
BBox3d::Expand( double dDeltaX, double dDeltaY, double dDeltaZ)
|
|
{
|
|
if ( IsValid()) {
|
|
m_ptMin -= Vector3d( dDeltaX, dDeltaY, dDeltaZ) ;
|
|
m_ptMax += Vector3d( dDeltaX, dDeltaY, dDeltaZ) ;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
BBox3d::GetMinMax( Point3d& ptMin, Point3d& ptMax) const
|
|
{
|
|
if ( ! IsValid())
|
|
return false ;
|
|
ptMin = m_ptMin ;
|
|
ptMax = m_ptMax ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
BBox3d::GetMinDim( Point3d& ptMin, double& dDimX, double& dDimY, double& dDimZ) const
|
|
{
|
|
if ( ! IsValid())
|
|
return false ;
|
|
ptMin = m_ptMin ;
|
|
dDimX = m_ptMax.x - m_ptMin.x ;
|
|
dDimY = m_ptMax.y - m_ptMin.y ;
|
|
dDimZ = m_ptMax.z - m_ptMin.z ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
double
|
|
BBox3d::GetDimX( void) const
|
|
{
|
|
if ( ! IsValid())
|
|
return 0 ;
|
|
return ( m_ptMax.x - m_ptMin.x) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
double
|
|
BBox3d::GetDimY( void) const
|
|
{
|
|
if ( ! IsValid())
|
|
return 0 ;
|
|
return ( m_ptMax.y - m_ptMin.y) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
double
|
|
BBox3d::GetDimZ( void) const
|
|
{
|
|
if ( ! IsValid())
|
|
return 0 ;
|
|
return ( m_ptMax.z - m_ptMin.z) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
BBox3d::GetCenterExtent( Point3d& ptCenter, Vector3d& vtExtent) const
|
|
{
|
|
if ( ! IsValid())
|
|
return false ;
|
|
ptCenter = 0.5 * ( m_ptMin + m_ptMax) ;
|
|
vtExtent = 0.5 * ( m_ptMax - m_ptMin) ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
BBox3d::GetCenter( Point3d& ptCenter) const
|
|
{
|
|
if ( ! IsValid())
|
|
return false ;
|
|
ptCenter = 0.5 * ( m_ptMin + m_ptMax) ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
BBox3d::GetRadius( double& dRad) const
|
|
{
|
|
if ( ! IsValid())
|
|
return false ;
|
|
dRad = ( m_ptMax - m_ptMin).Len() * 0.5 ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
BBox3d::GetDiameter( double& dDiam) const
|
|
{
|
|
if ( ! IsValid())
|
|
return false ;
|
|
dDiam = ( m_ptMax - m_ptMin).Len() ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
BBox3d::Translate( const Vector3d& vtMove)
|
|
{
|
|
if ( ! IsValid())
|
|
return false ;
|
|
// non essendoci cambio di orientamento, traslo semplicemente i punti
|
|
m_ptMin = m_ptMin + vtMove ;
|
|
m_ptMax = m_ptMax + vtMove ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
BBox3d::Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dAngDeg)
|
|
{
|
|
double dAngRad = dAngDeg * DEGTORAD ;
|
|
return Rotate( ptAx, vtAx, cos( dAngRad), sin( dAngRad)) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
BBox3d::Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAng, double dSinAng)
|
|
{
|
|
if ( ! IsValid())
|
|
return false ;
|
|
// ruoto il minimo
|
|
Point3d ptMinRot = m_ptMin ;
|
|
if ( ! ptMinRot.Rotate( ptAx, vtAx, dCosAng, dSinAng))
|
|
return false ;
|
|
// ruoto i vettori dal Min al Max diretti come gli assi locali
|
|
Vector3d vtXRot( m_ptMax.x - m_ptMin.x, 0, 0) ;
|
|
vtXRot.Rotate( vtAx, dCosAng, dSinAng) ;
|
|
Vector3d vtYRot( 0, m_ptMax.y - m_ptMin.y, 0) ;
|
|
vtYRot.Rotate( vtAx, dCosAng, dSinAng) ;
|
|
Vector3d vtZRot( 0, 0, m_ptMax.z - m_ptMin.z) ;
|
|
vtZRot.Rotate( vtAx, dCosAng, dSinAng) ;
|
|
// calcolo il box trasformato
|
|
Set( ptMinRot) ;
|
|
Add( ptMinRot + vtXRot) ;
|
|
Add( ptMinRot + vtYRot) ;
|
|
Add( ptMinRot + vtZRot) ;
|
|
Add( ptMinRot + vtXRot + vtYRot) ;
|
|
Add( ptMinRot + vtYRot + vtZRot) ;
|
|
Add( ptMinRot + vtZRot + vtXRot) ;
|
|
Add( ptMinRot + vtXRot + vtYRot + vtZRot) ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
BBox3d::ToGlob( const Frame3d& frRef)
|
|
{
|
|
if ( ! IsValid())
|
|
return false ;
|
|
// trasformo il minimo
|
|
Point3d ptMinGlob = m_ptMin ;
|
|
if ( ! ptMinGlob.ToGlob( frRef))
|
|
return false ;
|
|
// trasformo i vettori dal Min al Max diretti come gli assi locali
|
|
Vector3d vtXGlob = ( m_ptMax.x - m_ptMin.x) * frRef.VersX() ;
|
|
Vector3d vtYGlob = ( m_ptMax.y - m_ptMin.y) * frRef.VersY() ;
|
|
Vector3d vtZGlob = ( m_ptMax.z - m_ptMin.z) * frRef.VersZ() ;
|
|
// calcolo il box trasformato
|
|
Set( ptMinGlob) ;
|
|
Add( ptMinGlob + vtXGlob) ;
|
|
Add( ptMinGlob + vtYGlob) ;
|
|
Add( ptMinGlob + vtZGlob) ;
|
|
Add( ptMinGlob + vtXGlob + vtYGlob) ;
|
|
Add( ptMinGlob + vtYGlob + vtZGlob) ;
|
|
Add( ptMinGlob + vtZGlob + vtXGlob) ;
|
|
Add( ptMinGlob + vtXGlob + vtYGlob + vtZGlob) ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
BBox3d::ToLoc( const Frame3d& frRef)
|
|
{
|
|
if ( ! IsValid())
|
|
return false ;
|
|
// trasformo il minimo
|
|
Point3d ptMinLoc = m_ptMin ;
|
|
if ( ! ptMinLoc.ToLoc( frRef))
|
|
return false ;
|
|
// trasformo i vettori dal Min al Max diretti come gli assi globali
|
|
Vector3d vtXLoc = ( m_ptMax.x - m_ptMin.x) *
|
|
Vector3d( frRef.VersX().x, frRef.VersY().x, frRef.VersZ().x) ;
|
|
Vector3d vtYLoc = ( m_ptMax.y - m_ptMin.y) *
|
|
Vector3d( frRef.VersX().y, frRef.VersY().y, frRef.VersZ().y) ;
|
|
Vector3d vtZLoc = ( m_ptMax.z - m_ptMin.z) *
|
|
Vector3d( frRef.VersX().z, frRef.VersY().z, frRef.VersZ().z) ;
|
|
// calcolo il box trasformato
|
|
Set( ptMinLoc) ;
|
|
Add( ptMinLoc + vtXLoc) ;
|
|
Add( ptMinLoc + vtYLoc) ;
|
|
Add( ptMinLoc + vtZLoc) ;
|
|
Add( ptMinLoc + vtXLoc + vtYLoc) ;
|
|
Add( ptMinLoc + vtYLoc + vtZLoc) ;
|
|
Add( ptMinLoc + vtZLoc + vtXLoc) ;
|
|
Add( ptMinLoc + vtXLoc + vtYLoc + vtZLoc) ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
BBox3d::LocToLoc( const Frame3d& frOri, const Frame3d& frDest)
|
|
{
|
|
if ( ! IsValid())
|
|
return false ;
|
|
// se i due riferimenti coincidono, non devo fare alcunché
|
|
if ( AreSameFrame( frOri, frDest))
|
|
return true ;
|
|
// trasformo il minimo
|
|
Point3d ptMinNewLoc = m_ptMin ;
|
|
if ( ! ptMinNewLoc.LocToLoc( frOri, frDest))
|
|
return false ;
|
|
// trasformo i vettori dal Min al Max diretti come gli assi locali
|
|
Vector3d vtXNewLoc( m_ptMax.x - m_ptMin.x, 0, 0) ;
|
|
vtXNewLoc.LocToLoc( frOri, frDest) ;
|
|
Vector3d vtYNewLoc( 0, m_ptMax.y - m_ptMin.y, 0) ;
|
|
vtYNewLoc.LocToLoc( frOri, frDest) ;
|
|
Vector3d vtZNewLoc( 0, 0, m_ptMax.z - m_ptMin.z) ;
|
|
vtZNewLoc.LocToLoc( frOri, frDest) ;
|
|
// calcolo il box trasformato
|
|
Set( ptMinNewLoc) ;
|
|
Add( ptMinNewLoc + vtXNewLoc) ;
|
|
Add( ptMinNewLoc + vtYNewLoc) ;
|
|
Add( ptMinNewLoc + vtZNewLoc) ;
|
|
Add( ptMinNewLoc + vtXNewLoc + vtYNewLoc) ;
|
|
Add( ptMinNewLoc + vtYNewLoc + vtZNewLoc) ;
|
|
Add( ptMinNewLoc + vtZNewLoc + vtXNewLoc) ;
|
|
Add( ptMinNewLoc + vtXNewLoc + vtYNewLoc + vtZNewLoc) ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
BBox3d::Encloses( const Point3d& ptP) const
|
|
{
|
|
return ( ptP.x > m_ptMin.x - EPS_SMALL && ptP.x < m_ptMax.x + EPS_SMALL &&
|
|
ptP.y > m_ptMin.y - EPS_SMALL && ptP.y < m_ptMax.y + EPS_SMALL &&
|
|
ptP.z > m_ptMin.z - EPS_SMALL && ptP.z < m_ptMax.z + EPS_SMALL) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
BBox3d::EnclosesXY( const Point3d& ptP) const
|
|
{
|
|
return ( ptP.x > m_ptMin.x - EPS_SMALL && ptP.x < m_ptMax.x + EPS_SMALL &&
|
|
ptP.y > m_ptMin.y - EPS_SMALL && ptP.y < m_ptMax.y + EPS_SMALL) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
BBox3d::Encloses( const BBox3d& b3Box) const
|
|
{
|
|
return ( Encloses( b3Box.GetMin()) && Encloses( b3Box.GetMax())) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
BBox3d::EnclosesXY( const BBox3d& b3Box) const
|
|
{
|
|
return ( EnclosesXY( b3Box.GetMin()) && EnclosesXY( b3Box.GetMax())) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
BBox3d::Overlaps( const BBox3d& b3Box) const
|
|
{
|
|
if ( m_ptMax.x < b3Box.m_ptMin.x - EPS_SMALL || m_ptMin.x > b3Box.m_ptMax.x + EPS_SMALL)
|
|
return false ;
|
|
if ( m_ptMax.y < b3Box.m_ptMin.y - EPS_SMALL || m_ptMin.y > b3Box.m_ptMax.y + EPS_SMALL)
|
|
return false ;
|
|
if ( m_ptMax.z < b3Box.m_ptMin.z - EPS_SMALL || m_ptMin.z > b3Box.m_ptMax.z + EPS_SMALL)
|
|
return false ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
BBox3d::OverlapsXY( const BBox3d& b3Box) const
|
|
{
|
|
if ( m_ptMax.x < b3Box.m_ptMin.x - EPS_SMALL || m_ptMin.x > b3Box.m_ptMax.x + EPS_SMALL)
|
|
return false ;
|
|
if ( m_ptMax.y < b3Box.m_ptMin.y - EPS_SMALL || m_ptMin.y > b3Box.m_ptMax.y + EPS_SMALL)
|
|
return false ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
inline bool
|
|
TestSeparatingAxis( const Vector3d& vtAx, const Vector3d& vtDiff, const Vector3d& vtHe,
|
|
const Vector3d& vtHe2X, const Vector3d& vtHe2Y, const Vector3d& vtHe2Z)
|
|
{
|
|
if ( vtAx.IsSmall())
|
|
return false ;
|
|
double dLen = ( vtAx.IsNormalized() ? 1 : vtAx.Len()) ;
|
|
return ( abs( vtDiff * vtAx) >
|
|
abs( vtHe.x * vtAx.x) + abs( vtHe.y * vtAx.y) + abs( vtHe.z * vtAx.z) +
|
|
abs( vtHe2X * vtAx) + abs( vtHe2Y * vtAx) + abs( vtHe2Z * vtAx) + EPS_SMALL * dLen) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
BBox3d::Overlaps( const Frame3d& frBox, const BBox3d& b3Box) const
|
|
{
|
|
// Verifico validità di entrambi i box
|
|
if ( ! IsValid() || ! b3Box.IsValid())
|
|
return false ;
|
|
|
|
// Centro e semiampiezza del box
|
|
Point3d ptCen = ( m_ptMin + m_ptMax) / 2 ;
|
|
Vector3d vtHe = ( m_ptMax - m_ptMin) / 2 ;
|
|
// Centro e semiampiezza dell'altro box
|
|
Point3d ptCen2 = GetToGlob( ( b3Box.m_ptMin + b3Box.m_ptMax) / 2, frBox) ;
|
|
Vector3d vtHe2X = GetToGlob( Vector3d( ( b3Box.GetDimX()) / 2, 0, 0), frBox) ;
|
|
Vector3d vtHe2Y = GetToGlob( Vector3d( 0, ( b3Box.GetDimY()) / 2, 0), frBox) ;
|
|
Vector3d vtHe2Z = GetToGlob( Vector3d( 0, 0, ( b3Box.GetDimZ()) / 2), frBox) ;
|
|
// Vettore tra i due centri
|
|
Vector3d vtDiff = ptCen2 - ptCen ;
|
|
|
|
// Verifico separazione sulle normali ai piani principali del riferimento globale
|
|
if ( TestSeparatingAxis( X_AX, vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
|
|
return false ;
|
|
if ( TestSeparatingAxis( Y_AX, vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
|
|
return false ;
|
|
if ( TestSeparatingAxis( Z_AX, vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
|
|
return false ;
|
|
|
|
// Verifico separazione sulle normali ai piani principali del secondo riferimento
|
|
if ( TestSeparatingAxis( frBox.VersX(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
|
|
return false ;
|
|
if ( TestSeparatingAxis( frBox.VersY(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
|
|
return false ;
|
|
if ( TestSeparatingAxis( frBox.VersZ(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
|
|
return false ;
|
|
|
|
// Verifico separazione sulle altre normali ottenute come prodotto vettoriali di quelle precedenti
|
|
if ( TestSeparatingAxis( X_AX ^ frBox.VersX(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
|
|
return false ;
|
|
if ( TestSeparatingAxis( X_AX ^ frBox.VersY(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
|
|
return false ;
|
|
if ( TestSeparatingAxis( X_AX ^ frBox.VersZ(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
|
|
return false ;
|
|
if ( TestSeparatingAxis( Y_AX ^ frBox.VersX(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
|
|
return false ;
|
|
if ( TestSeparatingAxis( Y_AX ^ frBox.VersY(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
|
|
return false ;
|
|
if ( TestSeparatingAxis( Y_AX ^ frBox.VersZ(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
|
|
return false ;
|
|
if ( TestSeparatingAxis( Z_AX ^ frBox.VersX(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
|
|
return false ;
|
|
if ( TestSeparatingAxis( Z_AX ^ frBox.VersY(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
|
|
return false ;
|
|
if ( TestSeparatingAxis( Z_AX ^ frBox.VersZ(), vtDiff, vtHe, vtHe2X, vtHe2Y, vtHe2Z))
|
|
return false ;
|
|
|
|
// Si sovrappongono
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
BBox3d::FindIntersection( const BBox3d& b3Box, BBox3d& b3Int) const
|
|
{
|
|
if ( ! IsValid() || ! b3Box.IsValid())
|
|
return false ;
|
|
// verifico direttamente la sovrapposizione
|
|
if ( m_ptMax.x < b3Box.m_ptMin.x - EPS_SMALL || m_ptMin.x > b3Box.m_ptMax.x + EPS_SMALL)
|
|
return false ;
|
|
if ( m_ptMax.y < b3Box.m_ptMin.y - EPS_SMALL || m_ptMin.y > b3Box.m_ptMax.y + EPS_SMALL)
|
|
return false ;
|
|
if ( m_ptMax.z < b3Box.m_ptMin.z - EPS_SMALL || m_ptMin.z > b3Box.m_ptMax.z + EPS_SMALL)
|
|
return false ;
|
|
// calcolo il box intersezione
|
|
b3Int.m_ptMin.x = (( m_ptMin.x >= b3Box.m_ptMin.x) ? m_ptMin.x : b3Box.m_ptMin.x) ;
|
|
b3Int.m_ptMin.y = (( m_ptMin.y >= b3Box.m_ptMin.y) ? m_ptMin.y : b3Box.m_ptMin.y) ;
|
|
b3Int.m_ptMin.z = (( m_ptMin.z >= b3Box.m_ptMin.z) ? m_ptMin.z : b3Box.m_ptMin.z) ;
|
|
b3Int.m_ptMax.x = (( m_ptMax.x <= b3Box.m_ptMax.x) ? m_ptMax.x : b3Box.m_ptMax.x) ;
|
|
b3Int.m_ptMax.y = (( m_ptMax.y <= b3Box.m_ptMax.y) ? m_ptMax.y : b3Box.m_ptMax.y) ;
|
|
b3Int.m_ptMax.z = (( m_ptMax.z <= b3Box.m_ptMax.z) ? m_ptMax.z : b3Box.m_ptMax.z) ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
BBox3d::FindIntersectionXY( const BBox3d& b3Box, BBox3d& b3Int) const
|
|
{
|
|
if ( ! IsValid() || ! b3Box.IsValid())
|
|
return false ;
|
|
// verifico direttamente la sovrapposizione
|
|
if ( m_ptMax.x < b3Box.m_ptMin.x - EPS_SMALL || m_ptMin.x > b3Box.m_ptMax.x + EPS_SMALL)
|
|
return false ;
|
|
if ( m_ptMax.y < b3Box.m_ptMin.y - EPS_SMALL || m_ptMin.y > b3Box.m_ptMax.y + EPS_SMALL)
|
|
return false ;
|
|
// calcolo il box intersezione
|
|
b3Int.m_ptMin.x = (( m_ptMin.x >= b3Box.m_ptMin.x) ? m_ptMin.x : b3Box.m_ptMin.x) ;
|
|
b3Int.m_ptMin.y = (( m_ptMin.y >= b3Box.m_ptMin.y) ? m_ptMin.y : b3Box.m_ptMin.y) ;
|
|
b3Int.m_ptMin.z = 0.5 * ( m_ptMin.z + b3Box.m_ptMin.z) ;
|
|
b3Int.m_ptMax.x = (( m_ptMax.x <= b3Box.m_ptMax.x) ? m_ptMax.x : b3Box.m_ptMax.x) ;
|
|
b3Int.m_ptMax.y = (( m_ptMax.y <= b3Box.m_ptMax.y) ? m_ptMax.y : b3Box.m_ptMax.y) ;
|
|
b3Int.m_ptMax.z = 0.5 * ( m_ptMax.z + b3Box.m_ptMax.z) ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
double
|
|
BBox3d::SqDistFromPoint( const Point3d& ptP) const
|
|
{
|
|
if ( ! IsValid())
|
|
return INFINITO ;
|
|
double dSqDist = 0 ;
|
|
if ( ptP.x < m_ptMin.x)
|
|
dSqDist += ( m_ptMin.x - ptP.x) * ( m_ptMin.x - ptP.x) ;
|
|
else if ( ptP.x > m_ptMax.x)
|
|
dSqDist += ( ptP.x - m_ptMax.x) * ( ptP.x - m_ptMax.x) ;
|
|
if ( ptP.y < m_ptMin.y)
|
|
dSqDist += ( m_ptMin.y - ptP.y) * ( m_ptMin.y - ptP.y) ;
|
|
else if ( ptP.y > m_ptMax.y)
|
|
dSqDist += ( ptP.y - m_ptMax.y) * ( ptP.y - m_ptMax.y) ;
|
|
if ( ptP.z < m_ptMin.z)
|
|
dSqDist += ( m_ptMin.z - ptP.z) * ( m_ptMin.z - ptP.z) ;
|
|
else if ( ptP.z > m_ptMax.z)
|
|
dSqDist += ( ptP.z - m_ptMax.z) * ( ptP.z - m_ptMax.z) ;
|
|
return dSqDist ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
double
|
|
BBox3d::SqDistFromPointXY( const Point3d& ptP) const
|
|
{
|
|
if ( ! IsValid())
|
|
return INFINITO ;
|
|
double dSqDist = 0 ;
|
|
if ( ptP.x < m_ptMin.x)
|
|
dSqDist += ( m_ptMin.x - ptP.x) * ( m_ptMin.x - ptP.x) ;
|
|
else if ( ptP.x > m_ptMax.x)
|
|
dSqDist += ( ptP.x - m_ptMax.x) * ( ptP.x - m_ptMax.x) ;
|
|
if ( ptP.y < m_ptMin.y)
|
|
dSqDist += ( m_ptMin.y - ptP.y) * ( m_ptMin.y - ptP.y) ;
|
|
else if ( ptP.y > m_ptMax.y)
|
|
dSqDist += ( ptP.y - m_ptMax.y) * ( ptP.y - m_ptMax.y) ;
|
|
return dSqDist ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
double
|
|
BBox3d::SqMaxDistFromPoint( const Point3d& ptP) const
|
|
{
|
|
if ( ! IsValid())
|
|
return INFINITO ;
|
|
double dDmaxX = max( abs( ptP.x - m_ptMin.x), abs( ptP.x - m_ptMax.x)) ;
|
|
double dDmaxY = max( abs( ptP.y - m_ptMin.y), abs( ptP.y - m_ptMax.y)) ;
|
|
double dDmaxZ = max( abs( ptP.z - m_ptMin.z), abs( ptP.z - m_ptMax.z)) ;
|
|
return ( dDmaxX * dDmaxX + dDmaxY * dDmaxY + dDmaxZ * dDmaxZ) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
double
|
|
BBox3d::SqMaxDistFromPointXY( const Point3d& ptP) const
|
|
{
|
|
if ( ! IsValid())
|
|
return INFINITO ;
|
|
double dDmaxX = max( abs( ptP.x - m_ptMin.x), abs( ptP.x - m_ptMax.x)) ;
|
|
double dDmaxY = max( abs( ptP.y - m_ptMin.y), abs( ptP.y - m_ptMax.y)) ;
|
|
return ( dDmaxX * dDmaxX + dDmaxY * dDmaxY) ;
|
|
}
|