![]() |
rtVTK
0.6.0
|
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