WFMath  0.3.12
quaternion.h
1 // quaternion.h (based on the Quaternion class from eris)
2 //
3 // The WorldForge Project
4 // Copyright (C) 2002 The WorldForge Project
5 //
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 2 of the License, or
9 // (at your option) any later version.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 //
20 // For information about WorldForge and its authors, please contact
21 // the Worldforge Web Site at http://www.worldforge.org.
22 //
23 
24 // Author: Ron Steinke
25 
26 #ifndef WFMATH_QUATERNION_H
27 #define WFMATH_QUATERNION_H
28 
29 #include <wfmath/vector.h>
30 #include <wfmath/rotmatrix.h>
31 
32 namespace WFMath {
33 
35 
40 {
41  public:
43  Quaternion () : m_w(0), m_vec(), m_valid(false), m_age(0) {}
45 
48  Quaternion (CoordType w_in, CoordType x_in, CoordType y_in, CoordType z_in);
50  Quaternion (int axis, CoordType angle) : m_w(0), m_vec(), m_valid(false),
51  m_age(0)
52  {rotation(axis, angle);}
54  Quaternion (const Vector<3>& axis, CoordType angle) : m_w(0), m_vec(),
55  m_valid(false),
56  m_age(0)
57  {rotation(axis, angle);}
59 
62  explicit Quaternion (const Vector<3>& axis) : m_w(0), m_vec(),
63  m_valid(false), m_age(0)
64  {rotation(axis);} // angle == axis.mag()
66  Quaternion (const Quaternion& p) : m_w(p.m_w), m_vec(p.m_vec),
67  m_valid(p.m_valid), m_age(p.m_age) {}
69  explicit Quaternion (const AtlasInType& a) : m_w(0), m_vec(),
70  m_valid(false), m_age(0)
71  {fromAtlas(a);}
72 
73  ~Quaternion() {}
74 
75  friend std::ostream& operator<<(std::ostream& os, const Quaternion& p);
76  friend std::istream& operator>>(std::istream& is, Quaternion& p);
77 
79  AtlasOutType toAtlas() const;
81  void fromAtlas(const AtlasInType& a);
82 
83  Quaternion& operator= (const Quaternion& rhs)
84  {m_w = rhs.m_w; m_vec = rhs.m_vec; m_valid = rhs.m_valid; m_age = rhs.m_age; return *this;}
85 
86  // This regards q and -1*q as equal, since they give the
87  // same RotMatrix<3>
88  bool isEqualTo(const Quaternion &q, double epsilon = WFMATH_EPSILON) const;
89 
90  bool operator== (const Quaternion& rhs) const {return isEqualTo(rhs);}
91  bool operator!= (const Quaternion& rhs) const {return !isEqualTo(rhs);}
92 
93  bool isValid() const {return m_valid;}
94 
96  Quaternion& identity() {m_w = 1; m_vec.zero(); m_valid = true; m_age = 0; return *this;} // Set to null rotation
97 
98  // Operators
99 
101  Quaternion& operator*= (const Quaternion& rhs);
103  Quaternion& operator/= (const Quaternion& rhs);
105  Quaternion operator* (const Quaternion& rhs) const {
106  Quaternion out(*this);
107  out *= rhs;
108  return out;
109  }
111  Quaternion operator/ (const Quaternion& rhs) const {
112  Quaternion out(*this);
113  out /= rhs;
114  return out;
115  }
116 
117  // Functions
118 
119  // Returns "not_flip", similar to RotMatrix<>.toEuler()
121 
130  bool fromRotMatrix(const RotMatrix<3>& m);
131 
133  Quaternion inverse() const;
134 
136  Quaternion& rotate(const RotMatrix<3>&);
137 
139  Quaternion& rotate(const Quaternion& q) {return operator*=(q);}
140 
142  Quaternion& rotation(int axis, CoordType angle);
144  Quaternion& rotation(const Vector<3>& axis, CoordType angle);
146 
149  Quaternion& rotation(const Vector<3>& axis); // angle == axis.mag()
150 
152  Quaternion& rotation(const Vector<3>& from, const Vector<3>& to);
153 
155  CoordType scalar() const {return m_w;}
157  const Vector<3>& vector() const {return m_vec;}
158 
160  void normalize();
162  unsigned age() const {return m_age;}
163 
164  private:
165  Quaternion(bool valid) : m_w(0), m_vec(), m_valid(valid), m_age(1) {}
166  void checkNormalization() {if(m_age >= WFMATH_MAX_NORM_AGE && m_valid) normalize();}
167  CoordType m_w;
168  Vector<3> m_vec;
169  bool m_valid;
170  unsigned m_age;
171 };
172 
173 } // namespace WFMath
174 
175 #endif // WFMATH_QUATERNION_H