rtVTK  0.6.0
Quaternion.h
00001 
00002 #ifndef Quaternion_h
00003 #define Quaternion_h
00004 
00005 #include <Math/Math.h>
00006 
00007 namespace Math
00008 {
00012   class Quaternion
00013   {
00014   public:
00015     Quaternion(const MathF::Vector&);
00016     Quaternion(float, float, float);
00017     Quaternion(float);
00018     Quaternion(float, float, float, float);
00019     Quaternion(float, const MathF::Vector&);
00020     Quaternion();
00021 
00022     float s() const { return e[3]; }
00023     float x() const { return e[0]; }
00024     float y() const { return e[1]; }
00025     float z() const { return e[2]; }
00026 
00027     float  operator[](int i) const { return e[i]; }
00028     float& operator[](int i)       { return e[i]; }
00029 
00030     Quaternion conjugate() const;
00031     Quaternion inverse()   const;
00032     float      norm()      const;
00033 
00034     Quaternion operator+(const Quaternion&) const;
00035     Quaternion operator*(const Quaternion&) const;
00036 
00037     void encodeR(float, const MathF::Vector&);
00038     MathF::Vector rotateV(const MathF::Vector&) const;
00039 
00040     friend ostream& operator<<(ostream&, const Quaternion&);
00041 
00042   private:
00043     float e[4];
00044   };
00045 
00046   inline Quaternion::Quaternion(const MathF::Vector& v)
00047   {
00048     e[0] = v[0];
00049     e[1] = v[1];
00050     e[2] = v[2];
00051     e[3] = 0.f;
00052   }
00053 
00054   inline Quaternion::Quaternion(float x, float y, float z)
00055   {
00056     e[0] = x;
00057     e[1] = y;
00058     e[2] = z;
00059     e[3] = 0.f;
00060   }
00061 
00062   inline Quaternion::Quaternion(float s, const MathF::Vector& v)
00063   {
00064     e[0] = v[0];
00065     e[1] = v[1];
00066     e[2] = v[2];
00067     e[3] = s;
00068   }
00069 
00070   inline Quaternion::Quaternion(float s)
00071   {
00072     e[0] = 0.f;
00073     e[1] = 0.f;
00074     e[2] = 0.f;
00075     e[3] = s;
00076   }
00077 
00078   inline Quaternion::Quaternion(float s, float x, float y, float z)
00079   {
00080     e[0] = x;
00081     e[1] = y;
00082     e[2] = z;
00083     e[3] = s;
00084   }
00085 
00086   inline Quaternion::Quaternion()
00087   {
00088     e[0] = 0.f;
00089     e[1] = 0.f;
00090     e[2] = 0.f;
00091     e[3] = 0.f;
00092   }
00093 
00094   inline Quaternion Quaternion::conjugate() const
00095   {
00096     return Quaternion(e[3], -e[0], -e[1], -e[2]);
00097   }
00098 
00099   inline Quaternion Quaternion::inverse() const
00100   {
00101     return conjugate()*Quaternion(1.f/norm());
00102   }
00103 
00104   inline float Quaternion::norm() const
00105   {
00106     return e[3]*e[3] + e[0]*e[0] + e[1]*e[1] + e[2]*e[2];
00107   }
00108 
00109   inline Quaternion Quaternion::operator+(const Quaternion& q) const
00110   {
00111     return Quaternion(e[3] + q.e[3], e[0] + q.e[0], e[1] + q.e[1], e[2] + q.e[2]);
00112   }
00113 
00114   inline Quaternion Quaternion::operator*(const Quaternion& q) const
00115     // NOTE(dje) - to concatenate quaternion rotations, multiply the original
00116     //             rotation by the increment
00117   {
00118     const MathF::Vector v1(  e[0],   e[1],   e[2]);
00119     const MathF::Vector v2(q.e[0], q.e[1], q.e[2]);
00120 
00121     return Quaternion(e[3]*q.e[3] - Dot(v1, v2), e[3]*v2 + q.e[3]*v1 + Cross(v1, v2));
00122   }
00123 
00124   inline void Quaternion::encodeR(float theta, const MathF::Vector& axis)
00125   {
00126     theta /= 2;
00127     const MathF::Vector n = axis.normal();
00128     const float  sine     = Sin(theta);
00129 
00130     e[0] = sine*n[0];
00131     e[1] = sine*n[1];
00132     e[2] = sine*n[2];
00133     e[3] = Cos(theta);
00134   }
00135 
00136   inline MathF::Vector Quaternion::rotateV(const MathF::Vector& v) const
00137   {
00138     Quaternion q = inverse() * v * (*this);
00139     return MathF::Vector(q.x(), q.y(), q.z());
00140   }
00141 }
00142 
00143 #endif // Quaternion_h
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends