41 #ifndef GLS_QUATERNION_H
42 #define GLS_QUATERNION_H
52 class GlsMatrixAffine;
113 Type angle2,
const Vector& axis2,
114 Type angle3,
const Vector& axis3 )
172 inline const Type*
Data()
const
186 return _v[ 0 ] == q._v[ 0 ] && _v[ 1 ] == q._v[ 1 ] && _v[ 2 ] == q._v[ 2 ] && _v[ 3 ] == q._v[ 3 ];
198 return _v[ 0 ] != q._v[ 0 ] || _v[ 1 ] != q._v[ 1 ] || _v[ 2 ] != q._v[ 2 ] || _v[ 3 ] != q._v[ 3 ];
210 if( _v[ 0 ] < q._v[ 0 ] )
212 else if( _v[ 0 ] > q._v[ 0 ] )
214 else if( _v[ 1 ] < q._v[ 1 ] )
216 else if( _v[ 1 ] > q._v[ 1 ] )
218 else if( _v[ 2 ] < q._v[ 2 ] )
220 else if( _v[ 2 ] > q._v[ 2 ] )
223 return ( _v[ 3 ] < q._v[ 3 ] );
235 return GlsQuaternion( _v[ 0 ] * s, _v[ 1 ] * s, _v[ 2 ] * s, _v[ 3 ] * s );
263 return GlsQuaternion( q._v[ 3 ] * _v[ 0 ] + q._v[ 0 ] * _v[ 3 ] + q._v[ 1 ] * _v[ 2 ] - q._v[ 2 ] * _v[ 1 ],
264 q._v[ 3 ] * _v[ 1 ] - q._v[ 0 ] * _v[ 2 ] + q._v[ 1 ] * _v[ 3 ] + q._v[ 2 ] * _v[ 0 ],
265 q._v[ 3 ] * _v[ 2 ] + q._v[ 0 ] * _v[ 1 ] - q._v[ 1 ] * _v[ 0 ] + q._v[ 2 ] * _v[ 3 ],
266 q._v[ 3 ] * _v[ 3 ] - q._v[ 0 ] * _v[ 0 ] - q._v[ 1 ] * _v[ 1 ] - q._v[ 2 ] * _v[ 2 ] );
278 Type x = q._v[ 3 ] * _v[ 0 ] + q._v[ 0 ] * _v[ 3 ] + q._v[ 1 ] * _v[ 2 ] - q._v[ 2 ] * _v[ 1 ];
279 Type y = q._v[ 3 ] * _v[ 1 ] - q._v[ 0 ] * _v[ 2 ] + q._v[ 1 ] * _v[ 3 ] + q._v[ 2 ] * _v[ 0 ];
280 Type z = q._v[ 3 ] * _v[ 2 ] + q._v[ 0 ] * _v[ 1 ] - q._v[ 1 ] * _v[ 0 ] + q._v[ 2 ] * _v[ 3 ];
281 _v[ 3 ] = q._v[ 3 ] * _v[ 3 ] - q._v[ 0 ] * _v[ 0 ] - q._v[ 1 ] * _v[ 1 ] - q._v[ 2 ] * _v[ 2 ];
300 return GlsQuaternion( _v[ 0 ] * div, _v[ 1 ] * div, _v[ 2 ] * div, _v[ 3 ] * div );
329 return ( ( *
this ) * q.
Inverse() );
341 ( *this ) = ( *this ) * q.
Inverse();
354 return GlsQuaternion( _v[ 0 ] + q._v[ 0 ], _v[ 1 ] + q._v[ 1 ],
355 _v[ 2 ] + q._v[ 2 ], _v[ 3 ] + q._v[ 3 ] );
367 _v[ 0 ] += q._v[ 0 ];
368 _v[ 1 ] += q._v[ 1 ];
369 _v[ 2 ] += q._v[ 2 ];
370 _v[ 3 ] += q._v[ 3 ];
383 return GlsQuaternion( _v[ 0 ] - q._v[ 0 ], _v[ 1 ] - q._v[ 1 ],
384 _v[ 2 ] - q._v[ 2 ], _v[ 3 ] - q._v[ 3 ] );
396 _v[ 0 ] -= q._v[ 0 ];
397 _v[ 1 ] -= q._v[ 1 ];
398 _v[ 2 ] -= q._v[ 2 ];
399 _v[ 3 ] -= q._v[ 3 ];
407 return GlsQuaternion( -_v[ 0 ], -_v[ 1 ], -_v[ 2 ], -_v[ 3 ] );
418 return sqrt( _v[ 0 ] * _v[ 0 ] + _v[ 1 ] * _v[ 1 ] + _v[ 2 ] * _v[ 2 ] + _v[ 3 ] * _v[ 3 ] );
429 return _v[ 0 ] * _v[ 0 ] + _v[ 1 ] * _v[ 1 ] + _v[ 2 ] * _v[ 2 ] + _v[ 3 ] * _v[ 3 ];
440 return GlsQuaternion( -_v[ 0 ], -_v[ 1 ], -_v[ 2 ], _v[ 3 ] );
463 return ( ( _v[ 0 ] * q._v[ 0 ] ) + ( _v[ 1 ] * q._v[ 1 ] ) + ( _v[ 2 ] * q._v[ 2 ] ) + ( _v[ 3 ] * q._v[ 3 ] ) );
485 inline void Set( Type x, Type y, Type z, Type w )
502 Type half_angle = angle * (Type)0.5;
503 Type sin_half_angle = sin( half_angle );
505 _v[ 0 ] = sin_half_angle * axis.x;
506 _v[ 1 ] = sin_half_angle * axis.y;
507 _v[ 2 ] = sin_half_angle * axis.z;
508 _v[ 3 ] = cos( half_angle );
523 Type angle2,
const Vector& axis2,
524 Type angle3,
const Vector& axis3 )
530 *
this = q1 * q2 * *
this;
546 Type xOver2 = angleX * (Type)0.5;
547 Type yOver2 = angleY * (Type)0.5;
548 Type zOver2 = angleZ * (Type)0.5;
551 qx._v[ 0 ] = sin( xOver2 );
552 qx._v[ 1 ] = (Type)0.0;
553 qx._v[ 2 ] = (Type)0.0;
554 qx._v[ 3 ] = cos( xOver2 );
557 qy._v[ 0 ] = (Type)0.0;
558 qy._v[ 1 ] = sin( yOver2 );
559 qy._v[ 2 ] = (Type)0.0;
560 qy._v[ 3 ] = cos( yOver2 );
563 qz._v[ 0 ] = (Type)0.0;
564 qz._v[ 1 ] = (Type)0.0;
565 qz._v[ 2 ] = sin( zOver2 );
566 qz._v[ 3 ] = cos( zOver2 );
569 *
this = qx * qy * qz;
586 if( IsVeryCloseToZero( cosangle - 1 ) )
593 else if( IsVeryCloseToZero( cosangle + 1.0 ) )
598 if( fabs( from.x ) < fabs( from.y ) )
599 if( fabs( from.x ) < fabs( from.z ) )
600 tmp =
Vector( 1.0, 0.0, 0.0 );
602 tmp =
Vector( 0.0, 0.0, 1.0 );
603 else if( fabs( from.y ) < fabs( from.z ) )
604 tmp =
Vector( 0.0, 1.0, 0.0 );
606 tmp =
Vector( 0.0, 0.0, 1.0 );
623 Type angle = acos( cosangle );
641 int nxt[ 3 ] = { 1, 2, 0 };
643 tr = mat[ 0 * 4 + 0 ] + mat[ 1 * 4 + 1 ] + mat[ 2 * 4 + 2 ];
648 s = (Type)sqrt( tr + 1.0 );
651 _v[ 0 ] = ( mat[ 1 * 4 + 2 ] - mat[ 2 * 4 + 1 ] ) * s;
652 _v[ 1 ] = ( mat[ 2 * 4 + 0 ] - mat[ 0 * 4 + 2 ] ) * s;
653 _v[ 2 ] = ( mat[ 0 * 4 + 1 ] - mat[ 1 * 4 + 0 ] ) * s;
659 if( mat[ 1 * 4 + 1 ] > mat[ 0 * 4 + 0 ] )
661 if( mat[ 2 * 4 + 2 ] > mat[ i * 4 + i ] )
666 s = (Type)sqrt( ( mat[ i * 4 + i ] - ( mat[ j * 4 + j ] + mat[ k * 4 + k ] ) ) + 1.0 );
673 tq[ 3 ] = ( mat[ j * 4 + k ] - mat[ k * 4 + j ] ) * s;
674 tq[ j ] = ( mat[ i * 4 + j ] + mat[ j * 4 + i ] ) * s;
675 tq[ k ] = ( mat[ i * 4 + k ] + mat[ k * 4 + i ] ) * s;
689 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 ] );
697 Type tmp = -2 * ( _v[ 0 ] * _v[ 2 ] - _v[ 3 ] * _v[ 1 ] );
703 else if( tmp < -1.0 )
715 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 ] );
735 if( abs( _v[ 3 ] ) > (Type)1.0 )
737 if( fabs( (
double)_v[ 3 ] ) > 1.0 )
744 Type rad = acos( _v[ 3 ] ) * (Type)2.0;
754 Type sin_half_angle = sin( rad * (Type)0.5 );
755 if( sin_half_angle >= (Type)0.0001 )
757 Type sin_half_angle_inv = Type( 1.0 ) / sin_half_angle;
758 axis->x = float( _v[ 0 ] * sin_half_angle_inv );
759 axis->y = float( _v[ 1 ] * sin_half_angle_inv );
760 axis->z = float( _v[ 2 ] * sin_half_angle_inv );
770 axis->x = (float)1.0;
771 axis->y = (float)0.0;
772 axis->z = (float)0.0;
782 Type wx, wy, wz, xx, yy, yz, xy, xz, zz, x2, y2, z2;
785 x2 = _v[ 0 ] + _v[ 0 ];
786 y2 = _v[ 1 ] + _v[ 1 ];
787 z2 = _v[ 2 ] + _v[ 2 ];
801 mat[ 0 ][ 0 ] = 1.0f - ( yy + zz );
802 mat[ 0 ][ 1 ] = xy - wz;
803 mat[ 0 ][ 2 ] = xz + wy;
804 mat[ 0 ][ 3 ] = 0.0f;
806 mat[ 1 ][ 0 ] = xy + wz;
807 mat[ 1 ][ 1 ] = 1.0f - ( xx + zz );
808 mat[ 1 ][ 2 ] = yz - wx;
809 mat[ 1 ][ 3 ] = 0.0f;
811 mat[ 2 ][ 0 ] = xz - wy;
812 mat[ 2 ][ 1 ] = yz + wx;
813 mat[ 2 ][ 2 ] = 1.0f - ( xx + yy );
814 mat[ 2 ][ 3 ] = 0.0f;
840 if( adjustSign && ( cosom < (Type)0.0 ) )
843 q._v[ 0 ] = -to._v[ 0 ];
844 q._v[ 1 ] = -to._v[ 1 ];
845 q._v[ 2 ] = -to._v[ 2 ];
846 q._v[ 3 ] = -to._v[ 3 ];
855 if( ( (Type)1.0 - cosom ) > (Type)0.0001 )
859 omega = acos( cosom );
860 sinom = sin( omega );
861 sclp = sin( ( (Type)1.0 - t ) * omega ) / sinom;
862 sclq = sin( t * omega ) / sinom;
867 sclp = (Type)1.0 - t;
871 _v[ 0 ] = sclp * p._v[ 0 ] + sclq * q._v[ 0 ];
872 _v[ 1 ] = sclp * p._v[ 1 ] + sclq * q._v[ 1 ];
873 _v[ 2 ] = sclp * p._v[ 2 ] + sclq * q._v[ 2 ];
874 _v[ 3 ] = sclp * p._v[ 3 ] + sclq * q._v[ 3 ];
881 static bool IsVeryCloseToZero(
double value ) {
return fabs( value ) < 0.0001; }
884 typedef GlsQuaternion<float> GlsQuaternionF;
885 typedef GlsQuaternion<double> GlsQuaternionD;
888 inline std::ostream& operator<<( std::ostream& outstr, const GlsQuaternion<Type>& quat )
890 outstr.precision( MaxDigits10<Type>::value );
893 outstr << quat.Data()[ 0 ] <<
" ";
895 outstr << quat.Data()[ 1 ] <<
" ";
897 outstr << quat.Data()[ 2 ] <<
" ";
899 outstr << quat.Data()[ 3 ];
905 inline std::istream& operator>>( std::istream& instr, GlsQuaternion<Type>& quat )
907 instr >> quat.Data()[ 0 ] >> quat.Data()[ 1 ] >> quat.Data()[ 2 ] >> quat.Data()[ 3 ];
const Type * Data() const
Definition: gls_quaternion.h:172
GlsQuaternion(Type angle1, const Vector &axis1, Type angle2, const Vector &axis2, Type angle3, const Vector &axis3)
Definition: gls_quaternion.h:112
GlsQuaternion(Type angle, const Vector &axis)
Definition: gls_quaternion.h:96
const GlsQuaternion operator+(const GlsQuaternion &q) const
Definition: gls_quaternion.h:352
const GlsQuaternion operator-() const
Definition: gls_quaternion.h:405
bool operator!=(const GlsQuaternion &q) const
Definition: gls_quaternion.h:196
Vector GetEulerAngles()
Definition: gls_quaternion.h:721
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:394
bool operator<(const GlsQuaternion &q) const
Definition: gls_quaternion.h:208
void SetFromVectors(const Vector &to, const Vector &from)
Definition: gls_quaternion.h:581
const GlsQuaternion Inverse() const
Definition: gls_quaternion.h:449
Type GetRoll(void) const
Definition: gls_quaternion.h:687
Type DotProduct(const GlsQuaternion &q) const
Definition: gls_quaternion.h:461
void SetFromAngleAxis(Type angle, const Vector &axis)
Definition: gls_quaternion.h:500
void GetAngleAxis(Type *angle, Vector *axis)
Definition: gls_quaternion.h:731
Type Magnitude() const
Definition: gls_quaternion.h:416
GlsQuaternion(const Vector &anglesVec)
Definition: gls_quaternion.h:139
void SetFromAngleAxis(Type angle1, const Vector &axis1, Type angle2, const Vector &axis2, Type angle3, const Vector &axis3)
Definition: gls_quaternion.h:522
const GlsQuaternion operator-(const GlsQuaternion &q) const
Definition: gls_quaternion.h:381
void SetFromEulerAngles(Type angleX, Type angleY, Type angleZ)
Definition: gls_quaternion.h:541
GlsQuaternion(const GlsMatrixAffine< Type > &matrix)
Definition: gls_quaternion.h:150
VertexNoColor Vector
Definition: gls_font_base.h:66
GlsQuaternion(Type angleX, Type angleY, Type angleZ)
Definition: gls_quaternion.h:127
GlsQuaternion Conjugate() const
Definition: gls_quaternion.h:438
GlsQuaternion & operator+=(const GlsQuaternion &q)
Definition: gls_quaternion.h:365
GlsQuaternion & operator/=(Type s)
Definition: gls_quaternion.h:310
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:695
GlsQuaternion()
Definition: gls_quaternion.h:64
Type MagnitudeSquared() const
Definition: gls_quaternion.h:427
GlsQuaternion(Type x, Type y, Type z, Type w)
Definition: gls_quaternion.h:81
void Set(Type x, Type y, Type z, Type w)
Definition: gls_quaternion.h:485
const GlsQuaternion operator*(Type s) const
Definition: gls_quaternion.h:233
GlsQuaternion & operator/=(const GlsQuaternion &q)
Definition: gls_quaternion.h:339
Type * Data()
Definition: gls_quaternion.h:161
Type GetYaw(void) const
Definition: gls_quaternion.h:713
GlsQuaternion & operator*=(const GlsQuaternion &q)
Definition: gls_quaternion.h:276
const GlsQuaternion operator*(const GlsQuaternion &q) const
Definition: gls_quaternion.h:261
Definition: gls_quaternion.h:56
const GlsQuaternion operator/(const GlsQuaternion &q) const
Definition: gls_quaternion.h:327
bool operator==(const GlsQuaternion &q) const
Definition: gls_quaternion.h:184
float Magnitude() const
Definition: vertex.h:327
void SetFromSlerp(float t, const GlsQuaternion &from, const GlsQuaternion &to, bool adjustSign=true)
Definition: gls_quaternion.h:831
GlsMatrixAffine< Type > GetRotationMatrix()
Definition: gls_quaternion.h:780
Macros and helper code to determine what subset of C++11/14/17 is available.
GlsQuaternion & operator*=(Type s)
Definition: gls_quaternion.h:245
void SetFromRotationMatrix(const GlsMatrixAffine< Type > &matrix)
Definition: gls_quaternion.h:634
void Normalize()
Definition: gls_quaternion.h:471
Definition: bmpimage.h:46
GlsQuaternion operator/(Type s) const
Definition: gls_quaternion.h:297
Definition: gls_matrix_affine.h:60