///////////////////////////////////////////////////////////////////// // Linear Math Quaternions // © Dan Andersson 2013 ///////////////////////////////////////////////////////////////////// #ifndef LINEARALGEBRA_QUATERNION_H #define LINEARALGEBRA_QUATERNION_H #include "Vector.h" #include namespace LinearAlgebra { template struct Quaternion { public: union { struct{ Vector3 imaginary; ScalarType real; }; ScalarType element[4]; char byte[sizeof(ScalarType[2])]; }; Quaternion( ); Quaternion( const Quaternion &quaternion ); Quaternion( const Vector3 &imaginary, const ScalarType &real ); operator ScalarType* ( ); operator const ScalarType* ( ) const; operator char* ( ); operator const char* ( ) const; ScalarType & operator [] ( int i ); const ScalarType & operator [] ( int i ) const; Quaternion & operator = ( const Quaternion &quaternion ); Quaternion & operator *= ( const ScalarType &scalar ); Quaternion & operator /= ( const ScalarType &scalar ); Quaternion & operator += ( const Quaternion &quaternion ); Quaternion & operator -= ( const Quaternion &quaternion ); Quaternion operator * ( const Quaternion &quaternion ) const; Quaternion operator * ( const Vector3 &vector ) const; Quaternion operator * ( const ScalarType &scalar ) const; Quaternion operator / ( const ScalarType &scalar ) const; Quaternion operator + ( const Quaternion &quaternion ) const; Quaternion operator - ( const Quaternion &quaternion ) const; Quaternion operator - ( ) const; Quaternion GetConjugate( ) const; }; /////////////////////////////////////////////////////////////////////////////////// // Body /////////////////////////////////////////////////////////////////////////////////// template Quaternion::Quaternion( ) : imaginary(), real() {} template Quaternion::Quaternion( const Quaternion &quaternion ) { this->imaginary = quaternion.imaginary; this->real = quaternion.real; } template Quaternion::Quaternion( const Vector3 &_imaginary, const ScalarType &_real ) { this->imaginary = _imaginary; this->real = _real; } template inline Quaternion::operator ScalarType* ( ) { return this->element; } template inline Quaternion::operator const ScalarType* ( ) const { return this->element; } template inline Quaternion::operator char* ( ) { return this->byte; } template inline Quaternion::operator const char* ( ) const { return this->byte; } template inline ScalarType & Quaternion::operator [] ( int i ) { return this->element[i]; } template inline const ScalarType & Quaternion::operator [] ( int i ) const { return this->element[i]; } template Quaternion & Quaternion::operator = ( const Quaternion &quaternion ) { this->imaginary = quaternion.imaginary; this->real = quaternion.real; return *this; } template Quaternion & Quaternion::operator *= ( const ScalarType &scalar ) { this->imaginary *= scalar; this->real *= scalar; return *this; } template Quaternion & Quaternion::operator /= ( const ScalarType &scalar ) { this->imaginary /= scalar; this->real /= scalar; return *this; } template Quaternion & Quaternion::operator += ( const Quaternion &quaternion ) { this->imaginary += quaternion.imaginary; this->real += quaternion.real; return *this; } template Quaternion & Quaternion::operator -= ( const Quaternion &quaternion ) { this->imaginary -= quaternion.imaginary; this->real -= quaternion.real; return *this; } template Quaternion Quaternion::operator * ( const Quaternion &quaternion ) const { Vector3 im = this->imaginary.Cross( quaternion.imaginary ); im += (quaternion.imaginary * this->real); im += (this->imaginary * quaternion.real); ScalarType re = this->real * quaternion.real; re -= this->imaginary.Dot( quaternion.imaginary ); return Quaternion( im, re ); } template Quaternion Quaternion::operator * ( const Vector3 &vector ) const { Vector3 im = this->imaginary.Cross( vector ); im += (vector * this->real); ScalarType re = this->imaginary.Dot( vector ) * -1; return Quaternion( im, re ); } template inline Quaternion Quaternion::operator * ( const ScalarType &scalar ) const { return Quaternion(*this) *= scalar; } template inline Quaternion Quaternion::operator / ( const ScalarType &scalar ) const { return Quaternion(*this) /= scalar; } template inline Quaternion Quaternion::operator + ( const Quaternion &quaternion ) const { return Quaternion(*this) += quaternion; } template inline Quaternion Quaternion::operator - ( const Quaternion &quaternion ) const { return Quaternion(*this) -= quaternion; } template inline Quaternion Quaternion::operator - ( ) const { return Quaternion(-this->imaginary, -this->real); } template inline Quaternion Quaternion::GetConjugate( ) const { return Quaternion(-this->imaginary, this->real ); } } #endif