41 #ifndef GLS_QUATERNION_H 
   42 #define GLS_QUATERNION_H 
   50 class GlsMatrixAffine;
 
  111         Type angle2, 
const Vector& axis2,
 
  112         Type angle3, 
const Vector& axis3 )
 
  170     inline const Type* 
Data()
 const 
  184         return _v[ 0 ] == q._v[ 0 ] && _v[ 1 ] == q._v[ 1 ] && _v[ 2 ] == q._v[ 2 ] && _v[ 3 ] == q._v[ 3 ];
 
  196         return _v[ 0 ] != q._v[ 0 ] || _v[ 1 ] != q._v[ 1 ] || _v[ 2 ] != q._v[ 2 ] || _v[ 3 ] != q._v[ 3 ];
 
  208         if( _v[ 0 ] < q._v[ 0 ] )
 
  210         else if( _v[ 0 ] > q._v[ 0 ] )
 
  212         else if( _v[ 1 ] < q._v[ 1 ] )
 
  214         else if( _v[ 1 ] > q._v[ 1 ] )
 
  216         else if( _v[ 2 ] < q._v[ 2 ] )
 
  218         else if( _v[ 2 ] > q._v[ 2 ] )
 
  221             return ( _v[ 3 ] < q._v[ 3 ] );
 
  233         return GlsQuaternion( _v[ 0 ] * s, _v[ 1 ] * s, _v[ 2 ] * s, _v[ 3 ] * s );
 
  261         return GlsQuaternion( q._v[ 3 ] * _v[ 0 ] + q._v[ 0 ] * _v[ 3 ] + q._v[ 1 ] * _v[ 2 ] - q._v[ 2 ] * _v[ 1 ],
 
  262             q._v[ 3 ] * _v[ 1 ] - q._v[ 0 ] * _v[ 2 ] + q._v[ 1 ] * _v[ 3 ] + q._v[ 2 ] * _v[ 0 ],
 
  263             q._v[ 3 ] * _v[ 2 ] + q._v[ 0 ] * _v[ 1 ] - q._v[ 1 ] * _v[ 0 ] + q._v[ 2 ] * _v[ 3 ],
 
  264             q._v[ 3 ] * _v[ 3 ] - q._v[ 0 ] * _v[ 0 ] - q._v[ 1 ] * _v[ 1 ] - q._v[ 2 ] * _v[ 2 ] );
 
  276         Type x  = q._v[ 3 ] * _v[ 0 ] + q._v[ 0 ] * _v[ 3 ] + q._v[ 1 ] * _v[ 2 ] - q._v[ 2 ] * _v[ 1 ];
 
  277         Type y  = q._v[ 3 ] * _v[ 1 ] - q._v[ 0 ] * _v[ 2 ] + q._v[ 1 ] * _v[ 3 ] + q._v[ 2 ] * _v[ 0 ];
 
  278         Type z  = q._v[ 3 ] * _v[ 2 ] + q._v[ 0 ] * _v[ 1 ] - q._v[ 1 ] * _v[ 0 ] + q._v[ 2 ] * _v[ 3 ];
 
  279         _v[ 3 ] = q._v[ 3 ] * _v[ 3 ] - q._v[ 0 ] * _v[ 0 ] - q._v[ 1 ] * _v[ 1 ] - q._v[ 2 ] * _v[ 2 ];
 
  298         return GlsQuaternion( _v[ 0 ] * div, _v[ 1 ] * div, _v[ 2 ] * div, _v[ 3 ] * div );
 
  327         return ( ( *
this ) * q.
Inverse() );
 
  339         ( *this ) = ( *this ) * q.
