41a38fef3b
- aggiunta entità testo (con font Nfe e di sistema) - in tutte le rotate ora l'angolo è in gradi - aggiunta trasformazione Shear (scorrimento) - aggiunta trsformazione LocToLoc - Set/GetInfo specializzate per i diversi tipi di informazioni - Copy e Relocate con possibilità di indicare l'entità di riferimento rispetto a cui inserire - aggiunte trasformazioni a PolyLine.
536 lines
15 KiB
C++
536 lines
15 KiB
C++
//----------------------------------------------------------------------------
|
|
// EgalTech 2013-2014
|
|
//----------------------------------------------------------------------------
|
|
// File : Frame3d.cpp Data : 10.03.14 Versione : 1.5c4
|
|
// Contenuto : Funzioni della classe Riferimento 3d.
|
|
//
|
|
//
|
|
//
|
|
// Modifiche : 06.01.13 DS Creazione modulo.
|
|
// 10.03.14 DS Aggiunta Set con metodo OCS.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
//--------------------------- Include ----------------------------------------
|
|
#include "stdafx.h"
|
|
#include "\EgtDev\Include\EGkFrame3d.h"
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Frame3d::Set( const Point3d& ptOrig, const Vector3d& vtDirX,
|
|
const Vector3d& vtDirY, const Vector3d& vtDirZ)
|
|
{
|
|
// lo inizializzo come errato
|
|
m_nType = ERR ;
|
|
m_nZType = ERR ;
|
|
|
|
// assegnazione dell'origine e delle direzioni
|
|
m_ptOrig = ptOrig ;
|
|
m_vtVersX = vtDirX ;
|
|
m_vtVersY = vtDirY ;
|
|
m_vtVersZ = vtDirZ ;
|
|
|
|
// se le direzioni non sono normalizzabili, errore
|
|
if ( ! m_vtVersX.Normalize() ||
|
|
! m_vtVersY.Normalize() ||
|
|
! m_vtVersZ.Normalize())
|
|
return false ;
|
|
|
|
// verifica della ortogonalità dei versori e del senso destrorso
|
|
if ( ! Verify())
|
|
return false ;
|
|
|
|
// ne determino il tipo
|
|
CalculateType() ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Frame3d::Set( const Point3d& ptOrig, const Point3d& ptOnX, const Point3d& ptNearY)
|
|
{
|
|
// lo inizializzo come errato
|
|
m_nType = ERR ;
|
|
m_nZType = ERR ;
|
|
|
|
// origine
|
|
m_ptOrig = ptOrig ;
|
|
// calcolo il versore X
|
|
m_vtVersX = ptOnX - ptOrig ;
|
|
if ( ! m_vtVersX.Normalize())
|
|
return false ;
|
|
// calcolo il vettore che rappresenta un asse nel piano
|
|
Vector3d vtTemp = ptNearY - ptOrig ;
|
|
// calcolo il versore Z
|
|
m_vtVersZ = m_vtVersX ^ vtTemp ;
|
|
if ( ! m_vtVersZ.Normalize())
|
|
return false ;
|
|
// calcolo il versore Y
|
|
m_vtVersY = m_vtVersZ ^ m_vtVersX ;
|
|
if ( ! m_vtVersY.Normalize())
|
|
return false ;
|
|
|
|
// verifica della ortogonalità dei versori e del senso destrorso
|
|
if ( ! Verify())
|
|
return false ;
|
|
|
|
// ne determino il tipo
|
|
CalculateType() ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Frame3d::Set( const Point3d& ptOrig, const Vector3d& vtDirZ)
|
|
{
|
|
// lo inizializzo come errato
|
|
m_nType = ERR ;
|
|
m_nZType = ERR ;
|
|
|
|
// origine
|
|
m_ptOrig = ptOrig ;
|
|
// versore Z
|
|
m_vtVersZ = vtDirZ ;
|
|
if ( ! m_vtVersZ.Normalize())
|
|
return false ;
|
|
// versore X (metodo OCS di DXF)
|
|
if ( fabs( m_vtVersZ.x) < 1./64. && fabs( m_vtVersZ.y) < 1./64.)
|
|
m_vtVersX = Y_AX ^ m_vtVersZ ;
|
|
else
|
|
m_vtVersX = Z_AX ^ m_vtVersZ ;
|
|
if ( ! m_vtVersX.Normalize())
|
|
return false ;
|
|
// verzsore Y
|
|
m_vtVersY = m_vtVersZ ^ m_vtVersX ;
|
|
if ( ! m_vtVersY.Normalize())
|
|
return false ;
|
|
|
|
// verifica della ortogonalità dei versori e del senso destrorso
|
|
if ( ! Verify())
|
|
return false ;
|
|
|
|
// ne determino il tipo
|
|
CalculateType() ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Frame3d::Set( const Point3d& ptOrig, const Vector3d& vtDirZ, const Vector3d& vtNearDirX)
|
|
{
|
|
// lo inizializzo come errato
|
|
m_nType = ERR ;
|
|
m_nZType = ERR ;
|
|
|
|
// origine
|
|
m_ptOrig = ptOrig ;
|
|
// versore Z
|
|
m_vtVersZ = vtDirZ ;
|
|
if ( ! m_vtVersZ.Normalize())
|
|
return false ;
|
|
// versore Y
|
|
m_vtVersY = m_vtVersZ ^ vtNearDirX ;
|
|
if ( ! m_vtVersY.Normalize())
|
|
return false ;
|
|
// verzsore X
|
|
m_vtVersX = m_vtVersY ^ m_vtVersZ ;
|
|
if ( ! m_vtVersX.Normalize())
|
|
return false ;
|
|
|
|
// verifica della ortogonalità dei versori e del senso destrorso
|
|
if ( ! Verify())
|
|
return false ;
|
|
|
|
// ne determino il tipo
|
|
CalculateType() ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Frame3d::Set( const Point3d& ptOrig, Type nType)
|
|
{
|
|
// origine
|
|
m_ptOrig = ptOrig ;
|
|
// orientamento
|
|
switch ( nType) {
|
|
case TOP :
|
|
m_nType = TOP ;
|
|
m_vtVersX = X_AX ;
|
|
m_vtVersY = Y_AX ;
|
|
m_vtVersZ = Z_AX ;
|
|
break ;
|
|
case BOTTOM :
|
|
m_nType = BOTTOM ;
|
|
m_vtVersX = X_AX ;
|
|
m_vtVersY = - Y_AX ;
|
|
m_vtVersZ = - Z_AX ;
|
|
break ;
|
|
case FRONT :
|
|
m_nType = FRONT ;
|
|
m_vtVersX = X_AX ;
|
|
m_vtVersY = Z_AX ;
|
|
m_vtVersZ = - Y_AX ;
|
|
break ;
|
|
case BACK :
|
|
m_nType = BACK ;
|
|
m_vtVersX = - X_AX ;
|
|
m_vtVersY = Z_AX ;
|
|
m_vtVersZ = Y_AX ;
|
|
break ;
|
|
case LEFT :
|
|
m_nType = LEFT ;
|
|
m_vtVersX = - Y_AX ;
|
|
m_vtVersY = Z_AX ;
|
|
m_vtVersZ = - X_AX ;
|
|
break ;
|
|
case RIGHT :
|
|
m_nType = RIGHT ;
|
|
m_vtVersX = Y_AX ;
|
|
m_vtVersY = Z_AX ;
|
|
m_vtVersZ = X_AX ;
|
|
break ;
|
|
default :
|
|
m_nType = ERR ;
|
|
break ;
|
|
}
|
|
// orientamento di Z coincide con quello generale
|
|
m_nZType = m_nType ;
|
|
|
|
return ( m_nType != ERR) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Frame3d::Reset( void)
|
|
{
|
|
m_nType = TOP ;
|
|
m_nZType = TOP ;
|
|
m_ptOrig = ORIG ;
|
|
m_vtVersX = X_AX ;
|
|
m_vtVersY = Y_AX ;
|
|
m_vtVersZ = Z_AX ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void
|
|
Frame3d::Translate( const Vector3d& vtMove)
|
|
{
|
|
// verifico validità riferimento
|
|
if ( m_nType == ERR)
|
|
return ;
|
|
|
|
// eseguo la traslazione
|
|
m_ptOrig.Translate( vtMove) ;
|
|
|
|
// il tipo non cambia (dipende dall'orientamento e non dalla posizione)
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Frame3d::Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dAngDeg)
|
|
{
|
|
double dAngRad = dAngDeg * DEGTORAD ;
|
|
return Rotate( ptAx, vtAx, cos( dAngRad), sin( dAngRad)) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Frame3d::Rotate( const Point3d& ptAx, const Vector3d& vtAx, double dCosAng, double dSinAng)
|
|
{
|
|
// verifico validità riferimento
|
|
if ( m_nType == ERR)
|
|
return false ;
|
|
|
|
// controllo solo la prima rotazione, per le altre è lo stesso
|
|
if ( ! m_ptOrig.Rotate( ptAx, vtAx, dCosAng, dSinAng)) {
|
|
m_nType = ERR ;
|
|
m_nZType = ERR ;
|
|
return false ;
|
|
}
|
|
m_vtVersX.Rotate( vtAx, dCosAng, dSinAng) ;
|
|
m_vtVersY.Rotate( vtAx, dCosAng, dSinAng) ;
|
|
m_vtVersZ.Rotate( vtAx, dCosAng, dSinAng) ;
|
|
|
|
// ricalcolo il tipo
|
|
CalculateType() ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Frame3d::PseudoScale( const Frame3d& frRef, double dCoeffX, double dCoeffY, double dCoeffZ)
|
|
{
|
|
const double AXIS_LEN = 100 ;
|
|
|
|
// verifico validità dei frame
|
|
if ( m_nType == ERR || frRef.GetType() == ERR)
|
|
return false ;
|
|
|
|
// scalatura dell'origine
|
|
Point3d ptOrigS = m_ptOrig ;
|
|
ptOrigS.Scale( frRef, dCoeffX, dCoeffY, dCoeffZ) ;
|
|
|
|
// calcolo trasformazione del versore Z
|
|
Point3d ptDirZS = m_ptOrig + AXIS_LEN * m_vtVersZ ;
|
|
ptDirZS.Scale( frRef, dCoeffX, dCoeffY, dCoeffZ) ;
|
|
Vector3d vtVersZS = ptDirZS - ptOrigS ;
|
|
vtVersZS.Normalize() ;
|
|
// se il versore Z non cambia, basta applicare l'origine scalata
|
|
if ( AreSameVectorExact( m_vtVersZ, vtVersZS)) {
|
|
m_ptOrig = ptOrigS ;
|
|
return true ;
|
|
}
|
|
|
|
// altrimenti, devo scalare anche i versori X e Y
|
|
Point3d ptDirXS = m_ptOrig + AXIS_LEN * m_vtVersX ;
|
|
ptDirXS.Scale( frRef, dCoeffX, dCoeffY, dCoeffZ) ;
|
|
Point3d ptDirYS = m_ptOrig + AXIS_LEN * m_vtVersY ;
|
|
ptDirYS.Scale( frRef, dCoeffX, dCoeffY, dCoeffZ) ;
|
|
Frame3d frRefS ;
|
|
if ( ! frRefS.Set( ptOrigS, ptDirXS, ptDirYS))
|
|
return false ;
|
|
*this = frRefS ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Frame3d::PseudoMirror( const Point3d& ptOn, const Vector3d& vtNorm)
|
|
{
|
|
// verifico validità riferimento
|
|
if ( m_nType == ERR)
|
|
return false ;
|
|
|
|
// mirror dell'origine
|
|
m_ptOrig.Mirror( ptOn, vtNorm) ;
|
|
// mirror dei versori Y e Z
|
|
m_vtVersY.Mirror( vtNorm) ;
|
|
m_vtVersZ.Mirror( vtNorm) ;
|
|
// ricalcolo del versore X (per mantenere il senso destrorso)
|
|
m_vtVersX = m_vtVersY ^ m_vtVersZ ;
|
|
|
|
// ne determino il tipo
|
|
CalculateType() ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Frame3d::PseudoShear( const Point3d& ptOn, const Vector3d& vtNorm, const Vector3d& vtDir, double dCoeff)
|
|
{
|
|
const double AXIS_LEN = 100 ;
|
|
|
|
// verifico validità riferimento
|
|
if ( m_nType == ERR)
|
|
return false ;
|
|
|
|
// shear dell'origine e di due punti sugli assi X e Y
|
|
Point3d ptOrigS = m_ptOrig ;
|
|
ptOrigS.Shear( ptOn, vtNorm, vtDir, dCoeff) ;
|
|
Point3d ptDirXS = m_ptOrig + AXIS_LEN * m_vtVersX ;
|
|
ptDirXS.Shear( ptOn, vtNorm, vtDir, dCoeff) ;
|
|
Point3d ptDirYS = m_ptOrig + AXIS_LEN * m_vtVersY ;
|
|
ptDirYS.Shear( ptOn, vtNorm, vtDir, dCoeff) ;
|
|
|
|
// calcolo di un nuovo riferimento
|
|
Frame3d frRefS ;
|
|
if ( ! frRefS.Set( ptOrigS, ptDirXS, ptDirYS))
|
|
return false ;
|
|
// assegnazione del risultato
|
|
*this = frRefS ;
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Frame3d::Invert( void)
|
|
{
|
|
Frame3d frInv = GLOB_FRM ;
|
|
|
|
|
|
if ( frInv.ToLoc( *this)) {
|
|
*this = frInv ;
|
|
return true ;
|
|
}
|
|
else
|
|
return false ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Cambio di riferimento : dal riferimento al globale
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Frame3d::ToGlob( const Frame3d& frRef)
|
|
{
|
|
// verifico validità del frame
|
|
if ( GetType() == ERR || frRef.GetType() == ERR)
|
|
return false ;
|
|
|
|
// eseguo la trasformazione
|
|
m_ptOrig.ToGlob( frRef) ;
|
|
m_vtVersX.ToGlob( frRef) ;
|
|
m_vtVersY.ToGlob( frRef) ;
|
|
m_vtVersZ.ToGlob( frRef) ;
|
|
|
|
// ricalcolo il tipo
|
|
CalculateType() ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Cambio di riferimento : dal globale al riferimento
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Frame3d::ToLoc( const Frame3d& frRef)
|
|
{
|
|
// verifico validità dei frame
|
|
if ( GetType() == ERR || frRef.GetType() == ERR)
|
|
return false ;
|
|
|
|
// eseguo la trasformazione
|
|
m_ptOrig.ToLoc( frRef) ;
|
|
m_vtVersX.ToLoc( frRef) ;
|
|
m_vtVersY.ToLoc( frRef) ;
|
|
m_vtVersZ.ToLoc( frRef) ;
|
|
|
|
// ricalcolo il tipo
|
|
CalculateType() ;
|
|
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Cambio di riferimento : dal primo riferimento al secondo
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Frame3d::LocToLoc( const Frame3d& frOri, const Frame3d& frDest)
|
|
{
|
|
// se i due riferimenti coincidono, non devo fare alcunché
|
|
if ( AreSameFrame( frOri, frDest))
|
|
return true ;
|
|
|
|
return ( ToGlob( frOri) && ToLoc( frDest)) ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Frame3d::Verify( void)
|
|
{
|
|
// verifica della ortogonalità dei versori e del senso destrorso
|
|
double dOrtXY = m_vtVersX * m_vtVersY ;
|
|
double dOrtYZ = m_vtVersY * m_vtVersZ ;
|
|
double dOrtZX = m_vtVersZ * m_vtVersX ;
|
|
Vector3d vtTmp = m_vtVersX ^ m_vtVersY ;
|
|
double dRight = vtTmp * m_vtVersZ ;
|
|
if ( fabs( dOrtXY) > EPS_ZERO ||
|
|
fabs( dOrtYZ) > EPS_ZERO ||
|
|
fabs( dOrtZX) > EPS_ZERO ||
|
|
dRight < EPS_ZERO)
|
|
return false ;
|
|
else
|
|
return true ;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void
|
|
Frame3d::CalculateType( void)
|
|
{
|
|
// riferimento errato
|
|
m_nType = ERR ;
|
|
m_nZType = ERR ;
|
|
|
|
// se la Zloc non ha componenti x e y globali allora é diretta come Zglob
|
|
if ( fabs( m_vtVersZ.x) < EPS_ZERO && fabs( m_vtVersZ.y) < EPS_ZERO) {
|
|
// se inoltre ha lo stesso verso di Zglob
|
|
if ( m_vtVersZ.z > 0)
|
|
m_nZType = TOP ;
|
|
else
|
|
m_nZType = BOTTOM ;
|
|
// se la Xloc coincide con Xglob Type coincide con ZType
|
|
if ( fabs( m_vtVersX.y) < EPS_ZERO && fabs( m_vtVersX.z) < EPS_ZERO &&
|
|
m_vtVersX.x > 0)
|
|
m_nType = m_nZType ;
|
|
else
|
|
m_nType = GEN ;
|
|
}
|
|
|
|
// se la Zloc non ha componenti y e z globali allora é diretta come Xglob
|
|
else if ( fabs( m_vtVersZ.y) < EPS_ZERO && fabs( m_vtVersZ.z) < EPS_ZERO) {
|
|
// se inoltre ha lo stesso verso di Xglob
|
|
if ( m_vtVersZ.x > 0)
|
|
m_nZType = RIGHT ;
|
|
else
|
|
m_nZType = LEFT ;
|
|
// se la Yloc coincide con Zglob Type coincide con ZType
|
|
if ( fabs( m_vtVersY.x) < EPS_ZERO && fabs( m_vtVersY.y) < EPS_ZERO &&
|
|
m_vtVersY.z > 0)
|
|
m_nType = m_nZType ;
|
|
else
|
|
m_nType = GEN ;
|
|
}
|
|
|
|
// se la Zloc non ha componenti z e x globali allora é diretta come Yglob
|
|
else if ( fabs( m_vtVersZ.z) < EPS_ZERO && fabs( m_vtVersZ.x) < EPS_ZERO) {
|
|
// se inoltre ha lo stesso verso di Yglob
|
|
if ( m_vtVersZ.y > 0)
|
|
m_nZType = BACK ;
|
|
else
|
|
m_nZType = FRONT ;
|
|
// se la Yloc coincide con Zglob Type coincide con ZType
|
|
if ( fabs( m_vtVersY.x) < EPS_ZERO && fabs( m_vtVersY.y) < EPS_ZERO &&
|
|
m_vtVersY.z > 0)
|
|
m_nType = m_nZType ;
|
|
else
|
|
m_nType = GEN ;
|
|
}
|
|
|
|
// altrimenti é generico
|
|
else {
|
|
m_nZType = GEN ;
|
|
m_nType = GEN ;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool
|
|
Frame3d::GetRotationsCAC1( double& dAngCDeg, double& dAngADeg, double& dAngC1Deg) const
|
|
{
|
|
bool bDet ;
|
|
double dAngVertDeg ;
|
|
double dAngOrizzDeg ;
|
|
Vector3d vtXnoC1 ;
|
|
|
|
|
|
// verifico validità riferimento
|
|
if ( m_nType == ERR)
|
|
return false ;
|
|
|
|
// calcolo angoli sferici del versore Z
|
|
m_vtVersZ.ToSpherical( nullptr, &dAngVertDeg, &dAngOrizzDeg) ;
|
|
dAngADeg = dAngVertDeg ;
|
|
|
|
// ricavo la prima rotazione attorno a Z
|
|
if ( dAngADeg > EPS_ANG_SMALL)
|
|
dAngCDeg = dAngOrizzDeg + 90 ;
|
|
else
|
|
m_vtVersX.ToSpherical( nullptr, nullptr, &dAngCDeg) ;
|
|
|
|
// calcolo l'asse X senza la rotazione attorno a C'
|
|
vtXnoC1.FromPolar( 1, dAngCDeg) ;
|
|
|
|
// calcolo la rotazione attorno a C'
|
|
if ( ! vtXnoC1.GetRotation( m_vtVersX, m_vtVersZ, dAngC1Deg, bDet) || ! bDet)
|
|
dAngC1Deg = 0 ;
|
|
|
|
return true ;
|
|
} |