quaternion.h
1 /*
2 ** ClanLib SDK
3 ** Copyright (c) 1997-2016 The ClanLib Team
4 **
5 ** This software is provided 'as-is', without any express or implied
6 ** warranty. In no event will the authors be held liable for any damages
7 ** arising from the use of this software.
8 **
9 ** Permission is granted to anyone to use this software for any purpose,
10 ** including commercial applications, and to alter it and redistribute it
11 ** freely, subject to the following restrictions:
12 **
13 ** 1. The origin of this software must not be misrepresented; you must not
14 ** claim that you wrote the original software. If you use this software
15 ** in a product, an acknowledgment in the product documentation would be
16 ** appreciated but is not required.
17 ** 2. Altered source versions must be plainly marked as such, and must not be
18 ** misrepresented as being the original software.
19 ** 3. This notice may not be removed or altered from any source distribution.
20 **
21 ** Note: Some of the libraries ClanLib may link to may have additional
22 ** requirements or restrictions.
23 **
24 ** File Author(s):
25 **
26 ** Mark Page
27 */
28 
29 #pragma once
30 
31 #include "vec3.h"
32 #include "angle.h"
33 
34 namespace clan
35 {
38 
42  template<typename Type>
43  class Quaternionx
44  {
45  public:
47  Type w;
48 
50  union { Type i; Type x; };
51  union { Type j; Type y; };
52  union { Type k; Type z; };
53 
54  Quaternionx() : w(1), i(0), j(0), k(0) { }
55  explicit Quaternionx(Type real, Type i, Type j, Type k) : w(real), i(i), j(j), k(k) { }
56  explicit Quaternionx(Type real, const Vec3<Type> &imag) : w(real), i(imag.x), j(imag.y), k(imag.z) { }
57  Quaternionx(const Quaternionx<Type> &copy) : w(copy.w), i(copy.i), j(copy.j), k(copy.k) { }
58  explicit Quaternionx(Type euler_x, Type euler_y, Type euler_z, AngleUnit unit, EulerOrder order);
59  explicit Quaternionx(const Vec3<Type> &euler, AngleUnit unit, EulerOrder order);
60  explicit Quaternionx(const Angle &euler_x, const Angle &euler_y, const Angle &euler_z, EulerOrder order);
61  explicit Quaternionx(const Mat4<Type> &rotation_matrix);
62 
63  static Quaternionx<Type> axis_angle(const Angle &angle, const Vec3f &axis);
64  static Quaternionx<Type> multiply(const Quaternionx<Type> &quaternion_1, const Quaternionx<Type> &quaternion_2);
65 
68 
71 
77  static Quaternionx<Type> lerp(const Quaternionx<Type> &quaternion_initial, const Quaternionx<Type> &quaternion_final, Type lerp_time);
78 
84  static Quaternionx<Type> slerp(const Quaternionx<Type> &quaternion_initial, const Quaternionx<Type> &quaternion_final, Type slerp_time);
85 
89  Mat4<Type> to_matrix() const;
90 
92  Type magnitude() const;
93 
94  void set(Type euler_x, Type euler_y, Type euler_z, AngleUnit unit, EulerOrder order);
95  void set(const Vec3<Type> &euler, AngleUnit unit, EulerOrder order);
96  void set(const Angle &euler_x, const Angle &euler_y, const Angle &euler_z, EulerOrder order);
97 
98  Quaternionx<Type> &rotate(const Angle &angle, const Vec3f &axis);
99 
100  Quaternionx<Type> &rotate(const Angle &euler_x, const Angle &euler_y, const Angle &euler_z, EulerOrder order);
101 
106 
113 
119  Vec3<Type> rotate_vector(const Vec3<Type> &v) const;
120 
121  Vec4<Type> rotate_vector(const Vec4<Type> &v) const;
122 
126  static Quaternionx<Type> normalize(Quaternionx<Type> q) { return q.normalize(); }
127 
133  static Quaternionx<Type> inverse(Quaternionx<Type> q) { return q.inverse(); }
134 
136  Quaternionx<Type> operator *(const Quaternionx<Type> &mult) const { return Quaternionx<Type>::multiply(*this, mult); }
137 
138  Quaternionx<Type> operator *(const Mat4<Type> &matrix) const;
139 
141  bool operator<(const Quaternionx<Type> &other) const
142  {
143  if (x != other.x) return x < other.x;
144  else if (y != other.y) return y < other.y;
145  else if (z != other.z) return z < other.z;
146  else return w < other.w;
147  }
148 
150  bool operator>(const Quaternionx<Type> &other) const
151  {
152  if (x != other.x) return x > other.x;
153  else if (y != other.y) return y > other.y;
154  else if (z != other.z) return z > other.z;
155  else return w > other.w;
156  }
157 
159  bool operator<=(const Quaternionx<Type> &other) const { return *this < other || *this == other; }
160 
162  bool operator>=(const Quaternionx<Type> &other) const { return *this > other || *this == other; }
163 
165  bool operator==(const Quaternionx<Type> &other) const { return x == other.x && y == other.y && z == other.z && w == other.w; }
166 
168  bool operator!=(const Quaternionx<Type> &other) const { return x != other.x || y != other.y || z != other.z || w == other.w; }
169  };
170 
172  class Quaternionf : public Quaternionx<float>
173  {
174  public:
175  Quaternionf() : Quaternionx<float>() { }
176  Quaternionf(const Quaternionx<float> &copy) : Quaternionx<float>(copy) { }
177  explicit Quaternionf(const Mat4<float> &rotation_matrix) : Quaternionx<float>(rotation_matrix) { };
178 
179  explicit Quaternionf(float real, float i, float j, float k) : Quaternionx<float>(real, i, j, k) { }
180  explicit Quaternionf(float real, const Vec3<float> &imag) : Quaternionx<float>(real, imag) { }
181  explicit Quaternionf(float euler_x, float euler_y, float euler_z, AngleUnit unit, EulerOrder order) : Quaternionx<float>(euler_x, euler_y, euler_z, unit, order) { }
182  explicit Quaternionf(const Vec3<float> &euler, AngleUnit unit, EulerOrder order) : Quaternionx<float>(euler, unit, order) { }
183  explicit Quaternionf(const Angle &euler_x, const Angle &euler_y, const Angle &euler_z, EulerOrder order) : Quaternionx<float>(euler_x, euler_y, euler_z, order) { }
184 
185  };
186 
188  class Quaterniond : public Quaternionx<double>
189  {
190  public:
191  Quaterniond() : Quaternionx<double>() { }
192  Quaterniond(const Quaternionx<double> &copy) : Quaternionx<double>(copy) { }
193  explicit Quaterniond(const Mat4<double> &rotation_matrix) : Quaternionx<double>(rotation_matrix) { }
194  explicit Quaterniond(double real, double i, double j, double k) : Quaternionx<double>(real, i, j, k) { }
195  explicit Quaterniond(double real, const Vec3<double> &imag) : Quaternionx<double>(real, imag) { }
196  explicit Quaterniond(double euler_x, double euler_y, double euler_z, AngleUnit unit, EulerOrder order) : Quaternionx<double>(euler_x, euler_y, euler_z, unit, order) { }
197  explicit Quaterniond(const Vec3<double> &euler, AngleUnit unit, EulerOrder order) : Quaternionx<double>(euler, unit, order) { }
198  explicit Quaterniond(const Angle &euler_x, const Angle &euler_y, const Angle &euler_z, EulerOrder order) : Quaternionx<double>(euler_x, euler_y, euler_z, order) { }
199  };
200 
202 }
Quaterniond(double real, const Vec3< double > &imag)
Definition: quaternion.h:195
static Quaternionx< Type > normalize(Quaternionx< Type > q)
Normalizes this quaternion.
Definition: quaternion.h:126
Quaternionf(float real, float i, float j, float k)
Definition: quaternion.h:179
static Quaternionx< Type > rotation_between(Vec3< Type > v0, Vec3< Type > v1)
Calculates the shortest arc quaternion between two vectors.
Definition: clanapp.h:35
bool operator!=(const Quaternionx< Type > &other) const
Not equal operator.
Definition: quaternion.h:168
Quaternionf(const Mat4< float > &rotation_matrix)
Definition: quaternion.h:177
Angle class.
Definition: angle.h:59
Quaterniond(double euler_x, double euler_y, double euler_z, AngleUnit unit, EulerOrder order)
Definition: quaternion.h:196
4D vector
Definition: size.h:47
Quaternion.
Definition: mat4.h:69
Quaterniond(const Angle &euler_x, const Angle &euler_y, const Angle &euler_z, EulerOrder order)
Definition: quaternion.h:198
Type z
Definition: quaternion.h:52
Quaterniond(const Quaternionx< double > &copy)
Definition: quaternion.h:192
Quaternion - Double.
Definition: quaternion.h:188
Type i
Definition: quaternion.h:50
Quaternionf(float real, const Vec3< float > &imag)
Definition: quaternion.h:180
bool operator>=(const Quaternionx< Type > &other) const
Greater equal operator.
Definition: quaternion.h:162
Quaternionx< Type > operator*(const Quaternionx< Type > &mult) const
Multiplication operator.
Definition: quaternion.h:136
static Quaternionx< Type > multiply(const Quaternionx< Type > &quaternion_1, const Quaternionx< Type > &quaternion_2)
Type x
Definition: quaternion.h:50
Type w
The real scalar part.
Definition: quaternion.h:47
Type k
Definition: quaternion.h:52
Quaternionx< Type > & inverse()
Inverse this quaternion.
Quaternionx(const Quaternionx< Type > &copy)
Definition: quaternion.h:57
4D matrix
Definition: mat2.h:50
bool operator==(const Quaternionx< Type > &other) const
Equal operator.
Definition: quaternion.h:165
AngleUnit
Angle unit.
Definition: angle.h:41
Quaternionf(float euler_x, float euler_y, float euler_z, AngleUnit unit, EulerOrder order)
Definition: quaternion.h:181
static Quaternionx< Type > slerp(const Quaternionx< Type > &quaternion_initial, const Quaternionx< Type > &quaternion_final, Type slerp_time)
Spherical Quaternion Interpolation.
static Quaternionx< Type > axis_angle(const Angle &angle, const Vec3f &axis)
bool operator>(const Quaternionx< Type > &other) const
Greater operator.
Definition: quaternion.h:150
Quaterniond(const Mat4< double > &rotation_matrix)
Definition: quaternion.h:193
Quaternion - Float.
Definition: quaternion.h:172
Quaternionx(Type real, Type i, Type j, Type k)
Definition: quaternion.h:55
Quaternionx< Type > & normalize()
Normalizes this quaternion.
static Quaternionx< Type > inverse(Quaternionx< Type > q)
Inverse this quaternion.
Definition: quaternion.h:133
Quaternionf(const Quaternionx< float > &copy)
Definition: quaternion.h:176
Quaternionf(const Angle &euler_x, const Angle &euler_y, const Angle &euler_z, EulerOrder order)
Definition: quaternion.h:183
Type j
Definition: quaternion.h:51
Quaternionx< Type > & rotate(const Angle &angle, const Vec3f &axis)
EulerOrder
Euler angle rotation order.
Definition: angle.h:48
Quaternionf(const Vec3< float > &euler, AngleUnit unit, EulerOrder order)
Definition: quaternion.h:182
void set(Type euler_x, Type euler_y, Type euler_z, AngleUnit unit, EulerOrder order)
Quaternionx(Type real, const Vec3< Type > &imag)
Definition: quaternion.h:56
Mat4< Type > to_matrix() const
Convert the quaternion to a rotation matrix.
static Quaternionx< Type > lerp(const Quaternionx< Type > &quaternion_initial, const Quaternionx< Type > &quaternion_final, Type lerp_time)
Linear Quaternion Interpolation.
Quaterniond()
Definition: quaternion.h:191
Quaternionf()
Definition: quaternion.h:175
3D vector
Definition: line_ray.h:46
Quaterniond(double real, double i, double j, double k)
Definition: quaternion.h:194
Quaternionx()
Definition: quaternion.h:54
Quaterniond(const Vec3< double > &euler, AngleUnit unit, EulerOrder order)
Definition: quaternion.h:197
Type magnitude() const
Get the quaternion magnitude.
Type y
Definition: quaternion.h:51
Vec3< Type > rotate_vector(const Vec3< Type > &v) const
Rotates vector by this quaternion.