Files
EgtGeomKernel/BBox3d.cpp
T
Dario Sassi 5d17eb9617 EgtGeomKernel 1.5g3 :
- aggiunto concatenamento di Curve
- aggiunta modifica di punto iniziale e finale di Curve
- aggiunta Add a curva composita con tolleranza
- aggiunto calcolo distanza approssimativa tra due punti (senza radice quadrata)
- riordinate funzioni per modifica e copia curve.
2014-07-28 16:17:03 +00:00

342 lines
12 KiB
C++

//----------------------------------------------------------------------------
// 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 <stdlib.h>
//----------------------------------------------------------------------------
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 ;
}