//---------------------------------------------------------------------------- // 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 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) ; }