SIBCRotationd.h

Go to the documentation of this file.
00001 //***************************************************************************************
00002 // File supervisor: Crosswalk team
00012 //***************************************************************************************
00013 
00014 #if (_MSC_VER > 1000) || defined(SGI_COMPILER)
00015 #pragma once
00016 #endif
00017 
00018 //******************************************************************************
00019 // Defines
00020 //******************************************************************************
00021 
00022 #ifndef _ROTATION_H_
00023 #define _ROTATION_H_
00024 
00025 //******************************************************************************
00026 // Includes
00027 //******************************************************************************
00028 
00029 #include "SIBCMathLib.h"
00030 
00031 //******************************************************************************
00032 // Typedefs
00033 //******************************************************************************
00034 
00035 // Utility functions
00045 double F3DArcSinCos( double dSinus, double dCosinus );
00046 
00052 void F3DLimit( double& io_dVal, double in_dMin, double in_dMax );
00053 
00058 void F3DQuatToMat( const CSIBCQuaterniond& in_quat, CSIBCRotMatd& out_mat );
00059 
00064 void F3DMatToQuat( const CSIBCRotMatd& in_mat, CSIBCQuaterniond& out_quat );
00065 
00070 void F3DEulerToQuat( const CSIBCVector3Dd& in_vct, CSIBCQuaterniond& out_quat );
00071 
00076 void F3DEulerToMat( const CSIBCVector3Dd& in_vct, CSIBCRotMatd& out_mat );
00077 
00082 void F3DMatToEuler( const CSIBCRotMatd& in_mat, CSIBCVector3Dd& out_vct );
00083 
00093 void F3DMatToEulerUsingTarget( const CSIBCRotMatd& in_mat, CSIBCVector3Dd& inout_vct );
00094 
00100 void F3DQuatToAxisAngle( const CSIBCQuaterniond& in_quat, CSIBCVector3Dd& out_vctAxis, double& out_dAngle );
00101 
00107 void F3DAxisAngleToQuat( const CSIBCVector3Dd& in_vctAxis, const double& in_dAngle, CSIBCQuaterniond& out_quat );
00108 
00109 // Angle utility functions
00110 
00115 double F3DBoundAngleInMinus2PITo2PI( double in_dDesiredAngle);
00116 
00120 void F3DBoundAngleInZeroToTwoPI( double& in_dAngle );
00121 
00125 void F3DBoundAngleInMinusPIToPI( double& in_dAngle );
00126 
00133 double F3DGetUnboundedAngle( double in_dDesiredAngle, double in_dRefAngle );
00134 
00143 void F3DBoundAnglesInMatrixInMinus2PITo2PI( CSIBCMatrixMNd &io_matMN,   int in_nFirstRow, int in_nLastRow );
00144 
00153 double F3DGetClosestAngle( double in_dAngle, double in_dFirstAngle, double in_dSecondAngle );
00154 
00158 //******************************************************************************
00159 //  Mask Values for m_oRotationInfo. These are used internally by CSIBCRotationd,
00160 //  and do not require documentation.
00161 //******************************************************************************
00162 
00163 #define MASK_ORIGREP                    0x03
00164 #define BITVAL_ORIGREP_QUATERNION       0x00
00165 #define BITVAL_ORIGREP_ROTATION_MATRIX  0x01
00166 #define BITVAL_ORIGREP_EULER_ANGLES     0x02
00167 
00168 #define MASK_ISQUAT_DIRTY               (1 << 2 )   //   00000100
00169 #define MASK_ISMAT_DIRTY                (1 << 3 )   //   00001000
00170 #define MASK_ISANGLES_DIRTY             (1 << 4 )   //   00010000
00171 
00172 // Used to identify which of the three possible representations of a rotation is used.
00173 typedef enum tagE3DROTREPTYPE
00174 {
00175    QUATERNION_REP           = BITVAL_ORIGREP_QUATERNION,
00176    ROTATION_MATRIX_REP      = BITVAL_ORIGREP_ROTATION_MATRIX,
00177    EULER_ANGLES_REP         = BITVAL_ORIGREP_EULER_ANGLES
00178 } E3DRotRepType;
00179 
00180 
00181 //******************************************************************************
00182 // CSIBCRotationd | Implementation of a rotation object.
00183 //******************************************************************************
00184 
00199 class XSICOREEXPORT CSIBCRotationd
00200 {
00201     // Public members
00202     public:
00203         //****************************************
00204         // IMPLEMENTATION
00205         //****************************************
00206 
00211         CSIBCRotationd();
00212 
00217         CSIBCRotationd( const CSIBCQuaterniond& in_quat );
00218 
00223         CSIBCRotationd( const CSIBCRotMatd& in_matRot );
00224 
00230         CSIBCRotationd( const CSIBCVector3Dd& in_vctXYZAngles );
00231 
00238         CSIBCRotationd( double in_dX, double in_dY, double in_dZ );
00239 
00245         CSIBCRotationd( const E3DAxisType in_axis, const double in_dAngle );
00246 
00252         CSIBCRotationd( const CSIBCVector3Dd& in_vctAxis,
00253                           const double in_dAngle );
00254 
00261         CSIBCRotationd( const CSIBCVector3Dd& in_vctFrom,
00262                           const CSIBCVector3Dd& in_vctTo );
00263 
00264         ~CSIBCRotationd();
00265 
00271         CSIBCRotationd& SetIdentity();
00272 
00281         bool IsIdentity();
00282 
00292         bool IsAlmostIdentity(const double& in_rdTolerance = PICO_EPS) const;
00293 
00301         CSIBCQuaterniond& GetQuat( CSIBCQuaterniond& out_quat );
00302 
00311         const CSIBCRotMatd* GetMatrix();
00312 
00321         CSIBCRotMatd& GetMatrix( CSIBCRotMatd& out_matRot );
00322 
00331         CSIBCVector3Dd& GetXYZAngles( CSIBCVector3Dd& out_vctXYZAngles );
00332 
00342         void GetXYZAngles( double& out_dX, double& out_dY, double& out_dZ );
00343 
00351         void GetAxisAngle( CSIBCVector3Dd& out_vctAxis, double& out_dAngle );
00352 
00358         CSIBCRotationd& Set( const CSIBCRotationd& in_rot );
00359 
00365         CSIBCRotationd& Set( const CSIBCQuaterniond& in_quat );
00366 
00372         CSIBCRotationd& Set( const CSIBCRotMatd& in_matRot );
00373 
00379         CSIBCRotationd& Set( const CSIBCVector3Dd& in_vctXYZAngles );
00380 
00388         CSIBCRotationd& Set( double in_dX, double in_dY, double in_dZ );
00389 
00396         CSIBCRotationd& Set( const E3DAxisType in_axis, const double in_dAngle );
00397 
00404         CSIBCRotationd& Set( const CSIBCVector3Dd& in_vctAxis, const double in_dAngle );
00405 
00406 
00419         bool Set( const CSIBCVector3Dd& in_vctFrom, const CSIBCVector3Dd& in_vctTo, int& out_bFlip );
00420 
00429         CSIBCRotationd& Set( const CSIBCVector3Dd& in_vctX, const CSIBCVector3Dd& in_vctY,
00430                         const CSIBCVector3Dd& in_vctZ );
00431 
00445         bool MinAlignToX( const CSIBCVector3Dd& in_vct, int& out_bFlip );
00446 
00460         bool MinAlignToY( const CSIBCVector3Dd& in_vct, int& out_bFlip );
00461 
00475         bool MinAlignToZ( const CSIBCVector3Dd& in_vct, int& out_bFlip );
00476 
00489         bool AlignToX( const CSIBCVector3Dd& in_vct, int& out_bFlip );
00490 
00503         bool AlignToY( const CSIBCVector3Dd& in_vct, int& out_bFlip );
00504 
00517         bool AlignToZ( const CSIBCVector3Dd& in_vct, int& out_bFlip );
00518 
00537         bool AlignAxesToVct( const E3DAxisType in_eFirstAxis,
00538                            const CSIBCVector3Dd& in_vct1,
00539                            const E3DAxisType in_eSecondAxis,
00540                            const CSIBCVector3Dd& in_vct2,
00541                            int& out_bFlip );
00542 
00553         CSIBCRotationd& Mul( CSIBCRotationd& in_rot1, CSIBCRotationd& in_rot2 );
00554 
00564         CSIBCRotationd& Mul( CSIBCRotationd& in_rot );
00565 
00575         CSIBCRotationd& LeftMul( CSIBCRotationd& in_rot );
00576 
00590         CSIBCRotationd& MulUsingEulerAnglesTarget( CSIBCRotationd& in_rot1,
00591                                               CSIBCRotationd& in_rot2,
00592                                               CSIBCVector3Dd& in_oEulerAngles );
00593 
00594 
00609         CSIBCRotationd& MulAndUpdateEulerAngles( CSIBCRotationd& in_rot1,
00610                                             CSIBCRotationd& in_rot2,
00611                                             ULONG in_ulUseRot1OrUseRot2AsTarget);
00612 
00613 
00619         CSIBCRotationd& Invert( CSIBCRotationd& in_rot );
00620 
00625         CSIBCRotationd& Invert();
00626 
00634         CSIBCRotationd& Interpolate( CSIBCRotationd& in_rot1,
00635                                 CSIBCRotationd& in_rot2,
00636                                 const double in_dU );
00637 
00645         CSIBCVector3Dd& RotateVct( const CSIBCVector3Dd& in_vct, CSIBCVector3Dd& out_vct );
00646 
00654         void RotateVct( const CSIBCVector3Dd *in_vcts,
00655                       const LONG in_lNbVcts,
00656                       CSIBCVector3Dd *out_vcts );
00657 
00665         CSIBCVector3Dd& InvRotateVct( const CSIBCVector3Dd& in_vct, CSIBCVector3Dd& out_vct );
00666 
00674         void InvRotateVct( const CSIBCVector3Dd *in_vcts,
00675                          const LONG in_lNbVcts,
00676                          CSIBCVector3Dd *out_vcts );
00677 
00689         friend CSIBCVector3Dd& MapDirSpaceToWorld(
00690                                              CSIBCRotationd& in_rotFrom,
00691                                              const CSIBCVector3Dd& in_vctDir,
00692                                              CSIBCVector3Dd& out_vctDir );
00693 
00703         friend CSIBCVector3Dd& MapDirWorldToSpace(
00704                                              CSIBCRotationd& in_rotTo,
00705                                              const CSIBCVector3Dd& in_vctDir,
00706                                              CSIBCVector3Dd& out_vctDir );
00707 
00720         friend CSIBCVector3Dd& MapDirSpaceToSpace(
00721                                              CSIBCRotationd& in_rotFrom,
00722                                              CSIBCRotationd& in_rotTo,
00723                                              const CSIBCVector3Dd& in_vctDir,
00724                                              CSIBCVector3Dd& out_vctDir );
00725 
00727         // TO BE IMPLEMENTED LATER IF NEEDED... //
00729 
00730         // IMPORTANT: In the following tests, don't forget to compare q1 to q2
00731         //            and q1 to -q2 if quaternion representation is used.
00732 
00733         // AreAlmostEqual       | Verify if two rotations are equal within epsilon.
00735         friend bool AreAlmostEqual( const CSIBCRotationd& in_rot1,
00736                                   const CSIBCRotationd& in_rot2,
00737                                   const double in_dEpsilon = PICO_EPS );
00738 
00739         // operator==           | Verify equality between rotations.
00741         bool operator ==( const CSIBCRotationd& in_rot ) const;
00742 
00743         // operator!=           | Verify non-equality between rotations.
00745         bool operator !=( const CSIBCRotationd& in_rot ) const;
00746 
00747 
00748     // Protected members
00749     protected:
00750 
00751         //****************************************
00752         // IMPLEMENTATION
00753         //****************************************
00754 
00755         // SetMatrixRep       | Set rotation matrix representation as the
00756         //                      original one and raise dirty flags of
00757         //                      other representations.
00758 
00759         void SetQuatRep();
00760 
00761         // SetQuatRep         | Set quaternion representation as the
00762         //                      original one and raise dirty flags of
00763         //                      other representations.
00764         void SetMatrixRep();
00765 
00766         // SetXYZAnglesRep    | Set Euler angles representation as the
00767         //                      original one and raise dirty flags of
00768         //                      other representations.
00769         void SetXYZAnglesRep();
00770 
00771         // UpdateQuat         | Update the quaternion representation
00772         //                      from the original representation.
00773         void UpdateQuat();
00774 
00775         // UpdateMatrix       | Update the rotation matrix representation
00776         //                      from the original representation.
00777         void UpdateMatrix();
00778 
00779         // UpdateXYZAngles    | Update the Euler angles representation
00780         //                      from the original representation.
00781         void UpdateXYZAngles();
00782 
00783         // NextAxis           | Return the next axis of the given one
00784         //                      (in the order X, Y, Z).
00785         int NextAxis( int in_nAxis );
00786 
00787     // Private members
00788     private:
00789 
00790         //****************************************
00791         // ATTRIBUTES
00792         //****************************************
00793         // CSIBCQuaterniond | CSIBCRotationd | m_quat | Quaternion representation
00794         //          of the rotation (unitary quaternion).
00795         // CSIBCRotMatd | CSIBCRotationd | m_matRot | Rotation matrix
00796         //          representation.
00797         // CSIBCVector3Dd | CSIBCRotationd | m_vctXYZAngles | XYZ Euler angles
00798         //          representation.
00799         // double | CSIBCRotationd | m_dAngle | Original rotation angle
00800         //          used in the quaternion representation.
00801         CSIBCQuaterniond m_quat;
00802         CSIBCRotMatd m_matRot;
00803         CSIBCVector3Dd m_vctXYZAngles;
00804         double m_dAngle;
00805 
00806         //***********************************************************************
00807         // m_oRotationInfo comprises formely known m_bQuatDirty, m_bMatDirty
00808         // and m_bAnglesDirty and the enum m_eOrigRep.
00809         // Bit 0 and 1 = used for enum m_eOrigRep of type E3DRotRepType
00810         // E3DRotRepType : QUATERNION_REP       == value 0 ( bit 0 and  1 set to 0 )            //00
00811         //                 ROTATION_MATRIX_REP  == value 1 ( bit 0 set to 1, bit 1 set to 0 )   //01
00812         //                 EULER_ANGLES_REP     == value 2 ( bit 0 set to 0, bit 1 set to 1 )   //10
00813         // Bit 2 = m_bQuatDirty
00814         // Bit 3 = m_bMatDirty
00815         // Bit 4 = m_bAnglesDirty
00816         // Bit 5 to 7 = unused
00817 
00818         unsigned char m_oRotationInfo;
00819 
00820          void _SetQuatDirty(bool in_bIsDirty );
00821          void _SetMatDirty(bool in_bIsDirty );
00822          void _SetAnglesDirty(bool in_bIsDirty );
00823          void _SetOrigRep(E3DRotRepType in_eOrigRep );
00824 
00825          bool _IsQuatDirty () const;
00826          bool _IsMatDirty () const;
00827          bool _AreAnglesDirty () const;
00828          E3DRotRepType _GetOrigRep() const;
00829 
00830         // Disable copy constructor and assignment operator:
00831         CSIBCRotationd( const CSIBCRotationd& in_rot );
00832         CSIBCRotationd& operator =( const CSIBCRotationd& in_rot );
00833 };
00834 
00835 #endif