00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef WFMATH_QUATERNION_H
00027 #define WFMATH_QUATERNION_H
00028
00029 #include <wfmath/vector.h>
00030 #include <wfmath/rotmatrix.h>
00031
00032 namespace WFMath {
00033
00035 class Quaternion
00036 {
00037 public:
00038 class Identity {};
00040 Quaternion(const Identity &) : m_w(1), m_vec(), m_valid(true), m_age(0) {
00041 m_vec.zero();
00042 }
00044 Quaternion () : m_w(0), m_vec(), m_valid(false), m_age(0) {}
00046
00049 Quaternion (CoordType w_in, CoordType x_in, CoordType y_in, CoordType z_in);
00051 Quaternion (int axis, CoordType angle) : m_w(0), m_vec(), m_valid(false),
00052 m_age(0)
00053 {rotation(axis, angle);}
00055 Quaternion (const Vector<3>& axis, CoordType angle) : m_w(0), m_vec(),
00056 m_valid(false),
00057 m_age(0)
00058 {rotation(axis, angle);}
00060
00063 explicit Quaternion (const Vector<3>& axis) : m_w(0), m_vec(),
00064 m_valid(false), m_age(0)
00065 {rotation(axis);}
00067 Quaternion (const Quaternion& p) : m_w(p.m_w), m_vec(p.m_vec),
00068 m_valid(p.m_valid), m_age(p.m_age) {}
00070 explicit Quaternion (const AtlasInType& a) : m_w(0), m_vec(),
00071 m_valid(false), m_age(0)
00072 {fromAtlas(a);}
00073
00074 ~Quaternion() {}
00075
00076 friend std::ostream& operator<<(std::ostream& os, const Quaternion& p);
00077 friend std::istream& operator>>(std::istream& is, Quaternion& p);
00078
00080 AtlasOutType toAtlas() const;
00082 void fromAtlas(const AtlasInType& a);
00083
00084 Quaternion& operator= (const Quaternion& rhs)
00085 {m_w = rhs.m_w; m_vec = rhs.m_vec; m_valid = rhs.m_valid; m_age = rhs.m_age; return *this;}
00086
00087
00088
00089 bool isEqualTo(const Quaternion &q, CoordType epsilon = numeric_constants<CoordType>::epsilon()) const;
00090
00091 bool operator== (const Quaternion& rhs) const {return isEqualTo(rhs);}
00092 bool operator!= (const Quaternion& rhs) const {return !isEqualTo(rhs);}
00093
00094 bool isValid() const {return m_valid;}
00095
00097 Quaternion& identity() {m_w = 1; m_vec.zero(); m_valid = true; m_age = 0; return *this;}
00098
00099
00100
00102 Quaternion& operator*= (const Quaternion& rhs);
00104 Quaternion& operator/= (const Quaternion& rhs);
00106 Quaternion operator* (const Quaternion& rhs) const {
00107 Quaternion out(*this);
00108 out *= rhs;
00109 return out;
00110 }
00112 Quaternion operator/ (const Quaternion& rhs) const {
00113 Quaternion out(*this);
00114 out /= rhs;
00115 return out;
00116 }
00117
00118
00119
00120
00122
00131 bool fromRotMatrix(const RotMatrix<3>& m);
00132
00134 Quaternion inverse() const;
00135
00137 Quaternion& rotate(const RotMatrix<3>&);
00138
00140 Quaternion& rotate(const Quaternion& q) {return operator*=(q);}
00141
00143 Quaternion& rotation(int axis, CoordType angle);
00145 Quaternion& rotation(const Vector<3>& axis, CoordType angle);
00147
00150 Quaternion& rotation(const Vector<3>& axis);
00151
00153 Quaternion& rotation(const Vector<3>& from, const Vector<3>& to);
00154
00156 CoordType scalar() const {return m_w;}
00158 const Vector<3>& vector() const {return m_vec;}
00159
00161 void normalize();
00163 unsigned age() const {return m_age;}
00164
00165 private:
00166 Quaternion(bool valid) : m_w(0), m_vec(), m_valid(valid), m_age(1) {}
00167 void checkNormalization() {if(m_age >= WFMATH_MAX_NORM_AGE && m_valid) normalize();}
00168 CoordType m_w;
00169 Vector<3> m_vec;
00170 bool m_valid;
00171 unsigned m_age;
00172 };
00173
00174 }
00175
00176 #endif // WFMATH_QUATERNION_H