arbeit
Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound Members | File Members

quat.h

Go to the documentation of this file.
00001 /*
00002  * $Id: quat.h,v 1.5 2003/10/09 08:27:51 jmk Exp $
00003  */
00004 ///////////////////////////////////////////////////////////////////////////
00005 //              _____________  ______________________    __   __  _____
00006 //             /  ________  |  |   ___   ________   /   |  \ /  \   |
00007 //            |  |       |  |_ |  |_ |  |       /  /    \__  |      |
00008 //            |  |  ___  |  || |  || |  |      /  /        | |      |
00009 //            |  | |   \ |  || |  || |  |     /  /      \__/ \__/ __|__
00010 //            |  | |_@  ||  || |  || |  |    /  /          Institute
00011 //            |  |___/  ||  ||_|  || |  |   /  /_____________________
00012 //             \_______/  \______/ | |__|  /___________________________
00013 //                        |  |__|  |
00014 //                         \______/
00015 //                    University of Utah       
00016 //                           2002
00017 ///////////////////////////////////////////////////////////////////////////
00018 
00019 // quat.h
00020 
00021 #ifndef quat_h
00022 #define quat_h
00023 
00024 #include <../mathGutz/vec4.h>
00025 
00026 namespace gutz {
00027 
00028 template <class T> class vec3;
00029 template <class T> class mat3;
00030 
00031 template <class T>
00032 class quat
00033   : public vec4<T> 
00034 {
00035 public:
00036   inline quat ();
00037   inline quat (const T, const T, const T, const T);
00038   inline quat (const vec4<T>&);
00039   inline quat (const quat<T>&);
00040   inline quat (const vec3<T>&);
00041   inline quat (const T, const vec3<T>&);
00042   inline quat (const mat3<T>&);
00043   inline ~quat () {}
00044 
00045   inline quat mult (const quat&) const;
00046   inline quat conj () const;
00047   inline quat inv () const;
00048 
00049   inline vec3<T> rot (const vec3<T>&) const;
00050   inline quat rot (const quat&) const;
00051 
00052   inline void set (const T phi, const vec3<T>& k);
00053   inline void set (const mat3<T>& M);
00054 };
00055 
00056 //-----------------------------------------------------------------------------
00057 // typedefs
00058 //-----------------------------------------------------------------------------
00059 
00060 typedef quat<float> quatf;
00061 typedef quat<double> quatd;
00062 
00063 //-----------------------------------------------------------------------------
00064 // Implementation
00065 //-----------------------------------------------------------------------------
00066 
00067 template <class T>
00068 quat<T>::quat ()
00069   : vec4<T>(0, 0, 0, 1)
00070 {}
00071 
00072 template <class T>
00073 quat<T>::quat (T x0, T y0, T z0, T w0)
00074   : vec4<T>(x0, y0, z0, w0)
00075 {}
00076 
00077 template <class T>
00078 quat<T>::quat (const vec4<T>& v)
00079   : vec4<T>(v)
00080 {}
00081 
00082 template <class T>
00083 quat<T>::quat (const quat<T>& v)
00084   : vec4<T>((vec4<T>)v)
00085 {}
00086 
00087 template <class T>
00088 quat<T>::quat (const vec3<T>& v)
00089   : vec4<T>(v.x, v.y, v.z, 0)
00090 {}
00091 
00092 template <class T>
00093 quat<T>::quat (const T phi, const vec3<T>& k)
00094 {
00095   set(phi, k);
00096 }
00097 
00098 template <class T>
00099 quat<T>::quat (const mat3<T>& M)
00100 {
00101   set(M);
00102 }
00103 
00104 template <class T>
00105 quat<T>
00106 quat<T>::mult (const quat<T>& q) const
00107 {
00108   return quat( w*q.x + q.w*x + y*q.z - q.y*z,
00109                     w*q.y + q.w*y + z*q.x - q.z*x,
00110                     w*q.z + q.w*z + x*q.y - q.x*y,
00111                     w*q.w - x*q.x - y*q.y - z*q.z);
00112 }
00113 
00114 template <class T>
00115 quat<T>
00116 quat<T>::conj () const
00117 {
00118   return quat(-x, -y, -z, w);
00119 }
00120 
00121 template <class T>
00122 quat<T>
00123 quat<T>::inv () const
00124 {
00125   T n = 1/(w*w + x*x + y*y + z*z);
00126   return quat(-x*n, -y*n, -z*n, w*n);
00127 }
00128 
00129 template <class T>
00130 vec3<T>
00131 quat<T>::rot (const vec3<T>& v) const
00132 {
00133   // calculate tmp = q*v
00134   quat tmp(w*v.x + y*v.z - v.y*z,
00135            w*v.y + z*v.x - v.z*x,
00136            w*v.z + x*v.y - v.x*y,
00137            - x*v.x - y*v.y - z*v.z);
00138   // final result is (q*v)*conj(q)
00139   return vec3<T>(- tmp.w*x + w*tmp.x - tmp.y*z + y*tmp.z,
00140                  - tmp.w*y + w*tmp.y - tmp.z*x + z*tmp.x,
00141                  - tmp.w*z + w*tmp.z - tmp.x*y + x*tmp.y);
00142 }
00143 
00144 template <class T>
00145 quat<T>
00146 quat<T>::rot (const quat& r) const
00147 {
00148   // calculate tmp = q*r
00149   quat tmp(w*r.x + r.w*x + y*r.z - r.y*z,
00150            w*r.y + r.w*y + z*r.x - r.z*x,
00151            w*r.z + r.w*z + x*r.y - r.x*y,
00152            w*r.w - x*r.x - y*r.y - z*r.z);
00153   // final result is (q*r)*conj(q)
00154   return quat(- tmp.w*x + w*tmp.x - tmp.y*z + y*tmp.z,
00155               - tmp.w*y + w*tmp.y - tmp.z*x + z*tmp.x,
00156               - tmp.w*z + w*tmp.z - tmp.x*y + x*tmp.y,
00157               tmp.w*w + tmp.x*x + tmp.y*y + tmp.z*z);
00158 }
00159 
00160 template <class T>
00161 void
00162 quat<T>::set (const T phi, const vec3<T>& k)
00163 {
00164   vec3<T> axis = k;
00165   axis.normalize();
00166   T sphi = T(sin(phi*0.5));
00167   x = axis.x*sphi;
00168   y = axis.y*sphi;
00169   z = axis.z*sphi;
00170   w = T(cos(phi*0.5));
00171 }
00172 
00173 template <class T>
00174 void
00175 quat<T>::set (const mat3<T>& M)
00176 {
00177   T M11 = M.m[0];
00178   T M22 = M.m[4];
00179   T M33 = M.m[8];
00180   T M00 = M11 + M22 + M33;
00181   switch (maxi4<T>(M00, M11, M22, M33))
00182   {
00183     case 0:
00184     w = sqrt(1 + M00);
00185     x = (M.m[5] - M.m[7])/w;
00186     y = (M.m[6] - M.m[2])/w;
00187     z = (M.m[1] - M.m[3])/w;
00188     break;
00189     case 1:
00190     x = sqrt(1 + 2*M11 - M00);
00191     w = (M.m[5] - M.m[7])/x;
00192     y = (M.m[1] + M.m[3])/x;
00193     z = (M.m[2] + M.m[6])/x;
00194     break;
00195     case 2:
00196     y = sqrt(1 + 2*M22 - M00);
00197     w = (M.m[6] - M.m[2])/y;
00198     x = (M.m[1] + M.m[3])/y;
00199     z = (M.m[5] + M.m[7])/y;
00200     break;
00201     case 3:
00202     z = sqrt(1 + 2*M33 - M00);
00203     w = (M.m[1] - M.m[3])/z;
00204     x = (M.m[6] + M.m[2])/z;
00205     y = (M.m[5] + M.m[7])/z;
00206     break;
00207   }
00208   x *= 0.5;
00209   y *= 0.5;
00210   z *= 0.5;
00211   w *= 0.5;
00212 }
00213 
00214 
00215 template <class T1, class T2>
00216 inline quat<T2>
00217 mm_cast(quat<T1> v)
00218 {
00219   return quat<T2>(v.x, v.y, v.z, v.w);
00220 }
00221 
00222 } // namespace ve
00223 
00224 #endif // quat_h
00225 

Send questions, comments, and bug reports to:
jmk