41 #ifndef GLS_QUATERNION_H
42 #define GLS_QUATERNION_H
49 class GlsMatrixAffine;
110 Type angle2,
const Vector& axis2,
111 Type angle3,
const Vector& axis3 )
169 inline const Type*
Data()
const
183 return _v[ 0 ] == q._v[ 0 ] && _v[ 1 ] == q._v[ 1 ] && _v[ 2 ] == q._v[ 2 ] && _v[ 3 ] == q._v[ 3 ];
195 return _v[ 0 ] != q._v[ 0 ] || _v[ 1 ] != q._v[ 1 ] || _v[ 2 ] != q._v[ 2 ] || _v[ 3 ] != q._v[ 3 ];
207 if( _v[ 0 ] < q._v[ 0 ] )
209 else if( _v[ 0 ] > q._v[ 0 ] )
211 else if( _v[ 1 ] < q._v[ 1 ] )
213 else if( _v[ 1 ] > q._v[ 1 ] )
215 else if( _v[ 2 ] < q._v[ 2 ] )
217 else if( _v[ 2 ] > q._v[ 2 ] )
220 return ( _v[ 3 ] < q._v[ 3 ] );
232 return GlsQuaternion( _v[ 0 ] * s, _v[ 1 ] * s, _v[ 2 ] * s, _v[ 3 ] * s );
260 return GlsQuaternion( q._v[ 3 ] * _v[ 0 ] + q._v[ 0 ] * _v[ 3 ] + q._v[ 1 ] * _v[ 2 ] - q._v[ 2 ] * _v[ 1 ],
261 q._v[ 3 ] * _v[ 1 ] - q._v[ 0 ] * _v[ 2 ] + q._v[ 1 ] * _v[ 3 ] + q._v[ 2 ] * _v[ 0 ],
262 q._v[ 3 ] * _v[ 2 ] + q._v[ 0 ] * _v[ 1 ] - q._v[ 1 ] * _v[ 0 ] + q._v[ 2 ] * _v[ 3 ],
263 q._v[ 3 ] * _v[ 3 ] - q._v[ 0 ] * _v[ 0 ] - q._v[ 1 ] * _v[ 1 ] - q._v[ 2 ] * _v[ 2 ] );
275 Type x = q._v[ 3 ] * _v[ 0 ] + q._v[ 0 ] * _v[ 3 ] + q._v[ 1 ] * _v[ 2 ] - q._v[ 2 ] * _v[ 1 ];
276 Type y = q._v[ 3 ] * _v[ 1 ] - q._v[ 0 ] * _v[ 2 ] + q._v[ 1 ] * _v[ 3 ] + q._v[ 2 ] * _v[ 0 ];
277 Type z = q._v[ 3 ] * _v[ 2 ] + q._v[ 0 ] * _v[ 1 ] - q._v[ 1 ] * _v[ 0 ] + q._v[ 2 ] * _v[ 3 ];
278 _v[ 3 ] = q._v[ 3 ] * _v[ 3 ] - q._v[ 0 ] * _v[ 0 ] - q._v[ 1 ] * _v[ 1 ] - q._v[ 2 ] * _v[ 2 ];
297 return GlsQuaternion( _v[ 0 ] * div, _v[ 1 ] * div, _v[ 2 ] * div, _v[ 3 ] * div );
326 return ( ( *
this ) * q.
Inverse() );
338 ( *this ) = ( *this ) * q.
Inverse();
351 return GlsQuaternion( _v[ 0 ] + q._v[ 0 ], _v[ 1 ] + q._v[ 1 ],
352 _v[ 2 ] + q._v[ 2 ], _v[ 3 ] + q._v[ 3 ] );
364 _v[ 0 ] += q._v[ 0 ];
365 _v[ 1 ] += q._v[ 1 ];
366 _v[ 2 ] += q._v[ 2 ];
367 _v[ 3 ] += q._v[ 3 ];
380 return GlsQuaternion( _v[ 0 ] - q._v[ 0 ], _v[ 1 ] - q._v[ 1 ],
381 _v[ 2 ] - q._v[ 2 ], _v[ 3 ] - q._v[ 3 ] );
393 _v[ 0 ] -= q._v[ 0 ];
394 _v[ 1 ] -= q._v[ 1 ];
395 _v[ 2 ] -= q._v[ 2 ];
396 _v[ 3 ] -= q._v[ 3 ];
404 return GlsQuaternion( -_v[ 0 ], -_v[ 1 ], -_v[ 2 ], -_v[ 3 ] );
415 return sqrt( _v[ 0 ] * _v[ 0 ] + _v[ 1 ] * _v[ 1 ] + _v[ 2 ] * _v[ 2 ] + _v[ 3 ] * _v[ 3 ] );
426 return _v[ 0 ] * _v[ 0 ] + _v[ 1 ] * _v[ 1 ] + _v[ 2 ] * _v[ 2 ] + _v[ 3 ] * _v[ 3 ];
437 return GlsQuaternion( -_v[ 0 ], -_v[ 1 ], -_v[ 2 ], _v[ 3 ] );
460 return ( ( _v[ 0 ] * q._v[ 0 ] ) + ( _v[ 1 ] * q._v[ 1 ] ) + ( _v[ 2 ] * q._v[ 2 ] ) + ( _v[ 3 ] * q._v[ 3 ] ) );
482 inline void Set( Type x, Type y, Type z, Type w )
499 Type half_angle = angle * (Type)0.5;
500 Type sin_half_angle = sin( half_angle );
502 _v[ 0 ] = sin_half_angle * axis.x;
503 _v[ 1 ] = sin_half_angle * axis.y;
504 _v[ 2 ] = sin_half_angle * axis.z;
505 _v[ 3 ] = cos( half_angle );
520 Type angle2,
const Vector& axis2,
521 Type angle3,
const Vector& axis3 )
527 *
this = q1 * q2 * *
this;
543 Type xOver2 = angleX * (Type)0.5;
544 Type yOver2 = angleY * (Type)0.5;
545 Type zOver2 = angleZ * (Type)0.5;
548 qx._v[ 0 ] = sin( xOver2 );
549 qx._v[ 1 ] = (Type)0.0;
550 qx._v[ 2 ] = (Type)0.0;
551 qx._v[ 3 ] = cos( xOver2 );
554 qy._v[ 0 ] = (Type)0.0;
555 qy._v[ 1 ] = sin( yOver2 );
556 qy._v[ 2 ] = (Type)0.0;
557 qy._v[ 3 ] = cos( yOver2 );
560 qz._v[ 0 ] = (Type)0.0;
561 qz._v[ 1 ] = (Type)0.0;
562 qz._v[ 2 ] = sin( zOver2 );
563 qz._v[ 3 ] = cos( zOver2 );
566 *
this = qx * qy * qz;
583 if( IsVeryCloseToZero( cosangle - 1 ) )
590 else if( IsVeryCloseToZero( cosangle + 1.0 ) )
595 if( fabs( from.x ) < fabs( from.y ) )
596 if( fabs( from.x ) < fabs( from.z ) )
597 tmp =
Vector( 1.0, 0.0, 0.0 );
599 tmp =
Vector( 0.0, 0.0, 1.0 );
600 else if( fabs( from.y ) < fabs( from.z ) )
601 tmp =
Vector( 0.0, 1.0, 0.0 );
603 tmp =
Vector( 0.0, 0.0, 1.0 );
620 Type angle = acos( cosangle );
638 int nxt[ 3 ] = { 1, 2, 0 };
640 tr = mat[ 0 * 4 + 0 ] + mat[ 1 * 4 + 1 ] + mat[ 2 * 4 + 2 ];
645 s = (Type)sqrt( tr + 1.0 );
648 _v[ 0 ] = ( mat[ 1 * 4 + 2 ] - mat[ 2 * 4 + 1 ] ) * s;
649 _v[ 1 ] = ( mat[ 2 * 4 + 0 ] - mat[ 0 * 4 + 2 ] ) * s;
650 _v[ 2 ] = ( mat[ 0 * 4 + 1 ] - mat[ 1 * 4 + 0 ] ) * s;
656 if( mat[ 1 * 4 + 1 ] > mat[ 0 * 4 + 0 ] )
658 if( mat[ 2 * 4 + 2 ] > mat[ i * 4 + i ] )
663 s = (Type)sqrt( ( mat[ i * 4 + i ] - ( mat[ j * 4 + j ] + mat[ k * 4 + k ] ) ) + 1.0 );
670 tq[ 3 ] = ( mat[ j * 4 + k ] - mat[ k * 4 + j ] ) * s;
671 tq[ j ] = ( mat[ i * 4 + j ] + mat[ j * 4 + i ] ) * s;
672 tq[ k ] = ( mat[ i * 4 + k ] + mat[ k * 4 + i ] ) * s;
686 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 ] );
694 Type tmp = -2 * ( _v[ 0 ] * _v[ 2 ] - _v[ 3 ] * _v[ 1 ] );
700 else if( tmp < -1.0 )
712 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 ] );
732 if( abs( _v[ 3 ] ) > (Type)1.0 )
734 if( fabs( (
double)_v[ 3 ] ) > 1.0 )
741 Type rad = acos( _v[ 3 ] ) * (Type)2.0;
751 Type sin_half_angle = sin( rad * (Type)0.5 );
752 if( sin_half_angle >= (Type)0.0001 )
754 Type sin_half_angle_inv = Type( 1.0 ) / sin_half_angle;
755 axis->x = float( _v[ 0 ] * sin_half_angle_inv );
756 axis->y = float( _v[ 1 ] * sin_half_angle_inv );
757 axis->z = float( _v[ 2 ] * sin_half_angle_inv );
767 axis->x = (float)1.0;
768 axis->y = (float)0.0;
769 axis->z = (float)0.0;
779 Type wx, wy, wz, xx, yy, yz, xy, xz, zz, x2, y2, z2;
782 x2 = _v[ 0 ] + _v[ 0 ];
783 y2 = _v[ 1 ] + _v[ 1 ];
784 z2 = _v[ 2 ] + _v[ 2 ];
798 mat[ 0 ][ 0 ] = 1.0f - ( yy + zz );
799 mat[ 0 ][ 1 ] = xy - wz;
800 mat[ 0 ][ 2 ] = xz + wy;
801 mat[ 0 ][ 3 ] = 0.0f;
803 mat[ 1 ][ 0 ] = xy + wz;
804 mat[ 1 ][ 1 ] = 1.0f - ( xx + zz );
805 mat[ 1 ][ 2 ] = yz - wx;
806 mat[ 1 ][ 3 ] = 0.0f;
808 mat[ 2 ][ 0 ] = xz - wy;
809 mat[ 2 ][ 1 ] = yz + wx;
810 mat[ 2 ][ 2 ] = 1.0f - ( xx + yy );
811 mat[ 2 ][ 3 ] = 0.0f;
837 if( adjustSign && ( cosom < (Type)0.0 ) )
840 q._v[ 0 ] = -to._v[ 0 ];
841 q._v[ 1 ] = -to._v[ 1 ];
842 q._v[ 2 ] = -to._v[ 2 ];
843 q._v[ 3 ] = -to._v[ 3 ];
852 if( ( (Type)1.0 - cosom ) > (Type)0.0001 )
856 omega = acos( cosom );
857 sinom = sin( omega );
858 sclp = sin( ( (Type)1.0 - t ) * omega ) / sinom;
859 sclq = sin( t * omega ) / sinom;
864 sclp = (Type)1.0 - t;
868 _v[ 0 ] = sclp * p._v[ 0 ] + sclq * q._v[ 0 ];
869 _v[ 1 ] = sclp * p._v[ 1 ] + sclq * q._v[ 1 ];
870 _v[ 2 ] = sclp * p._v[ 2 ] + sclq * q._v[ 2 ];
871 _v[ 3 ] = sclp * p._v[ 3 ] + sclq * q._v[ 3 ];
878 static bool IsVeryCloseToZero(
double value ) {
return fabs( value ) < 0.0001; }
881 typedef GlsQuaternion<float> GlsQuaternionF;
882 typedef GlsQuaternion<double> GlsQuaternionD;
885 inline std::ostream& operator<<( std::ostream& outstr, const GlsQuaternion<Type>& quat )
887 outstr.precision( 10 );
890 outstr << quat.Data()[ 0 ] <<
" ";
892 outstr << quat.Data()[ 1 ] <<
" ";
894 outstr << quat.Data()[ 2 ] <<
" ";
896 outstr << quat.Data()[ 3 ];
902 inline std::istream& operator>>( std::istream& instr, GlsQuaternion<Type>& quat )
904 instr >> quat.Data()[ 0 ] >> quat.Data()[ 1 ] >> quat.Data()[ 2 ] >> quat.Data()[ 3 ];
const Type * Data() const
Definition: gls_quaternion.h:169
GlsQuaternion(Type angle1, const Vector &axis1, Type angle2, const Vector &axis2, Type angle3, const Vector &axis3)
Definition: gls_quaternion.h:109
GlsQuaternion(Type angle, const Vector &axis)
Definition: gls_quaternion.h:93
const GlsQuaternion operator+(const GlsQuaternion &q) const
Definition: gls_quaternion.h:349
const GlsQuaternion operator-() const
Definition: gls_quaternion.h:402
bool operator!=(const GlsQuaternion &q) const
Definition: gls_quaternion.h:193
Vector GetEulerAngles()
Definition: gls_quaternion.h:718
void Normalize(void)
Definition: vertex.h:307
float DotProduct(const VertexNoColor &w) const
Definition: vertex.h:356
GlsQuaternion & operator-=(const GlsQuaternion &q)
Definition: gls_quaternion.h:391
bool operator<(const GlsQuaternion &q) const
Definition: gls_quaternion.h:205
void SetFromVectors(const Vector &to, const Vector &from)
Definition: gls_quaternion.h:578
const GlsQuaternion Inverse() const
Definition: gls_quaternion.h:446
Type GetRoll(void) const
Definition: gls_quaternion.h:684
Type DotProduct(const GlsQuaternion &q) const
Definition: gls_quaternion.h:458
void SetFromAngleAxis(Type angle, const Vector &axis)
Definition: gls_quaternion.h:497
void GetAngleAxis(Type *angle, Vector *axis)
Definition: gls_quaternion.h:728
Type Magnitude() const
Definition: gls_quaternion.h:413
GlsQuaternion(const Vector &anglesVec)
Definition: gls_quaternion.h:136
void SetFromAngleAxis(Type angle1, const Vector &axis1, Type angle2, const Vector &axis2, Type angle3, const Vector &axis3)
Definition: gls_quaternion.h:519
const GlsQuaternion operator-(const GlsQuaternion &q) const
Definition: gls_quaternion.h:378
void SetFromEulerAngles(Type angleX, Type angleY, Type angleZ)
Definition: gls_quaternion.h:538
GlsQuaternion(const GlsMatrixAffine< Type > &matrix)
Definition: gls_quaternion.h:147
VertexNoColor Vector
Definition: gls_font_base.h:66
GlsQuaternion(Type angleX, Type angleY, Type angleZ)
Definition: gls_quaternion.h:124
GlsQuaternion Conjugate() const
Definition: gls_quaternion.h:435
GlsQuaternion & operator+=(const GlsQuaternion &q)
Definition: gls_quaternion.h:362
GlsQuaternion & operator/=(Type s)
Definition: gls_quaternion.h:307
The disti::Vertex class. A class for manipulating 3D vertices.
VertexNoColor CrossProduct(const VertexNoColor &w) const
Definition: vertex.h:345
Type GetPitch(void) const
Definition: gls_quaternion.h:692
GlsQuaternion()
Definition: gls_quaternion.h:61
Type MagnitudeSquared() const
Definition: gls_quaternion.h:424
GlsQuaternion(Type x, Type y, Type z, Type w)
Definition: gls_quaternion.h:78
void Set(Type x, Type y, Type z, Type w)
Definition: gls_quaternion.h:482
const GlsQuaternion operator*(Type s) const
Definition: gls_quaternion.h:230
GlsQuaternion & operator/=(const GlsQuaternion &q)
Definition: gls_quaternion.h:336
Type * Data()
Definition: gls_quaternion.h:158
Type GetYaw(void) const
Definition: gls_quaternion.h:710
GlsQuaternion & operator*=(const GlsQuaternion &q)
Definition: gls_quaternion.h:273
const GlsQuaternion operator*(const GlsQuaternion &q) const
Definition: gls_quaternion.h:258
Definition: gls_quaternion.h:53
const GlsQuaternion operator/(const GlsQuaternion &q) const
Definition: gls_quaternion.h:324
bool operator==(const GlsQuaternion &q) const
Definition: gls_quaternion.h:181
float Magnitude() const
Definition: vertex.h:326
void SetFromSlerp(float t, const GlsQuaternion &from, const GlsQuaternion &to, bool adjustSign=true)
Definition: gls_quaternion.h:828
GlsMatrixAffine< Type > GetRotationMatrix()
Definition: gls_quaternion.h:777
GlsQuaternion & operator*=(Type s)
Definition: gls_quaternion.h:242
void SetFromRotationMatrix(const GlsMatrixAffine< Type > &matrix)
Definition: gls_quaternion.h:631
void Normalize()
Definition: gls_quaternion.h:468
Definition: bmpimage.h:46
GlsQuaternion operator/(Type s) const
Definition: gls_quaternion.h:294
Definition: gls_matrix_affine.h:60