//---------------------------------------------------------------------------- // 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.Set( 1, 0, 0) ; m_vtVersY.Set( 0, 1, 0) ; m_vtVersZ.Set( 0, 0, 1) ; break ; case BOTTOM : m_nType = BOTTOM ; m_vtVersX.Set( 1, 0, 0) ; m_vtVersY.Set( 0, -1, 0) ; m_vtVersZ.Set( 0, 0, -1) ; break ; case FRONT : m_nType = FRONT ; m_vtVersX.Set( 1, 0, 0) ; m_vtVersY.Set( 0, 0, 1) ; m_vtVersZ.Set( 0, -1, 0) ; break ; case BACK : m_nType = BACK ; m_vtVersX.Set( -1, 0, 0) ; m_vtVersY.Set( 0, 0, 1) ; m_vtVersZ.Set( 0, 1, 0) ; break ; case LEFT : m_nType = LEFT ; m_vtVersX.Set( 0, -1, 0) ; m_vtVersY.Set( 0, 0, 1) ; m_vtVersZ.Set( -1, 0, 0) ; break ; case RIGHT : m_nType = RIGHT ; m_vtVersX.Set( 0, 1, 0) ; m_vtVersY.Set( 0, 0, 1) ; m_vtVersZ.Set( 1, 0, 0) ; 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.Set( 0, 0, 0) ; m_vtVersX.Set( 1, 0, 0) ; m_vtVersY.Set( 0, 1, 0) ; m_vtVersZ.Set( 0, 0, 1) ; 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) { double dCosAng ; double dSinAng ; // verifico validità riferimento if ( m_nType == ERR) return false ; // calcolo seno e coseno dell'angolo di rotazione dCosAng = cos( dAngRad) ; dSinAng = sin( dAngRad) ; // 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à deu 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 ; } }