///////////////////////////////////////////////////////////////////// // Linear Math Quaternions // © Dan Andersson 2013 ///////////////////////////////////////////////////////////////////// #pragma once #ifndef LINEARALGEBRA_QUATERNION_H #define LINEARALGEBRA_QUATERNION_H #include "Vector.h" #include namespace LinearAlgebra { template class Quaternion { public: union { struct{ Vector3 imaginary; ElementType real; }; ElementType element[4]; char byte[sizeof(ElementType[2])]; }; Quaternion( ); Quaternion( const Quaternion &quaternion ); Quaternion( const Vector3 &imaginary, const ElementType &real ); ~Quaternion( ); operator ElementType* ( ); operator const ElementType* ( ) const; operator char* ( ); operator const char* ( ) const; ElementType & operator [] ( int i ); const ElementType & operator [] ( int i ) const; Quaternion & operator = ( const Quaternion &quaternion ); Quaternion & operator *= ( const ElementType &scalar ); Quaternion & operator /= ( const ElementType &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 ElementType &scalar ) const; Quaternion operator / ( const ElementType &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(0,0,0), real(0) {} template Quaternion::Quaternion( const Quaternion &quaternion ) : imaginary(quaternion.imaginary), real(quaternion.real) {} template Quaternion::Quaternion( const Vector3 &_imaginary, const ElementType &_real ) : imaginary(_imaginary), real(_real) {} template Quaternion::~Quaternion( ) { /* Nothing that needs to be done */ } template inline Quaternion::operator ElementType* ( ) { return this->element; } template inline Quaternion::operator const ElementType* ( ) const { return this->element; } template inline Quaternion::operator char* ( ) { return this->byte; } template inline Quaternion::operator const char* ( ) const { return this->byte; } template inline ElementType & Quaternion::operator [] ( int i ) { return this->element[i]; } template inline const ElementType & 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 ElementType &scalar ) { this->imaginary *= scalar; this->real *= scalar; return *this; } template Quaternion & Quaternion::operator /= ( const ElementType &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); ElementType 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); ElementType re = this->imaginary.dot( vector ) * -1; return Quaternion( im, re ); } template inline Quaternion Quaternion::operator * ( const ElementType &scalar ) const { return Quaternion(*this) *= scalar; } template inline Quaternion Quaternion::operator / ( const ElementType &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 * -1, this->real ); } } #endif