Files
EgtGeomKernel/BBox3d.cpp
T
DarioS 6238ea1095 EgtGeomKernel 2.4h1 :
- in BBox3d aggiunti GetDimX, GetDimY e GetDimZ
- corretta DistLineLine con parametri punti estremi
- in creazione Stm da due curve (rigata) aggiunta gestione tipo RLT_ISOPAR_SMOOTH.
2022-08-17 19:17:44 +02:00

578 lines
19 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.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& 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
{
if ( ! IsValid() || ! b3B.IsValid())
return false ;
// 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
{
if ( ! IsValid() || ! b3B.IsValid())
return false ;
// 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 = 0.5 * ( 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 = 0.5 * ( m_ptMax.z + b3B.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) ;
}