//---------------------------------------------------------------------------- // EgalTech 2013-2013 //---------------------------------------------------------------------------- // File : BBox3d.cpp Data : 14.01.14 Versione : 1.5a3 // 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 //---------------------------------------------------------------------------- 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.x < ( m_ptMax.x + EPS_SMALL) && m_ptMin.y < ( m_ptMax.y + EPS_SMALL) && m_ptMin.z < ( m_ptMax.z + EPS_SMALL)) ; } //---------------------------------------------------------------------------- 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::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::ToGlob( const Frame3d& frRef) { // 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) { // 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::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::Overlaps( const BBox3d& b3B) const { if ( m_ptMax.x < b3B.m_ptMin.x - EPS_SMALL || m_ptMin.x > b3B.m_ptMax.x + EPS_SMALL) return false ; if ( m_ptMax.y < b3B.m_ptMin.y - EPS_SMALL || m_ptMin.y > b3B.m_ptMax.y + EPS_SMALL) return false ; if ( m_ptMax.z < b3B.m_ptMin.z - EPS_SMALL || m_ptMin.z > b3B.m_ptMax.z + EPS_SMALL) return false ; return true ; } //---------------------------------------------------------------------------- bool BBox3d::OverlapsXY( const BBox3d& b3B) const { if ( m_ptMax.x < b3B.m_ptMin.x - EPS_SMALL || m_ptMin.x > b3B.m_ptMax.x + EPS_SMALL) return false ; if ( m_ptMax.y < b3B.m_ptMin.y - EPS_SMALL || m_ptMin.y > b3B.m_ptMax.y + EPS_SMALL) return false ; return true ; } //---------------------------------------------------------------------------- bool BBox3d::FindIntersection( const BBox3d& b3B, BBox3d& b3Int) const { // verifico direttamente la sovrapposizione if ( m_ptMax.x < b3B.m_ptMin.x - EPS_SMALL || m_ptMin.x > b3B.m_ptMax.x + EPS_SMALL) return false ; if ( m_ptMax.y < b3B.m_ptMin.y - EPS_SMALL || m_ptMin.y > b3B.m_ptMax.y + EPS_SMALL) return false ; if ( m_ptMax.z < b3B.m_ptMin.z - EPS_SMALL || m_ptMin.z > b3B.m_ptMax.z + EPS_SMALL) return false ; // calcolo il box intersezione b3Int.m_ptMin.x = (( m_ptMin.x >= b3B.m_ptMin.x) ? m_ptMin.x : b3B.m_ptMin.x) ; b3Int.m_ptMin.y = (( m_ptMin.y >= b3B.m_ptMin.y) ? m_ptMin.y : b3B.m_ptMin.y) ; b3Int.m_ptMin.z = (( m_ptMin.z >= b3B.m_ptMin.z) ? m_ptMin.z : b3B.m_ptMin.z) ; b3Int.m_ptMax.x = (( m_ptMax.x <= b3B.m_ptMax.x) ? m_ptMax.x : b3B.m_ptMax.x) ; b3Int.m_ptMax.y = (( m_ptMax.y <= b3B.m_ptMax.y) ? m_ptMax.y : b3B.m_ptMax.y) ; b3Int.m_ptMax.z = (( m_ptMax.z <= b3B.m_ptMax.z) ? m_ptMax.z : b3B.m_ptMax.z) ; return true ; } //---------------------------------------------------------------------------- bool BBox3d::FindIntersectionXY( const BBox3d& b3B, BBox3d& b3Int) const { // verifico direttamente la sovrapposizione if ( m_ptMax.x < b3B.m_ptMin.x - EPS_SMALL || m_ptMin.x > b3B.m_ptMax.x + EPS_SMALL) return false ; if ( m_ptMax.y < b3B.m_ptMin.y - EPS_SMALL || m_ptMin.y > b3B.m_ptMax.y + EPS_SMALL) return false ; // calcolo il box intersezione b3Int.m_ptMin.x = (( m_ptMin.x >= b3B.m_ptMin.x) ? m_ptMin.x : b3B.m_ptMin.x) ; b3Int.m_ptMin.y = (( m_ptMin.y >= b3B.m_ptMin.y) ? m_ptMin.y : b3B.m_ptMin.y) ; b3Int.m_ptMin.z = (( m_ptMin.z >= b3B.m_ptMin.z) ? m_ptMin.z : b3B.m_ptMin.z) ; b3Int.m_ptMax.x = (( m_ptMax.x <= b3B.m_ptMax.x) ? m_ptMax.x : b3B.m_ptMax.x) ; b3Int.m_ptMax.y = (( m_ptMax.y <= b3B.m_ptMax.y) ? m_ptMax.y : b3B.m_ptMax.y) ; b3Int.m_ptMax.z = (( m_ptMax.z <= b3B.m_ptMax.z) ? m_ptMax.z : b3B.m_ptMax.z) ; return true ; } //---------------------------------------------------------------------------- double BBox3d::SqDistFromPoint( const Point3d& ptP) const { 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 { 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 ; }