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) const;
00095 Quaternion operator/ (const Quaternion& rhs) const;
00097 Quaternion& operator*= (const Quaternion& rhs)
00098 {return *this = operator*(rhs);}
00100 Quaternion& operator/= (const Quaternion& rhs)
00101 {return *this = operator/(rhs);}
00102
00103
00104
00105
00107
00116 bool fromRotMatrix(const RotMatrix<3>& m);
00117
00119 Quaternion inverse() const;
00120
00122 Quaternion& rotate(const RotMatrix<3>&);
00123
00125 Quaternion& rotate(const Quaternion& q) {return operator*=(q);}
00126
00128 Quaternion& rotation(int axis, CoordType angle);
00130 Quaternion& rotation(const Vector<3>& axis, CoordType angle);
00132
00135 Quaternion& rotation(const Vector<3>& axis);
00136
00138 Quaternion& rotation(const Vector<3>& from, const Vector<3>& to);
00139
00140
00141 template<const int dim>
00142 friend Vector<3>& Vector<dim>::rotate(const Quaternion& q);
00143 template<const int dim>
00144 friend RotMatrix<3>& RotMatrix<dim>::fromQuaternion(const Quaternion& q,
00145 const bool not_flip);
00146
00148 CoordType scalar() const {return m_w;}
00150 const Vector<3>& vector() const {return m_vec;}
00151
00153 void normalize();
00155 unsigned age() const {return m_age;}
00156
00157 private:
00158 Quaternion(bool valid) : m_valid(valid), m_age(1) {}
00159 void checkNormalization() {if(m_age >= WFMATH_MAX_NORM_AGE && m_valid) normalize();}
00160 CoordType m_w;
00161 Vector<3> m_vec;
00162 bool m_valid;
00163 unsigned m_age;
00164 };
00165
00166 }
00167
00168 #endif // WFMATH_QUATERNION_H