00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef GLQUATERNION_H
00021 #define GLQUATERNION_H
00022
00023 #include "GLVector.h"
00024 #include "GLMatrix.h"
00025
00026 namespace mathglpp
00027 {
00033 template <class T>
00034 class GLQuaternion
00035 {
00036 public:
00038 GLQuaternion()
00039 :w(1),v(0,0,0)
00040 {}
00041
00043 GLQuaternion(T f, const GLVector3<T>& gv)
00044 :w(f),v(gv)
00045 {}
00046
00048 GLQuaternion(const GLVector3<T>& gv)
00049 :w(0),v(gv)
00050 {}
00051
00053 GLQuaternion(const T* gq)
00054 :w(gq[0]),v(gq+1)
00055 {}
00056
00058 GLQuaternion(const GLQuaternion& gq)
00059 :w(gq.w),v(gq.v)
00060 {}
00061
00062
00066 GLQuaternion(GLVector3<T> gv, T degrees)
00067 { set(gv.unit(), degrees); }
00068
00070 ~GLQuaternion(){}
00071
00073 inline T getW()
00074 { return w; }
00075
00077 inline const GLVector3<T>& getV()
00078 { return v; }
00079
00081 inline void set(T _w, const GLVector3<T>& gv)
00082 { w = _w; v = gv; }
00083
00085 inline void set(T _w, T x, T y, T z)
00086 { w = _w; v.set(x,y,z); }
00087
00089 inline void set(const T* gq)
00090 { set(gq[0],gq[1],gq[2],gq[3]); }
00091
00094 inline void set(GLVector3<T> vec, T degrees)
00095 { set(cos(degrees*M_PI/360.0), vec * sin(degrees*M_PI/360.0) ); }
00096
00098 GLQuaternion operator + (GLQuaternion gq)
00099 { GLQuaternion temp(*this); temp += gq; return temp; }
00100
00102 GLQuaternion operator - (GLQuaternion gq)
00103 { GLQuaternion temp(*this); temp -= gq; return temp; }
00104
00106 GLQuaternion& operator += (GLQuaternion gq)
00107 { w += gq.w; v += gq.v; return *this; }
00108
00110 GLQuaternion& operator -= (GLQuaternion gq)
00111 { w -= gq.w; v -= gq.v; return *this; }
00112
00114 GLQuaternion operator * (GLQuaternion gq)
00115 { GLQuaternion temp(*this); temp *= gq; return temp; }
00116
00118 GLQuaternion operator / (T f)
00119 { GLQuaternion temp(*this); temp /= f; return temp; }
00120
00122 GLQuaternion& operator *= (GLQuaternion gq)
00123 { set( w * gq.w - v.dot(gq.v) , (gq.v * w) + (v * gq.w) + v.getCross(gq.v) ); return *this; }
00124
00126 GLQuaternion& operator /= (T f)
00127 { set( w / f , v / f ); return *this; }
00128
00130 T dot(GLQuaternion gq)
00131 { return ( w*gq.w + v.dot(gq.v) ); }
00132
00134 GLQuaternion getCross(GLQuaternion gq)
00135 { return GLQuaternion( w * gq.w - v.dot(gq.v) , (gq.v * w) + (v * gq.w) + v.getCross(gq.v) ); }
00136
00138 GLQuaternion getConjugate()
00139 { GLQuaternion temp(*this); temp.conjugate(); return temp; }
00140
00142 GLQuaternion& conjugate()
00143 { v = -v; return *this; }
00144
00146 GLQuaternion getInverse()
00147 { GLQuaternion temp(*this); temp.inverse(); return temp; }
00148
00150 GLQuaternion& inverse()
00151 { conjugate(); *this /= norm(); return *this; }
00152
00154 T selection()
00155 { return w; }
00156
00158 T norm()
00159 { return sqrt( w*w + v.lengthSqr() ); }
00160
00162 GLQuaternion unit() const
00163 { return this->operator /(norm()); }
00164
00166 inline GLQuaternion& normalise(){ return normalize(); }
00167
00168 GLQuaternion& normalize()
00169 { return this->operator /=(norm()); }
00170
00173 GLVector3<T> rotateVector(const GLVector3<T>& gv)
00174 { GLQuaternion temp = getCross(GLQuaternion(gv)); temp *= getConjugate(); return temp.v; }
00175
00178 GLMatrix<T> matrix(void)
00179 {
00180 GLMatrix<T> temp;
00181
00182 T xx=v.x*v.x; T xy=v.x*v.y; T xz=v.x*v.z; T xw=v.x*w;
00183 T yy=v.y*v.y; T yz=v.y*v.z; T yw=v.y*w;
00184 T zz=v.z*v.z; T zw=v.z*w;
00185
00186 temp[0] = 1 - 2*(zz + yy);
00187 temp[1] = 2*(xy + zw);
00188 temp[2] = 2*(xz - yw);
00189 temp[3] = 0;
00190
00191 temp[4] = 2*(xy - zw);
00192 temp[5] = 1 - 2*(zz + xx);
00193 temp[6] = 2*(yz + xw);
00194 temp[7] = 0;
00195
00196 temp[8] = 2*(yw + xz);
00197 temp[9] = 2*(yz - xw);
00198 temp[10] = 1 - 2*(yy + xx);
00199 temp[11] = 0;
00200
00201 temp[12] = 0;
00202 temp[13] = 0;
00203 temp[14] = 0;
00204 temp[15] = 1;
00205
00206 return temp;
00207 }
00208
00209 private:
00211 T w;
00213 GLVector3<T> v;
00214 };
00215
00217 typedef GLQuaternion<GLfloat> GLQuaternionf;
00219 typedef GLQuaternion<GLdouble> GLQuaterniond;
00220
00221 };
00222
00223 #endif