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