00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #ifndef COURNIA_QUATERNION_H
00028 #define COURNIA_QUATERNION_H 1
00029
00030 #include <iostream>
00031 #include <cmath>
00032 #include "fob/vector.h"
00033 #include "fob/matrix.h"
00034
00035 namespace math {
00036 class quaternion;
00037 std::ostream& operator<< ( std::ostream& o, const math::quaternion& vec );
00038 }
00039
00041
00046 class math::quaternion {
00047 private:
00048 math::vector3 m_v;
00049 real_t m_w;
00050
00052
00055 friend std::ostream& math::operator<< ( std::ostream& o, const math::quaternion& vec );
00056
00057 public:
00059
00062 quaternion( void ): m_w( 1.0 )
00063 { }
00064
00066
00070 quaternion( const math::vector3& v_, real_t w_ ): m_v( v_ ), m_w( w_ )
00071 { }
00072
00074
00080 quaternion( real_t x_, real_t y_, real_t z_, real_t w_ ):
00081 m_v( x_, y_, z_ ), m_w( w_ )
00082 { }
00083
00085 quaternion( const math::quaternion& p ): m_v( p.m_v ), m_w( p.m_w )
00086 { }
00087
00089 inline math::quaternion& operator= ( const math::quaternion& p ) {
00090 m_v = p.m_v;
00091 m_w = p.m_w;
00092 return *this;
00093 }
00094
00096 inline real_t w( void ) const {
00097 return m_w;
00098 }
00099
00101 inline real_t x( void ) const {
00102 return m_v.x( );
00103 }
00104
00106 inline real_t y( void ) const {
00107 return m_v.y( );
00108 }
00109
00111 inline real_t z( void ) const {
00112 return m_v.z( );
00113 }
00114
00116
00120 inline math::vector3 v( void ) const {
00121 return m_v;
00122 }
00123
00125
00129 inline math::vector3 vec( void ) const {
00130 return m_v;
00131 }
00132
00134
00137 inline real_t scalar( void ) const {
00138 return m_w;
00139 }
00140
00142
00148 inline void set( real_t x_, real_t y_, real_t z_, real_t w_ ) {
00149 m_v.set( x_, y_, z_ );
00150 m_w = w_;
00151 }
00152
00154
00158 inline void
00159 set( const math::vector3& v_, real_t w_ ) {
00160 m_v = v_;
00161 m_w = w_;
00162 }
00163
00165
00170 inline math::quaternion conjugate( void ) const {
00171 return math::quaternion( -1.0 * m_v, m_w );
00172 }
00173
00175
00180 inline math::quaternion operator! ( void ) const {
00181 return math::quaternion( -1.0 * m_v, m_w );
00182 }
00183
00185
00189 inline double
00190 magnitude( void ) const {
00191 return sqrt( (double)(m_w * m_w + math::dot( m_v, m_v )) );
00192 }
00193
00195
00198 inline void
00199 normalize( void ) {
00200 double mag = magnitude( );
00201 m_w /= mag;
00202 m_v.x( m_v.x( ) / mag );
00203 m_v.y( m_v.y( ) / mag );
00204 m_v.z( m_v.z( ) / mag );
00205 }
00206
00208
00212 void
00213 set_identity( void ) {
00214 m_w = 1.0;
00215 m_v.set( 0.0, 0.0, 0.0 );
00216 }
00217
00219
00222 math::matrix4
00223 get_rotation_matrix( void ) const;
00224
00226
00229 void
00230 get_rotation_matrix( math::matrix4& m ) const;
00231
00233
00237 math::matrix4
00238 get_transposed_rotation_matrix( void ) const;
00239
00241
00245 void
00246 get_transposed_rotation_matrix( math::matrix4& m ) const;
00247
00249 math::quaternion
00250 operator* ( const math::quaternion& rhs ) const;
00251
00253
00257 math::vector3
00258 operator* ( const math::vector3& rhs ) const;
00259
00261
00269 void
00270 from_angle_axis( real_t radians, const math::vector3& axis );
00271
00273
00278 void
00279 get_angle_axis( real_t& radians, math::vector3& axis ) const;
00280
00282
00287 void
00288 from_angles( real_t x_rad, real_t y_rad, real_t z_rad );
00289
00291
00294 void
00295 from_matrix3( const real_t *mat );
00296
00298
00301 void
00302 from_matrix4( const real_t *mat );
00303
00305
00311 static math::quaternion
00312 slerp( real_t percent, const math::quaternion& qa,
00313 math::quaternion qb );
00314
00315
00317
00321 static const math::quaternion IDENTITY;
00322 };
00323
00324 #endif