//---------------------------------------------------------------------------- // EgalTech 2013-2013 //---------------------------------------------------------------------------- // File : Frame3d.cpp Data : 20.11.13 Versione : 1.3a1 // Contenuto : Funzioni della classe Riferimento 3d. // // // // Modifiche : 06.01.13 DS Creazione modulo. // // //---------------------------------------------------------------------------- //--------------------------- Include ---------------------------------------- #include "stdafx.h" #include "\EgtDev\Include\EGkGeoConst.h" #include "\EgtDev\Include\EGkFrame3d.h" //---------------------------------------------------------------------------- Frame3d::Frame3d( void) { Reset() ; } //---------------------------------------------------------------------------- bool Frame3d::Set( const Point3d& ptOrig, const Vector3d& vtDirX, const Vector3d& vtDirY, const Vector3d& vtDirZ) { double dOrtXY ; double dOrtYZ ; double dOrtZX ; double dRight ; Vector3d vtTmp ; // 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 dOrtXY = m_vtVersX * m_vtVersY ; dOrtYZ = m_vtVersY * m_vtVersZ ; dOrtZX = m_vtVersZ * m_vtVersX ; vtTmp = m_vtVersX ^ m_vtVersY ; dRight = vtTmp * m_vtVersZ ; if ( fabs( dOrtXY) > EPS_ZERO || fabs( dOrtYZ) > EPS_ZERO || fabs( dOrtZX) > EPS_ZERO || dRight < EPS_ZERO) return false ; // ne determino il tipo CalculateType() ; return true ; } //---------------------------------------------------------------------------- bool Frame3d::Set( const Point3d& ptOrig, const Point3d& ptOnX, const Point3d& ptNearY) { Vector3d vtDirX ; Vector3d vtDirY ; Vector3d vtDirZ ; Vector3d vtTemp ; // calcolo il vettore che rappresenta l'asse X del piano vtDirX = ptOnX - ptOrig ; // calcolo il vettore che rappresenta un asse nel piano vtTemp = ptNearY - ptOrig ; // alcolo il vettore dell'asse Z vtDirZ = vtDirX ^ vtTemp ; // calcolo il vettore dell'asse Y vtDirY = vtDirZ ^ vtDirX ; return Set( ptOrig, vtDirX, vtDirY, vtDirZ) ; } //---------------------------------------------------------------------------- bool Frame3d::Set( const Point3d& ptOrig, Type nType) { // origine m_ptOrig = ptOrig ; // orientamento switch ( nType) { case TOP : m_nType = m_nZType ; 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 dAngRad) { 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::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 ; } //---------------------------------------------------------------------------- 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 ; } //---------------------------------------------------------------------------- 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 ; }