Inverse();
 
  352         return GlsQuaternion( _v[ 0 ] + q._v[ 0 ], _v[ 1 ] + q._v[ 1 ],
 
  353             _v[ 2 ] + q._v[ 2 ], _v[ 3 ] + q._v[ 3 ] );
 
  365         _v[ 0 ] += q._v[ 0 ];
 
  366         _v[ 1 ] += q._v[ 1 ];
 
  367         _v[ 2 ] += q._v[ 2 ];
 
  368         _v[ 3 ] += q._v[ 3 ];
 
  381         return GlsQuaternion( _v[ 0 ] - q._v[ 0 ], _v[ 1 ] - q._v[ 1 ],
 
  382             _v[ 2 ] - q._v[ 2 ], _v[ 3 ] - q._v[ 3 ] );
 
  394         _v[ 0 ] -= q._v[ 0 ];
 
  395         _v[ 1 ] -= q._v[ 1 ];
 
  396         _v[ 2 ] -= q._v[ 2 ];
 
  397         _v[ 3 ] -= q._v[ 3 ];
 
  405         return GlsQuaternion( -_v[ 0 ], -_v[ 1 ], -_v[ 2 ], -_v[ 3 ] );
 
  416         return sqrt( _v[ 0 ] * _v[ 0 ] + _v[ 1 ] * _v[ 1 ] + _v[ 2 ] * _v[ 2 ] + _v[ 3 ] * _v[ 3 ] );
 
  427         return _v[ 0 ] * _v[ 0 ] + _v[ 1 ] * _v[ 1 ] + _v[ 2 ] * _v[ 2 ] + _v[ 3 ] * _v[ 3 ];
 
  438         return GlsQuaternion( -_v[ 0 ], -_v[ 1 ], -_v[ 2 ], _v[ 3 ] );
 
  461         return ( ( _v[ 0 ] * q._v[ 0 ] ) + ( _v[ 1 ] * q._v[ 1 ] ) + ( _v[ 2 ] * q._v[ 2 ] ) + ( _v[ 3 ] * q._v[ 3 ] ) );
 
  483     inline void Set( Type x, Type y, Type z, Type w )
 
  500         Type half_angle     = angle * (Type)0.5;
 
  501         Type sin_half_angle = sin( half_angle );
 
  503         _v[ 0 ] = sin_half_angle * axis.x;
 
  504         _v[ 1 ] = sin_half_angle * axis.y;
 
  505         _v[ 2 ] = sin_half_angle * axis.z;
 
  506         _v[ 3 ] = cos( half_angle );
 
  521         Type angle2, 
const Vector& axis2,
 
  522         Type angle3, 
const Vector& axis3 )
 
  528         *
this = q1 * q2 * *
this;
 
  544         Type xOver2 = angleX * (Type)0.5;
 
  545         Type yOver2 = angleY * (Type)0.5;
 
  546         Type zOver2 = angleZ * (Type)0.5;
 
  549         qx._v[ 0 ] = sin( xOver2 );
 
  550         qx._v[ 1 ] = (Type)0.0;
 
  551         qx._v[ 2 ] = (Type)0.0;
 
  552         qx._v[ 3 ] = cos( xOver2 );
 
  555         qy._v[ 0 ] = (Type)0.0;
 
  556         qy._v[ 1 ] = sin( yOver2 );
 
  557         qy._v[ 2 ] = (Type)0.0;
 
  558         qy._v[ 3 ] = cos( yOver2 );
 
  561         qz._v[ 0 ] = (Type)0.0;
 
  562         qz._v[ 1 ] = (Type)0.0;
 
  563         qz._v[ 2 ] = sin( zOver2 );
 
  564         qz._v[ 3 ] = cos( zOver2 );
 
  567         *
this = qx * qy * qz;
 
  584         if( IsVeryCloseToZero( cosangle - 1 ) )
 
  591         else if( IsVeryCloseToZero( cosangle + 1.0 ) )
 
  596             if( fabs( from.x ) < fabs( from.y ) )
 
  597                 if( fabs( from.x ) < fabs( from.z ) )
 
  598                     tmp = 
Vector( 1.0, 0.0, 0.0 ); 
 
  600                     tmp = 
Vector( 0.0, 0.0, 1.0 );
 
  601             else if( fabs( from.y ) < fabs( from.z ) )
 
  602                 tmp = 
