Files
Include/EGkPoint3d.h
T
Dario Sassi c57e44db02 Include :
- unificazione funzioni AreSamePoint***
- aggiornamento mensile codici protezione librerie.
2024-08-06 14:41:25 +02:00

433 lines
16 KiB
C++

//----------------------------------------------------------------------------
// EgalTech 2013-2023
//----------------------------------------------------------------------------
// File : EGkPoint3d.h Data : 23.08.23 Versione : 2.5h2
// Contenuto : Dichiarazione della classe Punto 3d.
//
//
//
// Modifiche : 30.12.12 DS Creazione modulo.
// 23.08.23 DS Aggiunto P_INVALID.
//
//
//----------------------------------------------------------------------------
#pragma once
#include "/EgtDev/Include/EGkVector3d.h"
//----------------------- Macro per import/export ----------------------------
#undef EGK_EXPORT
#if defined( I_AM_EGK) // da definirsi solo nella DLL
#define EGK_EXPORT __declspec( dllexport)
#else
#define EGK_EXPORT __declspec( dllimport)
#endif
//-------------------------- Forward Definition -------------------------------
class Frame3d ;
//-----------------------------------------------------------------------------
class EGK_EXPORT Point3d
{
public :
//! Costruttore del punto con tre componenti X, Y e Z
Point3d( double dX, double dY, double dZ) : x( dX), y( dY), z( dZ) {}
//! Costruttore del punto da un array di tre componenti
Point3d( const double V[3]) : x( V[0]), y( V[1]), z( V[2]) {}
//! Costruttore del punto con due componenti X e Y, Z = 0
Point3d( double dX, double dY) : x( dX), y( dY), z( 0) {}
//! Costruttore del punto origine X = Y = Z = 0
Point3d( void) : x( 0), y( 0), z( 0) {}
//! Assegnazione delle componenti X, Y e Z al punto
void Set( double dX, double dY, double dZ) { x = dX ; y = dY ; z = dZ ;}
public :
//! Verifica la validità delle coordinate del punto
bool IsValid( void) const
{ return ( std::isfinite( x) && std::isfinite( y) && std::isfinite( z)) ; }
//! Verifica se il punto è quasi l'origine
bool IsSmall( void) const
{ return ( ( x * x + y * y + z * z) < SQ_EPS_SMALL) ; }
//! Verifica se il punto è esattamente l'origine
bool IsZero( void) const
{ return ( ( x * x + y * y + z * z) < SQ_EPS_ZERO) ; }
//! Somma sul posto con un vettore
Point3d& operator +=( const Vector3d& vtV)
{ x += vtV.x ; y += vtV.y ; z += vtV.z ; return *this ; }
//! Sottrazione sul posto con un vettore
Point3d& operator -=( const Vector3d& vtV)
{ x -= vtV.x ; y -= vtV.y ; z -= vtV.z ; return *this ; }
//! Somma sul posto con un altro punto (valida solo se equivalente ad una combinazione baricentrica)
Point3d& operator +=( const Point3d& ptP)
{ x += ptP.x ; y += ptP.y ; z += ptP.z ; return *this ; }
//! Moltiplicazione sul posto con un numero
Point3d& operator *=( double dMul)
{ x *= dMul ; y *= dMul ; z *= dMul ; return *this ; }
//! Divisione sul posto con un numero
Point3d& operator /=( double dDiv)
{ double dMul = 1 / dDiv ; x *= dMul ; y *= dMul ; z *= dMul ; return *this ; }
//! Traslazione dato il vettore di movimento
void Translate( const Vector3d& vtMove) ;
//! Rotazione attorno ad un asse per un punto, dato l'angolo in gradi
bool Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dAngDeg) ;
//! Rotazione attorno ad un asse per un punto, dati coseno e seno dell'angolo di rotazione
bool Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAng, double dSinAng) ;
//! Scalatura non uniforme
bool Scale( const Frame3d& frRef, double dCoeffX, double dCoeffY, double dCoeffZ) ;
//! Specchiatura
bool Mirror( const Point3d& ptOn, const Vector3d& vtNorm) ;
//! Scorrimento
bool Shear( const Point3d& ptOn, const Vector3d& vtNorm, const Vector3d& vtDir, double dCoeff) ;
//! Cambio di riferimento : dal riferimento al globale
bool ToGlob( const Frame3d& frRef) ;
//! Cambio di riferimento : dal globale al riferimento
bool ToLoc( const Frame3d& frRef) ;
//! Cambio di riferimento : dal primo riferimento al secondo
bool LocToLoc( const Frame3d& frOri, const Frame3d& frDest) ;
public :
union {
struct {
double x ; //!< coordinata sull'asse X
double y ; //!< coordinata sull'asse Y
double z ; //!< coordinata sull'asse Z
} ;
double v[3] ; //!< equivalente vettoriale delle tre coordinate
} ;
} ;
//----------------------------------------------------------------------------
// Punti notevoli
//----------------------------------------------------------------------------
//! Punto non valido
const Point3d P_INVALID( NAN, NAN, NAN) ;
//! Punto origine
const Point3d ORIG( 0, 0, 0) ;
//----------------------------------------------------------------------------
//! Somma di due punti (valida solo se equivalente ad una combinazione baricentrica)
//----------------------------------------------------------------------------
inline const Point3d
operator+( const Point3d& ptP1, const Point3d& ptP2)
{
return Point3d( ptP1.x + ptP2.x, ptP1.y + ptP2.y, ptP1.z + ptP2.z) ;
}
//----------------------------------------------------------------------------
//! Somma di un punto e un vettore
//----------------------------------------------------------------------------
inline const Point3d
operator+( const Point3d& ptP1, const Vector3d& vtV2)
{
return Point3d( ptP1.x + vtV2.x, ptP1.y + vtV2.y, ptP1.z + vtV2.z) ;
}
//----------------------------------------------------------------------------
//! Opposto di un punto, genera un vettore
//----------------------------------------------------------------------------
inline const Vector3d
operator-( const Point3d& ptP)
{
return Vector3d( - ptP.x, - ptP.y, - ptP.z) ;
}
//----------------------------------------------------------------------------
//! Differenza di due punti, genera un vettore
//----------------------------------------------------------------------------
inline const Vector3d
operator-( const Point3d& ptP1, const Point3d& ptP2)
{
return Vector3d( ptP1.x - ptP2.x, ptP1.y - ptP2.y, ptP1.z - ptP2.z) ;
}
//----------------------------------------------------------------------------
//! Sottrazione di un punto e un vettore
//----------------------------------------------------------------------------
inline const Point3d
operator-( const Point3d& ptP1, const Vector3d& vtV2)
{
return Point3d( ptP1.x - vtV2.x, ptP1.y - vtV2.y, ptP1.z - vtV2.z) ;
}
//----------------------------------------------------------------------------
//! Prodotto con uno scalare
//----------------------------------------------------------------------------
inline const Point3d
operator*( const Point3d& ptP, double dMul)
{
return Point3d( ptP.x * dMul, ptP.y * dMul, ptP.z * dMul) ;
}
//----------------------------------------------------------------------------
//! Prodotto di uno scalare con un punto
//----------------------------------------------------------------------------
inline const Point3d
operator*( double dMul, const Point3d& ptP)
{
return Point3d( ptP.x * dMul, ptP.y * dMul, ptP.z * dMul) ;
}
//----------------------------------------------------------------------------
//! Divisione per uno scalare
//----------------------------------------------------------------------------
inline const Point3d
operator/( const Point3d& ptP, double dDiv)
{
double dMul ;
dMul = 1 / dDiv ;
return ( Point3d( ptP.x * dMul, ptP.y * dMul, ptP.z * dMul)) ;
}
//----------------------------------------------------------------------------
//! Somma mediata di due punti (baricentrica)
//----------------------------------------------------------------------------
inline const Point3d
Media( const Point3d& ptP1, const Point3d& ptP2, double dCoeff = 0.5)
{
return Point3d( ( 1 - dCoeff) * ptP1.x + dCoeff * ptP2.x,
( 1 - dCoeff) * ptP1.y + dCoeff * ptP2.y,
( 1 - dCoeff) * ptP1.z + dCoeff * ptP2.z) ;
}
//----------------------------------------------------------------------------
//! Approssimazione della distanza tra due punti (errore <= 8%)
// ( vedi Graphics Gem I pag 432 )
//----------------------------------------------------------------------------
inline double
ApproxDist( const Point3d& ptP1, const Point3d& ptP2)
{
double dMax = abs( ptP1.x - ptP2.x) ;
double dMed = abs( ptP1.y - ptP2.y) ;
double dMin = abs( ptP1.z - ptP2.z) ;
if ( dMax < dMed) {
double dTmp = dMax ;
dMax = dMed ;
dMed = dTmp ;
}
if ( dMax < dMin) {
double dTmp = dMax ;
dMax = dMin ;
dMin = dTmp ;
}
if ( dMed < dMin) {
double dTmp = dMed ;
dMed = dMin ;
dMin = dTmp ;
}
return ( dMax + 0.34375 * dMed + 0.25 * dMin) ;
}
//----------------------------------------------------------------------------
//! Approssimazione della distanza tra due punti nel piano XY (errore <= 5%)
// ( vedi Graphics Gem I pag 427 + articolo di R. Baptista su FlipCode )
//----------------------------------------------------------------------------
inline double
ApproxDistXY( const Point3d& ptP1, const Point3d& ptP2)
{
double dMax = abs( ptP1.x - ptP2.x) ;
double dMin = abs( ptP1.y - ptP2.y) ;
if ( dMax < dMin) {
double dTmp = dMax ;
dMax = dMin ;
dMin = dTmp ;
}
return ( 0.9833984375 * dMax + 0.4306640625 * dMin) ;
}
//----------------------------------------------------------------------------
//! Quadrato della distanza tra due punti
//----------------------------------------------------------------------------
inline double
SqDist( const Point3d& ptP1, const Point3d& ptP2)
{
double dX = ptP1.x - ptP2.x ;
double dY = ptP1.y - ptP2.y ;
double dZ = ptP1.z - ptP2.z ;
return ( dX * dX + dY * dY + dZ * dZ) ;
}
//----------------------------------------------------------------------------
//! Quadrato della distanza tra due punti nel piano XY
//----------------------------------------------------------------------------
inline double
SqDistXY( const Point3d& ptP1, const Point3d& ptP2)
{
double dX = ptP1.x - ptP2.x ;
double dY = ptP1.y - ptP2.y ;
return ( dX * dX + dY * dY) ;
}
//----------------------------------------------------------------------------
//! Distanza tra due punti
//----------------------------------------------------------------------------
inline double
Dist( const Point3d& ptP1, const Point3d& ptP2)
{
double dX = ptP1.x - ptP2.x ;
double dY = ptP1.y - ptP2.y ;
double dZ = ptP1.z - ptP2.z ;
if ( abs( dY) < EPS_ZERO && abs( dZ) < EPS_ZERO)
return abs( dX) ;
if ( abs( dZ) < EPS_ZERO && abs( dX) < EPS_ZERO)
return abs( dY) ;
if ( abs( dX) < EPS_ZERO && abs( dY) < EPS_ZERO)
return abs( dZ) ;
return sqrt( dX * dX + dY * dY + dZ * dZ) ;
}
//----------------------------------------------------------------------------
//! Distanza tra due punti nel piano XY
//----------------------------------------------------------------------------
inline double
DistXY( const Point3d& ptP1, const Point3d& ptP2)
{
double dX = ptP1.x - ptP2.x ;
double dY = ptP1.y - ptP2.y ;
if ( abs( dY) < EPS_ZERO)
return abs( dX) ;
if ( abs( dX) < EPS_ZERO)
return abs( dY) ;
return sqrt( dX * dX + dY * dY) ;
}
//----------------------------------------------------------------------------
//! Direzione e distanza tra due punti ( P1 -> P2)
//----------------------------------------------------------------------------
inline bool
DirDist( const Point3d& ptP1, const Point3d& ptP2, Vector3d& vtDir, double& dDist)
{
dDist = Dist( ptP1, ptP2) ;
// se distanza significativa
if ( dDist > EPS_SMALL) {
vtDir = ( ptP2 - ptP1) / dDist ;
return true ;
}
// punti praticamente coincidenti
vtDir.Set( 0, 0, 0) ;
return false ;
}
//----------------------------------------------------------------------------
//! Verifica se due punti sono quasi coincidenti (tolleranza come parametro)
//----------------------------------------------------------------------------
inline bool
AreSamePointEpsilon( const Point3d& ptP1, const Point3d& ptP2, double dToler)
{
double dX = ptP1.x - ptP2.x ;
if ( abs( dX) > dToler)
return false ;
double dY = ptP1.y - ptP2.y ;
if ( abs( dY) > dToler)
return false ;
double dZ = ptP1.z - ptP2.z ;
if ( abs( dZ) > dToler)
return false ;
return ( ( dX * dX + dY * dY + dZ * dZ) < ( dToler * dToler)) ;
}
//----------------------------------------------------------------------------
//! Verifica se due punti sono quasi coincidenti nel piano XY (tolleranza come parametro)
//----------------------------------------------------------------------------
inline bool
AreSamePointXYEpsilon( const Point3d& ptP1, const Point3d& ptP2, double dToler)
{
return ( SqDistXY( ptP1, ptP2) < ( dToler * dToler)) ;
}
//----------------------------------------------------------------------------
//! Verifica se due punti sono quasi coincidenti (Small error -> Approx)
//----------------------------------------------------------------------------
inline bool
AreSamePointApprox( const Point3d& ptP1, const Point3d& ptP2)
{
double dX = ptP1.x - ptP2.x ;
if ( abs( dX) > EPS_SMALL)
return false ;
double dY = ptP1.y - ptP2.y ;
if ( abs( dY) > EPS_SMALL)
return false ;
double dZ = ptP1.z - ptP2.z ;
if ( abs( dZ) > EPS_SMALL)
return false ;
return ( ( dX * dX + dY * dY + dZ * dZ) < SQ_EPS_SMALL) ;
}
//----------------------------------------------------------------------------
//! Verifica se due punti sono quasi coincidenti nel piano XY (Small error -> Approx)
//----------------------------------------------------------------------------
inline bool
AreSamePointXYApprox( const Point3d& ptP1, const Point3d& ptP2)
{
return ( SqDistXY( ptP1, ptP2) < SQ_EPS_SMALL) ;
}
//----------------------------------------------------------------------------
//! Verifica se due punti sono esattamente coincidenti (Zero error -> Exact)
//----------------------------------------------------------------------------
inline bool
AreSamePointExact( const Point3d& ptP1, const Point3d& ptP2)
{
double dX = ptP1.x - ptP2.x ;
if ( abs( dX) > EPS_ZERO)
return false ;
double dY = ptP1.y - ptP2.y ;
if ( abs( dY) > EPS_ZERO)
return false ;
double dZ = ptP1.z - ptP2.z ;
if ( abs( dZ) > EPS_ZERO)
return false ;
return ( ( dX * dX + dY * dY + dZ * dZ) < SQ_EPS_ZERO) ;
}
//----------------------------------------------------------------------------
//! Verifica se due punti sono esattamente coincidenti nel piano XY (Zero error -> Exact)
//----------------------------------------------------------------------------
inline bool
AreSamePointXYExact( const Point3d& ptP1, const Point3d& ptP2)
{
return ( SqDistXY( ptP1, ptP2) < SQ_EPS_ZERO) ;
}
//----------------------------------------------------------------------------
//! Restituisce una copia in locale del punto passato
//----------------------------------------------------------------------------
inline const Point3d
GetToLoc( const Point3d& ptP, const Frame3d& frRef)
{
Point3d ptQ = ptP ;
ptQ.ToLoc( frRef) ;
return ptQ ;
}
//----------------------------------------------------------------------------
//! Restituisce una copia in globale del punto passato
//----------------------------------------------------------------------------
inline const Point3d
GetToGlob( const Point3d& ptP, const Frame3d& frRef)
{
Point3d ptQ = ptP ;
ptQ.ToGlob( frRef) ;
return ptQ ;
}
//----------------------------------------------------------------------------
//! Restituisce una copia dal primo al secondo riferimento del punto passato
//----------------------------------------------------------------------------
inline const Point3d
GetLocToLoc( const Point3d& ptP, const Frame3d& frOri, const Frame3d& frDest)
{
Point3d ptQ = ptP ;
ptQ.LocToLoc( frOri, frDest) ;
return ptQ ;
}