41 #ifndef GLS_QUATERNION_H
42 #define GLS_QUATERNION_H
49 bool IsVeryCloseToZero(
double value ) {
return fabs(value) < 0.0001; }
53 class GlsMatrixAffine;
78 _v[0]=x; _v[1]=y; _v[2]=z; _v[3]=w;
105 Type angle2,
const Vector& axis2,
106 Type angle3,
const Vector& axis3)
162 inline const Type*
Data()
const
173 {
return _v[0]==q._v[0] && _v[1]==q._v[1] && _v[2]==q._v[2] && _v[3]==q._v[3]; }
183 {
return _v[0]!=q._v[0] || _v[1]!=q._v[1] || _v[2]!=q._v[2] || _v[3]!=q._v[3]; }
194 if (_v[0]<q._v[0])
return true;
195 else if (_v[0]>q._v[0])
return false;
196 else if (_v[1]<q._v[1])
return true;
197 else if (_v[1]>q._v[1])
return false;
198 else if (_v[2]<q._v[2])
return true;
199 else if (_v[2]>q._v[2])
return false;
200 else return (_v[3]<q._v[3]);
240 return GlsQuaternion( q._v[3]*_v[0] + q._v[0]*_v[3] + q._v[1]*_v[2] - q._v[2]*_v[1],
241 q._v[3]*_v[1] - q._v[0]*_v[2] + q._v[1]*_v[3] + q._v[2]*_v[0],
242 q._v[3]*_v[2] + q._v[0]*_v[1] - q._v[1]*_v[0] + q._v[2]*_v[3],
243 q._v[3]*_v[3] - q._v[0]*_v[0] - q._v[1]*_v[1] - q._v[2]*_v[2] );
255 Type x = q._v[3]*_v[0] + q._v[0]*_v[3] + q._v[1]*_v[2] - q._v[2]*_v[1];
256 Type y = q._v[3]*_v[1] - q._v[0]*_v[2] + q._v[1]*_v[3] + q._v[2]*_v[0];
257 Type z = q._v[3]*_v[2] + q._v[0]*_v[1] - q._v[1]*_v[0] + q._v[2]*_v[3];
258 _v[3] = q._v[3]*_v[3] - q._v[0]*_v[0] - q._v[1]*_v[1] - q._v[2]*_v[2];
277 return GlsQuaternion(_v[0]*div, _v[1]*div, _v[2]*div, _v[3]*div);
306 return ( (*
this) * q.
Inverse() );
318 (*this) = (*this) * q.
Inverse();
332 _v[2]+q._v[2], _v[3]+q._v[3]);
361 _v[2]-q._v[2], _v[3]-q._v[3] );
395 return sqrt( _v[0]*_v[0] + _v[1]*_v[1] + _v[2]*_v[2] + _v[3]*_v[3]);
406 return _v[0]*_v[0] + _v[1]*_v[1] + _v[2]*_v[2] + _v[3]*_v[3];
440 return ( (_v[0] * q._v[0]) +
465 inline void Set(Type x, Type y, Type z, Type w)
467 _v[0]=x; _v[1]=y; _v[2]=z; _v[3]=w;
479 Type half_angle = angle * (Type)0.5;
480 Type sin_half_angle = sin( half_angle );
482 _v[0] = sin_half_angle * axis.x;
483 _v[1] = sin_half_angle * axis.y;
484 _v[2] = sin_half_angle * axis.z;
485 _v[3] = cos( half_angle );
500 Type angle2,
const Vector& axis2,
501 Type angle3,
const Vector& axis3)
507 *
this = q1 * q2 * *
this;
523 Type xOver2 = angleX * (Type)0.5;
524 Type yOver2 = angleY * (Type)0.5;
525 Type zOver2 = angleZ * (Type)0.5;
528 qx._v[0] = sin( xOver2 );
529 qx._v[1] = (Type)0.0;
530 qx._v[2] = (Type)0.0;
531 qx._v[3] = cos( xOver2 );
534 qy._v[0] = (Type)0.0;
535 qy._v[1] = sin( yOver2 );
536 qy._v[2] = (Type)0.0;
537 qy._v[3] = cos( yOver2 );
540 qz._v[0] = (Type)0.0;
541 qz._v[1] = (Type)0.0;
542 qz._v[2] = sin( zOver2 );
543 qz._v[3] = cos( zOver2 );
546 *
this = qx * qy * qz;
563 if ( IsVeryCloseToZero(cosangle - 1) )
571 if ( IsVeryCloseToZero(cosangle + 1.0) )
576 if (fabs(from.x)<fabs(from.y))
577 if (fabs(from.x)<fabs(from.z)) tmp =
Vector(1.0,0.0,0.0);
578 else tmp =
Vector(0.0,0.0,1.0);
579 else if (fabs(from.y)<fabs(from.z)) tmp =
Vector(0.0,1.0,0.0);
580 else tmp =
Vector(0.0,0.0,1.0);
598 Type angle = acos( cosangle );
616 int nxt[3] = {1, 2, 0};
618 tr = mat[0*4+0] + mat[1*4+1] + mat[2*4+2];
623 s = (Type)sqrt (tr + 1.0);
626 _v[0] = (mat[1*4+2] - mat[2*4+1]) * s;
627 _v[1] = (mat[2*4+0] - mat[0*4+2]) * s;
628 _v[2] = (mat[0*4+1] - mat[1*4+0]) * s;
634 if (mat[1*4+1] > mat[0*4+0])
636 if (mat[2*4+2] > mat[i*4+i])
641 s = (Type)sqrt ((mat[i*4+i] - (mat[j*4+j] + mat[k*4+k])) + 1.0);
648 tq[3] = (mat[j*4+k] - mat[k*4+j]) * s;
649 tq[j] = (mat[i*4+j] + mat[j*4+i]) * s;
650 tq[k] = (mat[i*4+k] + mat[k*4+i]) * s;
664 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]);
672 Type tmp = -2*(_v[0]*_v[2] - _v[3]*_v[1]);
674 if(tmp > 1.0) { tmp = 1.0; }
675 else if(tmp < -1.0) { tmp = -1.0; }
684 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]);
704 if (abs( _v[3] ) > (Type)1.0)
706 if (fabs( (
double)_v[3] ) > 1.0)
713 Type rad = acos( _v[3] ) * (Type)2.0;
723 Type sin_half_angle = sin( rad * (Type)0.5 );
724 if (sin_half_angle >= (Type)0.0001)
726 Type sin_half_angle_inv = Type(1.0) / sin_half_angle;
727 axis->x = float(_v[0] * sin_half_angle_inv);
728 axis->y = float(_v[1] * sin_half_angle_inv);
729 axis->z = float(_v[2] * sin_half_angle_inv);
739 axis->x = (float)1.0;
740 axis->y = (float)0.0;
741 axis->z = (float)0.0;
752 Type wx, wy, wz, xx, yy, yz, xy, xz, zz, x2, y2, z2;
771 mat[0][0] = 1.0f - (yy + zz);
777 mat[1][1] = 1.0f - (xx + zz);
783 mat[2][2] = 1.0f - (xx + yy);
810 if (adjustSign && (cosom < (Type)0.0))
825 if (((Type)1.0 - cosom) > (Type)0.0001)
829 omega = acos( cosom );
830 sinom = sin( omega );
831 sclp = sin( ((Type)1.0 - t) * omega ) / sinom;
832 sclq = sin( t * omega ) / sinom;
837 sclp = (Type)1.0 - t;
841 _v[0] = sclp * p._v[0] + sclq * q._v[0];
842 _v[1] = sclp * p._v[1] + sclq * q._v[1];
843 _v[2] = sclp * p._v[2] + sclq * q._v[2];
844 _v[3] = sclp * p._v[3] + sclq * q._v[3];
851 typedef GlsQuaternion<float> GlsQuaternionF;
852 typedef GlsQuaternion<double> GlsQuaternionD;
854 template <
class Type>
855 inline std::ostream& operator<<(std::ostream& outstr, const GlsQuaternion<Type>& quat)
857 outstr.precision(10);
860 outstr << quat.Data()[0]<<
" ";
862 outstr << quat.Data()[1]<<
" ";
864 outstr << quat.Data()[2]<<
" ";
866 outstr << quat.Data()[3];
871 template <
class Type>
872 inline std::istream& operator>>(std::istream& instr, GlsQuaternion<Type>& quat)
874 instr >> quat.Data()[0] >> quat.Data()[1] >> quat.Data()[2] >> quat.Data()[3];
const Type * Data() const
Definition: gls_quaternion.h:162
GlsQuaternion(Type angle1, const Vector &axis1, Type angle2, const Vector &axis2, Type angle3, const Vector &axis3)
Definition: gls_quaternion.h:104
GlsQuaternion(Type angle, const Vector &axis)
Definition: gls_quaternion.h:88
const GlsQuaternion operator+(const GlsQuaternion &q) const
Definition: gls_quaternion.h:329
const GlsQuaternion operator-() const
Definition: gls_quaternion.h:382
bool operator!=(const GlsQuaternion &q) const
Definition: gls_quaternion.h:182
Vector GetEulerAngles()
Definition: gls_quaternion.h:690
void Normalize(void)
Definition: vertex.h:271
float DotProduct(const VertexNoColor &w) const
Definition: vertex.h:315
GlsQuaternion & operator-=(const GlsQuaternion &q)
Definition: gls_quaternion.h:371
bool operator<(const GlsQuaternion &q) const
Definition: gls_quaternion.h:192
void SetFromVectors(const Vector &to, const Vector &from)
Definition: gls_quaternion.h:558
const GlsQuaternion Inverse() const
Definition: gls_quaternion.h:426
Type GetRoll(void) const
Definition: gls_quaternion.h:662
Type DotProduct(const GlsQuaternion &q) const
Definition: gls_quaternion.h:438
void SetFromAngleAxis(Type angle, const Vector &axis)
Definition: gls_quaternion.h:477
void GetAngleAxis(Type *angle, Vector *axis)
Definition: gls_quaternion.h:700
Type Magnitude() const
Definition: gls_quaternion.h:393
GlsQuaternion(const Vector &anglesVec)
Definition: gls_quaternion.h:131
void SetFromAngleAxis(Type angle1, const Vector &axis1, Type angle2, const Vector &axis2, Type angle3, const Vector &axis3)
Definition: gls_quaternion.h:499
void SetFromEulerAngles(Type angleX, Type angleY, Type angleZ)
Definition: gls_quaternion.h:518
GlsQuaternion(const GlsMatrixAffine< Type > &matrix)
Definition: gls_quaternion.h:142
VertexNoColor Vector
Definition: gls_font_base.h:68
GlsQuaternion(Type angleX, Type angleY, Type angleZ)
Definition: gls_quaternion.h:119
GlsQuaternion Conjugate() const
Definition: gls_quaternion.h:415
GlsQuaternion & operator+=(const GlsQuaternion &q)
Definition: gls_quaternion.h:342
GlsQuaternion & operator/=(Type s)
Definition: gls_quaternion.h:287
VertexNoColor CrossProduct(const VertexNoColor &w) const
Definition: vertex.h:305
Type GetPitch(void) const
Definition: gls_quaternion.h:670
GlsQuaternion()
Definition: gls_quaternion.h:65
Type MagnitudeSquared() const
Definition: gls_quaternion.h:404
GlsQuaternion(Type x, Type y, Type z, Type w)
Definition: gls_quaternion.h:76
void Set(Type x, Type y, Type z, Type w)
Definition: gls_quaternion.h:465
const GlsQuaternion operator*(Type s) const
Definition: gls_quaternion.h:210
GlsQuaternion & operator/=(const GlsQuaternion &q)
Definition: gls_quaternion.h:316
Type * Data()
Definition: gls_quaternion.h:153
Type GetYaw(void) const
Definition: gls_quaternion.h:682
GlsQuaternion & operator*=(const GlsQuaternion &q)
Definition: gls_quaternion.h:253
const GlsQuaternion operator*(const GlsQuaternion &q) const
Definition: gls_quaternion.h:238
Definition: gls_quaternion.h:57
const GlsQuaternion operator/(const GlsQuaternion &q) const
Definition: gls_quaternion.h:304
bool operator==(const GlsQuaternion &q) const
Definition: gls_quaternion.h:172
float Magnitude() const
Definition: vertex.h:290
void SetFromSlerp(float t, const GlsQuaternion &from, const GlsQuaternion &to, bool adjustSign=true)
Definition: gls_quaternion.h:801
GlsMatrixAffine< Type > GetRotationMatrix()
Definition: gls_quaternion.h:750
GlsQuaternion & operator*=(Type s)
Definition: gls_quaternion.h:222
void SetFromRotationMatrix(const GlsMatrixAffine< Type > &matrix)
Definition: gls_quaternion.h:609
void Normalize()
Definition: gls_quaternion.h:451
Definition: bmpimage.h:46
GlsQuaternion operator/(Type s) const
Definition: gls_quaternion.h:274
Definition: gls_matrix_affine.h:61