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/const.h>
00030 #include <wfmath/vector.h>
00031 #include <wfmath/rotmatrix.h>
00032
00033 namespace WFMath {
00034
00036
00040 class Quaternion
00041 {
00042 public:
00044 Quaternion () : m_valid(false) {}
00046
00049 Quaternion (CoordType w_in, CoordType x_in, CoordType y_in, CoordType z_in);
00051 Quaternion (int axis, CoordType angle) {rotation(axis, angle);}
00053 Quaternion (const Vector<3>& axis, CoordType angle) {rotation(axis, angle);}
00055
00058 explicit Quaternion (const Vector<3>& axis) {rotation(axis);}
00060 Quaternion (const Quaternion& p) : m_w(p.m_w), m_vec(p.m_vec),
00061 m_valid(p.m_valid), m_age(p.m_age) {}
00063 explicit Quaternion (const AtlasInType& a) {fromAtlas(a);}
00064
00065 ~Quaternion() {}
00066
00067 friend std::ostream& operator<<(std::ostream& os, const Quaternion& p);
00068 friend std::istream& operator>>(std::istream& is, Quaternion& p);
00069
00071 AtlasOutType toAtlas() const;
00073 void fromAtlas(const AtlasInType& a);
00074
00075 Quaternion& operator= (const Quaternion& rhs)
00076 {m_w = rhs.m_w; m_vec = rhs.m_vec; m_valid = rhs.m_valid; m_age = rhs.m_age; return *this;}
00077
00078
00079
00080 bool isEqualTo(const Quaternion &q, double epsilon = WFMATH_EPSILON) const;
00081
00082 bool operator== (const Quaternion& rhs) const {return isEqualTo(rhs);}
00083 bool operator!= (const Quaternion& rhs) const {return !isEqualTo(rhs);}
00084
00085 bool isValid() const {return m_valid;}
00086
00088 Quaternion& identity() {m_w = 1; m_vec.zero(); m_valid = true; m_age = 0; return *this;}
00089
00090
00091
00093 Quaternion& operator*= (const Quaternion& rhs);
00095 Quaternion& operator/= (const Quaternion& rhs);
00097 Quaternion operator* (const Quaternion& rhs) const {
00098 Quaternion out(*this);
00099 out *= rhs;
00100 return out;
00101 }
00103 Quaternion operator/ (const Quaternion& rhs) const {
00104 Quaternion out(*this);
00105 out /= rhs;
00106 return out;
00107 }
00108
00109
00110
00111
00113
00122 bool fromRotMatrix(const RotMatrix<3>& m);
00123
00125 Quaternion inverse() const;
00126
00128 Quaternion& rotate(const RotMatrix<3>&);
00129
00131 Quaternion& rotate(const Quaternion& q) {return operator*=(q);}
00132
00134 Quaternion& rotation(int axis, CoordType angle);
00136 Quaternion& rotation(const Vector<3>& axis, CoordType angle);
00138
00141 Quaternion& rotation(const Vector<3>& axis);
00142
00144 Quaternion& rotation(const Vector<3>& from, const Vector<3>& to);
00145
00146
00147 template<const int dim>
00148 friend Vector<3>& Vector<dim>::rotate(const Quaternion& q);
00149 template<const int dim>
00150 friend RotMatrix<3>& RotMatrix<dim>::fromQuaternion(const Quaternion& q,
00151 const bool not_flip);
00152
00154 CoordType scalar() const {return m_w;}
00156 const Vector<3>& vector() const {return m_vec;}
00157
00159 void normalize();
00161 unsigned age() const {return m_age;}
00162
00163 private:
00164 Quaternion(bool valid) : m_valid(valid), m_age(1) {}
00165 void checkNormalization() {if(m_age >= WFMATH_MAX_NORM_AGE && m_valid) normalize();}
00166 CoordType m_w;
00167 Vector<3> m_vec;
00168 bool m_valid;
00169 unsigned m_age;
00170 };
00171
00172 }
00173
00174 #endif // WFMATH_QUATERNION_H