41 #ifndef GLS_QUATERNION_H
42 #define GLS_QUATERNION_H
51 bool IsVeryCloseToZero(
double value ) {
return fabs( value ) < 0.0001; }
55 class GlsMatrixAffine;
116 Type angle2,
const Vector& axis2,
117 Type angle3,
const Vector& axis3 )
175 inline const Type*
Data()
const
189 return _v[ 0 ] == q._v[ 0 ] && _v[ 1 ] == q._v[ 1 ] && _v[ 2 ] == q._v[ 2 ] && _v[ 3 ] == q._v[ 3 ];
201 return _v[ 0 ] != q._v[ 0 ] || _v[ 1 ] != q._v[ 1 ] || _v[ 2 ] != q._v[ 2 ] || _v[ 3 ] != q._v[ 3 ];
213 if( _v[ 0 ] < q._v[ 0 ] )
215 else if( _v[ 0 ] > q._v[ 0 ] )
217 else if( _v[ 1 ] < q._v[ 1 ] )
219 else if( _v[ 1 ] > q._v[ 1 ] )
221 else if( _v[ 2 ] < q._v[ 2 ] )
223 else if( _v[ 2 ] > q._v[ 2 ] )
226 return ( _v[ 3 ] < q._v[ 3 ] );
238 return GlsQuaternion( _v[ 0 ] * s, _v[ 1 ] * s, _v[ 2 ] * s, _v[ 3 ] * s );
266 return GlsQuaternion( q._v[ 3 ] * _v[ 0 ] + q._v[ 0 ] * _v[ 3 ] + q._v[ 1 ] * _v[ 2 ] - q._v[ 2 ] * _v[ 1 ],
267 q._v[ 3 ] * _v[ 1 ] - q._v[ 0 ] * _v[ 2 ] + q._v[ 1 ] * _v[ 3 ] + q._v[ 2 ] * _v[ 0 ],
268 q._v[ 3 ] * _v[ 2 ] + q._v[ 0 ] * _v[ 1 ] - q._v[ 1 ] * _v[ 0 ] + q._v[ 2 ] * _v[ 3 ],
269 q._v[ 3 ] * _v[ 3 ] - q._v[ 0 ] * _v[ 0 ] - q._v[ 1 ] * _v[ 1 ] - q._v[ 2 ] * _v[ 2 ] );
281 Type x = q._v[ 3 ] * _v[ 0 ] + q._v[ 0 ] * _v[ 3 ] + q._v[ 1 ] * _v[ 2 ] - q._v[ 2 ] * _v[ 1 ];
282 Type y = q._v[ 3 ] * _v[ 1 ] - q._v[ 0 ] * _v[ 2 ] + q._v[ 1 ] * _v[ 3 ] + q._v[ 2 ] * _v[ 0 ];
283 Type z = q._v[ 3 ] * _v[ 2 ] + q._v[ 0 ] * _v[ 1 ] - q._v[ 1 ] * _v[ 0 ] + q._v[ 2 ] * _v[ 3 ];
284 _v[ 3 ] = q._v[ 3 ] * _v[ 3 ] - q._v[ 0 ] * _v[ 0 ] - q._v[ 1 ] * _v[ 1 ] - q._v[ 2 ] * _v[ 2 ];
303 return GlsQuaternion( _v[ 0 ] * div, _v[ 1 ] * div, _v[ 2 ] * div, _v[ 3 ] * div );
332 return ( ( *
this ) * q.
Inverse() );
344 ( *this ) = ( *this ) * q.
Inverse();
357 return GlsQuaternion( _v[ 0 ] + q._v[ 0 ], _v[ 1 ] + q._v[ 1 ],
358 _v[ 2 ] + q._v[ 2 ], _v[ 3 ] + q._v[ 3 ] );
370 _v[ 0 ] += q._v[ 0 ];
371 _v[ 1 ] += q._v[ 1 ];
372 _v[ 2 ] += q._v[ 2 ];
373 _v[ 3 ] += q._v[ 3 ];
386 return GlsQuaternion( _v[ 0 ] - q._v[ 0 ], _v[ 1 ] - q._v[ 1 ],
387 _v[ 2 ] - q._v[ 2 ], _v[ 3 ] - q._v[ 3 ] );
399 _v[ 0 ] -= q._v[ 0 ];
400 _v[ 1 ] -= q._v[ 1 ];
401 _v[ 2 ] -= q._v[ 2 ];
402 _v[ 3 ] -= q._v[ 3 ];
410 return GlsQuaternion( -_v[ 0 ], -_v[ 1 ], -_v[ 2 ], -_v[ 3 ] );
421 return sqrt( _v[ 0 ] * _v[ 0 ] + _v[ 1 ] * _v[ 1 ] + _v[ 2 ] * _v[ 2 ] + _v[ 3 ] * _v[ 3 ] );
432 return _v[ 0 ] * _v[ 0 ] + _v[ 1 ] * _v[ 1 ] + _v[ 2 ] * _v[ 2 ] + _v[ 3 ] * _v[ 3 ];
443 return GlsQuaternion( -_v[ 0 ], -_v[ 1 ], -_v[ 2 ], _v[ 3 ] );
466 return ( ( _v[ 0 ] * q._v[ 0 ] ) + ( _v[ 1 ] * q._v[ 1 ] ) + ( _v[ 2 ] * q._v[ 2 ] ) + ( _v[ 3 ] * q._v[ 3 ] ) );
488 inline void Set( Type x, Type y, Type z, Type w )
505 Type half_angle = angle * (Type)0.5;
506 Type sin_half_angle = sin( half_angle );
508 _v[ 0 ] = sin_half_angle * axis.x;
509 _v[ 1 ] = sin_half_angle * axis.y;
510 _v[ 2 ] = sin_half_angle * axis.z;
511 _v[ 3 ] = cos( half_angle );
526 Type angle2,
const Vector& axis2,
527 Type angle3,
const Vector& axis3 )
533 *
this = q1 * q2 * *
this;
549 Type xOver2 = angleX * (Type)0.5;
550 Type yOver2 = angleY * (Type)0.5;
551 Type zOver2 = angleZ * (Type)0.5;
554 qx._v[ 0 ] = sin( xOver2 );
555 qx._v[ 1 ] = (Type)0.0;
556 qx._v[ 2 ] = (Type)0.0;
557 qx._v[ 3 ] = cos( xOver2 );
560 qy._v[ 0 ] = (Type)0.0;
561 qy._v[ 1 ] = sin( yOver2 );
562 qy._v[ 2 ] = (Type)0.0;
563 qy._v[ 3 ] = cos( yOver2 );
566 qz._v[ 0 ] = (Type)0.0;
567 qz._v[ 1 ] = (Type)0.0;
568 qz._v[ 2 ] = sin( zOver2 );
569 qz._v[ 3 ] = cos( zOver2 );
572 *
this = qx * qy * qz;
589 if( IsVeryCloseToZero( cosangle - 1 ) )
596 else if( IsVeryCloseToZero( cosangle + 1.0 ) )
601 if( fabs( from.x ) < fabs( from.y ) )
602 if( fabs( from.x ) < fabs( from.z ) )
603 tmp =
Vector( 1.0, 0.0, 0.0 );
605 tmp =
Vector( 0.0, 0.0, 1.0 );
606 else if( fabs( from.y ) < fabs( from.z ) )
607 tmp =
Vector( 0.0, 1.0, 0.0 );
609 tmp =
Vector( 0.0, 0.0, 1.0 );
626 Type angle = acos( cosangle );
644 int nxt[ 3 ] = { 1, 2, 0 };
646 tr = mat[ 0 * 4 + 0 ] + mat[ 1 * 4 + 1 ] + mat[ 2 * 4 + 2 ];
651 s = (Type)sqrt( tr + 1.0 );
654 _v[ 0 ] = ( mat[ 1 * 4 + 2 ] - mat[ 2 * 4 + 1 ] ) * s;
655 _v[ 1 ] = ( mat[ 2 * 4 + 0 ] - mat[ 0 * 4 + 2 ] ) * s;
656 _v[ 2 ] = ( mat[ 0 * 4 + 1 ] - mat[ 1 * 4 + 0 ] ) * s;
662 if( mat[ 1 * 4 + 1 ] > mat[ 0 * 4 + 0 ] )
664 if( mat[ 2 * 4 + 2 ] > mat[ i * 4 + i ] )
669 s = (Type)sqrt( ( mat[ i * 4 + i ] - ( mat[ j * 4 + j ] + mat[ k * 4 + k ] ) ) + 1.0 );
676 tq[ 3 ] = ( mat[ j * 4 + k ] - mat[ k * 4 + j ] ) * s;
677 tq[ j ] = ( mat[ i * 4 + j ] + mat[ j * 4 + i ] ) * s;
678 tq[ k ] = ( mat[ i * 4 + k ] + mat[ k * 4 + i ] ) * s;
692 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 ] );
700 Type tmp = -2 * ( _v[ 0 ] * _v[ 2 ] - _v[ 3 ] * _v[ 1 ] );
706 else if( tmp < -1.0 )
718 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 ] );
738 if( abs( _v[ 3 ] ) > (Type)1.0 )
740 if( fabs( (
double)_v[ 3 ] ) > 1.0 )
747 Type rad = acos( _v[ 3 ] ) * (Type)2.0;
757 Type sin_half_angle = sin( rad * (Type)0.5 );
758 if( sin_half_angle >= (Type)0.0001 )
760 Type sin_half_angle_inv = Type( 1.0 ) / sin_half_angle;
761 axis->x = float( _v[ 0 ] * sin_half_angle_inv );
762 axis->y = float( _v[ 1 ] * sin_half_angle_inv );
763 axis->z = float( _v[ 2 ] * sin_half_angle_inv );
773 axis->x = (float)1.0;
774 axis->y = (float)0.0;
775 axis->z = (float)0.0;
785 Type wx, wy, wz, xx, yy, yz, xy, xz, zz, x2, y2, z2;
788 x2 = _v[ 0 ] + _v[ 0 ];
789 y2 = _v[ 1 ] + _v[ 1 ];
790 z2 = _v[ 2 ] + _v[ 2 ];
804 mat[ 0 ][ 0 ] = 1.0f - ( yy + zz );
805 mat[ 0 ][ 1 ] = xy - wz;
806 mat[ 0 ][ 2 ] = xz + wy;
807 mat[ 0 ][ 3 ] = 0.0f;
809 mat[ 1 ][ 0 ] = xy + wz;
810 mat[ 1 ][ 1 ] = 1.0f - ( xx + zz );
811 mat[ 1 ][ 2 ] = yz - wx;
812 mat[ 1 ][ 3 ] = 0.0f;
814 mat[ 2 ][ 0 ] = xz - wy;
815 mat[ 2 ][ 1 ] = yz + wx;
816 mat[ 2 ][ 2 ] = 1.0f - ( xx + yy );
817 mat[ 2 ][ 3 ] = 0.0f;
843 if( adjustSign && ( cosom < (Type)0.0 ) )
846 q._v[ 0 ] = -to._v[ 0 ];
847 q._v[ 1 ] = -to._v[ 1 ];
848 q._v[ 2 ] = -to._v[ 2 ];
849 q._v[ 3 ] = -to._v[ 3 ];
858 if( ( (Type)1.0 - cosom ) > (Type)0.0001 )
862 omega = acos( cosom );
863 sinom = sin( omega );
864 sclp = sin( ( (Type)1.0 - t ) * omega ) / sinom;
865 sclq = sin( t * omega ) / sinom;
870 sclp = (Type)1.0 - t;
874 _v[ 0 ] = sclp * p._v[ 0 ] + sclq * q._v[ 0 ];
875 _v[ 1 ] = sclp * p._v[ 1 ] + sclq * q._v[ 1 ];
876 _v[ 2 ] = sclp * p._v[ 2 ] + sclq * q._v[ 2 ];
877 _v[ 3 ] = sclp * p._v[ 3 ] + sclq * q._v[ 3 ];
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( 10 );
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:175
GlsQuaternion(Type angle1, const Vector &axis1, Type angle2, const Vector &axis2, Type angle3, const Vector &axis3)
Definition: gls_quaternion.h:115
GlsQuaternion(Type angle, const Vector &axis)
Definition: gls_quaternion.h:99
const GlsQuaternion operator+(const GlsQuaternion &q) const
Definition: gls_quaternion.h:355
const GlsQuaternion operator-() const
Definition: gls_quaternion.h:408
bool operator!=(const GlsQuaternion &q) const
Definition: gls_quaternion.h:199
Vector GetEulerAngles()
Definition: gls_quaternion.h:724
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:397
bool operator<(const GlsQuaternion &q) const
Definition: gls_quaternion.h:211
void SetFromVectors(const Vector &to, const Vector &from)
Definition: gls_quaternion.h:584
const GlsQuaternion Inverse() const
Definition: gls_quaternion.h:452
Type GetRoll(void) const
Definition: gls_quaternion.h:690
Type DotProduct(const GlsQuaternion &q) const
Definition: gls_quaternion.h:464
void SetFromAngleAxis(Type angle, const Vector &axis)
Definition: gls_quaternion.h:503
void GetAngleAxis(Type *angle, Vector *axis)
Definition: gls_quaternion.h:734
Type Magnitude() const
Definition: gls_quaternion.h:419
GlsQuaternion(const Vector &anglesVec)
Definition: gls_quaternion.h:142
void SetFromAngleAxis(Type angle1, const Vector &axis1, Type angle2, const Vector &axis2, Type angle3, const Vector &axis3)
Definition: gls_quaternion.h:525
const GlsQuaternion operator-(const GlsQuaternion &q) const
Definition: gls_quaternion.h:384
void SetFromEulerAngles(Type angleX, Type angleY, Type angleZ)
Definition: gls_quaternion.h:544
GlsQuaternion(const GlsMatrixAffine< Type > &matrix)
Definition: gls_quaternion.h:153
VertexNoColor Vector
Definition: gls_font_base.h:66
GlsQuaternion(Type angleX, Type angleY, Type angleZ)
Definition: gls_quaternion.h:130
GlsQuaternion Conjugate() const
Definition: gls_quaternion.h:441
GlsQuaternion & operator+=(const GlsQuaternion &q)
Definition: gls_quaternion.h:368
GlsQuaternion & operator/=(Type s)
Definition: gls_quaternion.h:313
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:698
GlsQuaternion()
Definition: gls_quaternion.h:67
Type MagnitudeSquared() const
Definition: gls_quaternion.h:430
GlsQuaternion(Type x, Type y, Type z, Type w)
Definition: gls_quaternion.h:84
void Set(Type x, Type y, Type z, Type w)
Definition: gls_quaternion.h:488
const GlsQuaternion operator*(Type s) const
Definition: gls_quaternion.h:236
GlsQuaternion & operator/=(const GlsQuaternion &q)
Definition: gls_quaternion.h:342
Type * Data()
Definition: gls_quaternion.h:164
Type GetYaw(void) const
Definition: gls_quaternion.h:716
GlsQuaternion & operator*=(const GlsQuaternion &q)
Definition: gls_quaternion.h:279
const GlsQuaternion operator*(const GlsQuaternion &q) const
Definition: gls_quaternion.h:264
Definition: gls_quaternion.h:59
const GlsQuaternion operator/(const GlsQuaternion &q) const
Definition: gls_quaternion.h:330
bool operator==(const GlsQuaternion &q) const
Definition: gls_quaternion.h:187
float Magnitude() const
Definition: vertex.h:326
void SetFromSlerp(float t, const GlsQuaternion &from, const GlsQuaternion &to, bool adjustSign=true)
Definition: gls_quaternion.h:834
GlsMatrixAffine< Type > GetRotationMatrix()
Definition: gls_quaternion.h:783
GlsQuaternion & operator*=(Type s)
Definition: gls_quaternion.h:248
void SetFromRotationMatrix(const GlsMatrixAffine< Type > &matrix)
Definition: gls_quaternion.h:637
void Normalize()
Definition: gls_quaternion.h:474
Definition: bmpimage.h:46
GlsQuaternion operator/(Type s) const
Definition: gls_quaternion.h:300
Definition: gls_matrix_affine.h:60