Vector( 0.0, 1.0, 0.0 );
 
  604                 tmp = 
Vector( 0.0, 0.0, 1.0 );
 
  621             Type angle = acos( cosangle );
 
  639         int nxt[ 3 ] = { 1, 2, 0 };
 
  641         tr = mat[ 0 * 4 + 0 ] + mat[ 1 * 4 + 1 ] + mat[ 2 * 4 + 2 ];
 
  646             s       = (Type)sqrt( tr + 1.0 );
 
  649             _v[ 0 ] = ( mat[ 1 * 4 + 2 ] - mat[ 2 * 4 + 1 ] ) * s;
 
  650             _v[ 1 ] = ( mat[ 2 * 4 + 0 ] - mat[ 0 * 4 + 2 ] ) * s;
 
  651             _v[ 2 ] = ( mat[ 0 * 4 + 1 ] - mat[ 1 * 4 + 0 ] ) * s;
 
  657             if( mat[ 1 * 4 + 1 ] > mat[ 0 * 4 + 0 ] )
 
  659             if( mat[ 2 * 4 + 2 ] > mat[ i * 4 + i ] )
 
  664             s = (Type)sqrt( ( mat[ i * 4 + i ] - ( mat[ j * 4 + j ] + mat[ k * 4 + k ] ) ) + 1.0 );
 
  671             tq[ 3 ] = ( mat[ j * 4 + k ] - mat[ k * 4 + j ] ) * s;
 
  672             tq[ j ] = ( mat[ i * 4 + j ] + mat[ j * 4 + i ] ) * s;
 
  673             tq[ k ] = ( mat[ i * 4 + k ] + mat[ k * 4 + i ] ) * s;
 
  687         return atan2( 2 * ( _v[ 1 ] * _v[ 2 ] + _v[ 3 ] * _v[ 0 ] ), _v[ 3 ] * _v[ 3 ] - _v[ 0 ] * _v[ 0 ] - _v[ 1 ] * _v[ 1 ] + _v[ 2 ] * _v[ 2 ] );
 
  695         Type tmp = -2 * ( _v[ 0 ] * _v[ 2 ] - _v[ 3 ] * _v[ 1 ] );
 
  701         else if( tmp < -1.0 )
 
  713         return atan2( 2 * ( _v[ 0 ] * _v[ 1 ] + _v[ 3 ] * _v[ 2 ] ), _v[ 3 ] * _v[ 3 ] + _v[ 0 ] * _v[ 0 ] - _v[ 1 ] * _v[ 1 ] - _v[ 2 ] * _v[ 2 ] );
 
  733         if( abs( _v[ 3 ] ) > (Type)1.0 )
 
  735         if( fabs( (
double)_v[ 3 ] ) > 1.0 )
 
  742         Type rad = acos( _v[ 3 ] ) * (Type)2.0;
 
  752             Type sin_half_angle = sin( rad * (Type)0.5 );
 
  753             if( sin_half_angle >= (Type)0.0001 ) 
 
  755                 Type sin_half_angle_inv = Type( 1.0 ) / sin_half_angle;
 
  756                 axis->x                 = float( _v[ 0 ] * sin_half_angle_inv );
 
  757                 axis->y                 = float( _v[ 1 ] * sin_half_angle_inv );
 
  758                 axis->z                 = float( _v[ 2 ] * sin_half_angle_inv );
 
  768                 axis->x = (float)1.0;
 
  769                 axis->y = (float)0.0;
 
  770                 axis->z = (float)0.0;
 
  780         Type wx, wy, wz, xx, yy, yz, xy, xz, zz, x2, y2, z2;
 
  783         x2 = _v[ 0 ] + _v[ 0 ];
 
  784         y2 = _v[ 1 ] + _v[ 1 ];
 
  785         z2 = _v[ 2 ] + _v[ 2 ];
 
  799         mat[ 0 ][ 0 ] = 1.0f - ( yy + zz );
 
  800         mat[ 0 ][ 1 ] = xy - wz;
 
  801         mat[ 0 ][ 2 ] = xz + wy;
 
  802         mat[ 0 ][ 3 ] = 0.0f;
 
  804         mat[ 1 ][ 0 ] = xy + wz;
 
  805         mat[ 1 ][ 1 ] = 1.0f - ( xx + zz );
 
  806         mat[ 1 ][ 2 ] = yz - wx;
 
  807         mat[ 1 ][ 3 ] = 0.0f;
 
  809         mat[ 2 ][ 0 ] = xz - wy;
 
  810         mat[ 2 ][ 1 ] = yz + wx;
 
  811         mat[ 2 ][ 2 ] = 1.0f - ( xx + yy );
 
  812         mat[ 2 ][ 3 ] = 0.0f;
 
  838         if( adjustSign && ( cosom < (Type)0.0 ) )
 
  841             q._v[ 0 ] = -to._v[ 0 ]; 
 
  842             q._v[ 1 ] = -to._v[ 1 ];
 
  843             q._v[ 2 ] = -to._v[ 2 ];
 
  844             q._v[ 3 ] = -to._v[ 3 ];
 
  853         if( ( (Type)1.0 - cosom ) > (Type)0.0001 ) 
 
  857             omega = acos( cosom ); 
 
  858             sinom = sin( omega );
 
  859             sclp  = sin( ( (Type)1.0 - t ) * omega ) / sinom;
 
  860             sclq  = sin( t * omega ) / sinom;
 
  865             sclp = (Type)1.0 - t;
 
  869         _v[ 0 ] = sclp * p._v[ 0 ] + sclq * q._v[ 0 ];
 
  870         _v[ 1 ] = sclp * p._v[ 1 ] + sclq * q._v[ 1 ];
 
  871         _v[ 2 ] = sclp * p._v[ 2 ] + sclq * q._v[ 2 ];
 
  872         _v[ 3 ] = sclp * p._v[ 3 ] + sclq * q._v[ 3 ];
 
  879     static bool IsVeryCloseToZero( 
double value ) { 
return fabs( value ) < 0.0001; }
 
  882 typedef GlsQuaternion<float>  GlsQuaternionF;
 
  883 typedef GlsQuaternion<double> GlsQuaternionD;
 
  886 inline std::ostream& operator<<( std::ostream& outstr, const GlsQuaternion<Type>& quat )
 
  888     outstr.precision( MaxDigits10<Type>::value );
 
  891     outstr << quat.Data()[ 0 ] << 
