00001
00002
00003
00004
00005 #ifndef COURNIA_QUATERNION_H
00006 #define COURNIA_QUATERNION_H 1
00007
00008 #include <iostream>
00009 #include <cmath>
00010 #include "vector.h"
00011 #include "matrix.h"
00012
00013 namespace math {
00014 class quaternion;
00015 }
00016
00017 std::ostream& operator<< ( std::ostream& o, const math::quaternion& q );
00018
00020
00025 class math::quaternion {
00026 private:
00027 math::vector3 m_v;
00028 real_t m_w;
00029
00031
00034 friend std::ostream& operator<< ( std::ostream& o, const math::quaternion& vec );
00035
00036 public:
00038
00041 quaternion( void ): m_w( 1.0 )
00042 { }
00043
00045
00049 quaternion( const math::vector3& v_, real_t w_ ): m_v( v_ ), m_w( w_ )
00050 { }
00051
00053
00059 quaternion( real_t x_, real_t y_, real_t z_, real_t w_ ):
00060 m_v( x_, y_, z_ ), m_w( w_ )
00061 { }
00062
00064 quaternion( const math::quaternion& p ): m_v( p.m_v ), m_w( p.m_w )
00065 { }
00066
00068 inline math::quaternion& operator= ( const math::quaternion& p ) {
00069 m_v = p.m_v;
00070 m_w = p.m_w;
00071 return *this;
00072 }
00073
00075 inline real_t w( void ) const {
00076 return m_w;
00077 }
00078
00080 inline real_t x( void ) const {
00081 return m_v.x( );
00082 }
00083
00085 inline real_t y( void ) const {
00086 return m_v.y( );
00087 }
00088
00090 inline real_t z( void ) const {
00091 return m_v.z( );
00092 }
00093
00095
00099 inline math::vector3 v( void ) const {
00100 return m_v;
00101 }
00102
00104
00108 inline math::vector3 vec( void ) const {
00109 return m_v;
00110 }
00111
00113
00116 inline real_t scalar( void ) const {
00117 return m_w;
00118 }
00119
00121
00127 inline void set( real_t x_, real_t y_, real_t z_, real_t w_ ) {
00128 m_v.set( x_, y_, z_ );
00129 m_w = w_;
00130 }
00131
00133
00137 inline void
00138 set( const math::vector3& v_, real_t w_ ) {
00139 m_v = v_;
00140 m_w = w_;
00141 }
00142
00144
00149 inline math::quaternion conjugate( void ) const {
00150 return math::quaternion( -1.0 * m_v, m_w );
00151 }
00152
00154
00159 inline math::quaternion operator! ( void ) const {
00160 return math::quaternion( -1.0 * m_v, m_w );
00161 }
00162
00164
00168 inline double
00169 magnitude( void ) const {
00170 return sqrt( (double)(m_w * m_w + math::dot( m_v, m_v )) );
00171 }
00172
00174
00177 inline void
00178 normalize( void ) {
00179 double mag = magnitude( );
00180 m_w /= mag;
00181 m_v.x( m_v.x( ) / mag );
00182 m_v.y( m_v.y( ) / mag );
00183 m_v.z( m_v.z( ) / mag );
00184 }
00185
00187
00191 void
00192 set_identity( void ) {
00193 m_w = 1.0;
00194 m_v.set( 0.0, 0.0, 0.0 );
00195 }
00196
00198
00201 math::matrix4
00202 get_rotation_matrix( void ) const;
00203
00205
00208 void
00209 get_rotation_matrix( math::matrix4& m ) const;
00210
00212
00216 math::matrix4
00217 get_transposed_rotation_matrix( void ) const;
00218
00220
00224 void
00225 get_transposed_rotation_matrix( math::matrix4& m ) const;
00226
00228 math::quaternion
00229 operator* ( const math::quaternion& rhs ) const;
00230
00232
00236 math::vector3
00237 operator* ( const math::vector3& rhs ) const;
00238
00240
00248 void
00249 from_angle_axis( real_t radians, const math::vector3& axis );
00250
00252
00257 void
00258 get_angle_axis( real_t& radians, math::vector3& axis ) const;
00259
00261
00265 static math::quaternion
00266 slerp( real_t percent, const math::quaternion& qa,
00267 const math::quaternion& qb );
00268
00269
00271
00275 static const math::quaternion IDENTITY;
00276 };
00277
00278 #endif