" ";
 
  893     outstr << quat.Data()[ 1 ] << 
" ";
 
  895     outstr << quat.Data()[ 2 ] << 
" ";
 
  897     outstr << quat.Data()[ 3 ];
 
  903 inline std::istream& operator>>( std::istream& instr, GlsQuaternion<Type>& quat )
 
  905     instr >> quat.Data()[ 0 ] >> quat.Data()[ 1 ] >> quat.Data()[ 2 ] >> quat.Data()[ 3 ];
 
const Type * Data() const 
Definition: gls_quaternion.h:170
GlsQuaternion(Type angle1, const Vector &axis1, Type angle2, const Vector &axis2, Type angle3, const Vector &axis3)
Definition: gls_quaternion.h:110
GlsQuaternion(Type angle, const Vector &axis)
Definition: gls_quaternion.h:94
const GlsQuaternion operator+(const GlsQuaternion &q) const 
Definition: gls_quaternion.h:350
const GlsQuaternion operator-() const 
Definition: gls_quaternion.h:403
bool operator!=(const GlsQuaternion &q) const 
Definition: gls_quaternion.h:194
Vector GetEulerAngles()
Definition: gls_quaternion.h:719
void Normalize(void)
Definition: vertex.h:308
float DotProduct(const VertexNoColor &w) const 
Definition: vertex.h:357
GlsQuaternion & operator-=(const GlsQuaternion &q)
Definition: gls_quaternion.h:392
bool operator<(const GlsQuaternion &q) const 
Definition: gls_quaternion.h:206
void SetFromVectors(const Vector &to, const Vector &from)
Definition: gls_quaternion.h:579
const GlsQuaternion Inverse() const 
Definition: gls_quaternion.h:447
Type GetRoll(void) const 
Definition: gls_quaternion.h:685
Type DotProduct(const GlsQuaternion &q) const 
Definition: gls_quaternion.h:459
void SetFromAngleAxis(Type angle, const Vector &axis)
Definition: gls_quaternion.h:498
void GetAngleAxis(Type *angle, Vector *axis)
Definition: gls_quaternion.h:729
Type Magnitude() const 
Definition: gls_quaternion.h:414
GlsQuaternion(const Vector &anglesVec)
Definition: gls_quaternion.h:137
void SetFromAngleAxis(Type angle1, const Vector &axis1, Type angle2, const Vector &axis2, Type angle3, const Vector &axis3)
Definition: gls_quaternion.h:520
const GlsQuaternion operator-(const GlsQuaternion &q) const 
Definition: gls_quaternion.h:379
void SetFromEulerAngles(Type angleX, Type angleY, Type angleZ)
Definition: gls_quaternion.h:539
GlsQuaternion(const GlsMatrixAffine< Type > &matrix)
Definition: gls_quaternion.h:148
VertexNoColor Vector
Definition: gls_font_base.h:66
GlsQuaternion(Type angleX, Type angleY, Type angleZ)
Definition: gls_quaternion.h:125
GlsQuaternion Conjugate() const 
Definition: gls_quaternion.h:436
GlsQuaternion & operator+=(const GlsQuaternion &q)
Definition: gls_quaternion.h:363
GlsQuaternion & operator/=(Type s)
Definition: gls_quaternion.h:308
The disti::Vertex class. A class for manipulating 3D vertices. 
VertexNoColor CrossProduct(const VertexNoColor &w) const 
Definition: vertex.h:346
Type GetPitch(void) const 
Definition: gls_quaternion.h:693
GlsQuaternion()
Definition: gls_quaternion.h:62
Type MagnitudeSquared() const 
Definition: gls_quaternion.h:425
GlsQuaternion(Type x, Type y, Type z, Type w)
Definition: gls_quaternion.h:79
void Set(Type x, Type y, Type z, Type w)
Definition: gls_quaternion.h:483
const GlsQuaternion operator*(Type s) const 
Definition: gls_quaternion.h:231
GlsQuaternion & operator/=(const GlsQuaternion &q)
Definition: gls_quaternion.h:337
Type * Data()
Definition: gls_quaternion.h:159
Type GetYaw(void) const 
Definition: gls_quaternion.h:711
GlsQuaternion & operator*=(const GlsQuaternion &q)
Definition: gls_quaternion.h:274
const GlsQuaternion operator*(const GlsQuaternion &q) const 
Definition: gls_quaternion.h:259
Definition: gls_quaternion.h:54
const GlsQuaternion operator/(const GlsQuaternion &q) const 
Definition: gls_quaternion.h:325
bool operator==(const GlsQuaternion &q) const 
Definition: gls_quaternion.h:182
float Magnitude() const 
Definition: vertex.h:327
void SetFromSlerp(float t, const GlsQuaternion &from, const GlsQuaternion &to, bool adjustSign=true)
Definition: gls_quaternion.h:829
GlsMatrixAffine< Type > GetRotationMatrix()
Definition: gls_quaternion.h:778
Macros and helper code to determine what subset of C++11/14/17 is available. 
GlsQuaternion & operator*=(Type s)
Definition: gls_quaternion.h:243
void SetFromRotationMatrix(const GlsMatrixAffine< Type > &matrix)
Definition: gls_quaternion.h:632
void Normalize()
Definition: gls_quaternion.h:469
Definition: bmpimage.h:46
GlsQuaternion operator/(Type s) const 
Definition: gls_quaternion.h:295
Definition: gls_matrix_affine.h:60