quaternion.h
1 /*
2 ** ClanLib SDK
3 ** Copyright (c) 1997-2013 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 
30 #pragma once
31 
32 #include "../api_core.h"
33 
34 #include "vec3.h"
35 #include "angle.h"
36 
37 namespace clan
38 {
41 
45 template<typename Type>
46 class Quaternionx
47 {
48 public:
50  Type w;
51 
53  union { Type i; Type x; };
54  union { Type j; Type y; };
55  union { Type k; Type z; };
56 
57  Quaternionx() : w(1), i(0), j(0), k(0) { }
58  explicit Quaternionx(Type real, Type i, Type j, Type k) : w(real), i(i), j(j), k(k) { }
59  explicit Quaternionx(Type real, const Vec3<Type> &imag) : w(real), i(imag.x), j(imag.y), k(imag.z) { }
60  Quaternionx(const Quaternionx<Type> &copy) : w(copy.w), i(copy.i), j(copy.j), k(copy.k) { }
61  explicit Quaternionx(Type euler_x, Type euler_y, Type euler_z, AngleUnit unit, EulerOrder order);
62  explicit Quaternionx(const Vec3<Type> &euler, AngleUnit unit, EulerOrder order);
63  explicit Quaternionx(const Angle &euler_x, const Angle &euler_y, const Angle &euler_z, EulerOrder order);
64  explicit Quaternionx(const Mat4<Type> &rotation_matrix);
65 
66  static Quaternionx<Type> axis_angle(const Angle &angle, const Vec3f &axis);
67  static Quaternionx<Type> multiply(const Quaternionx<Type> &quaternion_1, const Quaternionx<Type> &quaternion_2);
68 
71 
74 
80  static Quaternionx<Type> lerp(const Quaternionx<Type> &quaternion_initial, const Quaternionx<Type> &quaternion_final, Type lerp_time);
81 
87  static Quaternionx<Type> slerp(const Quaternionx<Type> &quaternion_initial, const Quaternionx<Type> &quaternion_final, Type slerp_time);
88 
91 public:
95  Mat4<Type> to_matrix() const;
96 
98  Type magnitude() const;
99 
103 public:
104  void set(Type euler_x, Type euler_y, Type euler_z, AngleUnit unit, EulerOrder order);
105  void set(const Vec3<Type> &euler, AngleUnit unit, EulerOrder order);
106  void set(const Angle &euler_x, const Angle &euler_y, const Angle &euler_z, EulerOrder order);
107 
108  Quaternionx<Type> &rotate(const Angle &angle, const Vec3f &axis);
109 
110  Quaternionx<Type> &rotate(const Angle &euler_x, const Angle &euler_y, const Angle &euler_z, EulerOrder order);
111 
116 
123 
129  Vec3<Type> rotate_vector(const Vec3<Type> &v) const;
130 
131  Vec4<Type> rotate_vector(const Vec4<Type> &v) const;
132 
136  static Quaternionx<Type> normalize(Quaternionx<Type> q) { return q.normalize(); }
137 
143  static Quaternionx<Type> inverse(Quaternionx<Type> q) { return q.inverse(); }
144 
148 public:
150  Quaternionx<Type> operator *(const Quaternionx<Type> &mult) const { return Quaternionx<Type>::multiply(*this, mult); }
151 
152  Quaternionx<Type> operator *(const Mat4<Type> &matrix) const;
153 
155  bool operator<(const Quaternionx<Type> &other) const
156  {
157  if (x != other.x) return x < other.x;
158  else if (y != other.y) return y < other.y;
159  else if (z != other.z) return z < other.z;
160  else return w < other.w;
161  }
162 
164  bool operator>(const Quaternionx<Type> &other) const
165  {
166  if (x != other.x) return x > other.x;
167  else if (y != other.y) return y > other.y;
168  else if (z != other.z) return z > other.z;
169  else return w > other.w;
170  }
171 
173  bool operator<=(const Quaternionx<Type> &other) const { return *this < other || *this == other; }
174 
176  bool operator>=(const Quaternionx<Type> &other) const { return *this > other || *this == other; }
177 
179  bool operator==(const Quaternionx<Type> &other) const { return x == other.x && y == other.y && z == other.z && w == other.w; }
180 
182  bool operator!=(const Quaternionx<Type> &other) const { return x != other.x || y != other.y || z != other.z || w == other.w; }
183 
185 };
186 
188 class Quaternionf : public Quaternionx<float>
189 {
190 public:
191  Quaternionf() : Quaternionx<float>() { }
192  Quaternionf(const Quaternionx<float> &copy) : Quaternionx<float>(copy) { }
193  explicit Quaternionf(const Mat4<float> &rotation_matrix) : Quaternionx<float>(rotation_matrix) { };
194 
195  explicit Quaternionf(float real, float i, float j, float k) : Quaternionx<float>(real, i, j, k) { }
196  explicit Quaternionf(float real, const Vec3<float> &imag) : Quaternionx<float>(real, imag) { }
197  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) { }
198  explicit Quaternionf(const Vec3<float> &euler, AngleUnit unit, EulerOrder order) : Quaternionx<float>(euler, unit, order) { }
199  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) { }
200 
201 };
202 
204 class Quaterniond : public Quaternionx<double>
205 {
206 public:
207  Quaterniond() : Quaternionx<double>() { }
208  Quaterniond(const Quaternionx<double> &copy) : Quaternionx<double>(copy) { }
209  explicit Quaterniond(const Mat4<double> &rotation_matrix) : Quaternionx<double>(rotation_matrix) { }
210  explicit Quaterniond(double real, double i, double j, double k) : Quaternionx<double>(real, i, j, k) { }
211  explicit Quaterniond(double real, const Vec3<double> &imag) : Quaternionx<double>(real, imag) { }
212  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) { }
213  explicit Quaterniond(const Vec3<double> &euler, AngleUnit unit, EulerOrder order) : Quaternionx<double>(euler, unit, order) { }
214  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) { }
215 };
216 
217 }
218 
Angle class.
Definition: angle.h:63
Quaterniond(const Vec3< double > &euler, AngleUnit unit, EulerOrder order)
Definition: quaternion.h:213
Quaternionf(float euler_x, float euler_y, float euler_z, AngleUnit unit, EulerOrder order)
Definition: quaternion.h:197
Quaternionx< Type > operator*(const Quaternionx< Type > &mult) const
Multiplication operator.
Definition: quaternion.h:150
Type w
The real scalar part.
Definition: quaternion.h:50
Quaternionx(Type real, const Vec3< Type > &imag)
Definition: quaternion.h:59
Quaternion - Double.
Definition: quaternion.h:204
Quaternionx< Type > & normalize()
Normalizes this quaternion.
Quaternionx< Type > & inverse()
Inverse this quaternion.
bool operator==(const Quaternionx< Type > &other) const
Equal operator.
Definition: quaternion.h:179
Quaternionx()
Definition: quaternion.h:57
static Quaternionx< Type > slerp(const Quaternionx< Type > &quaternion_initial, const Quaternionx< Type > &quaternion_final, Type slerp_time)
Spherical Quaternion Interpolation.
Quaternionf(const Mat4< float > &rotation_matrix)
Definition: quaternion.h:193
static Quaternionx< Type > normalize(Quaternionx< Type > q)
Normalizes this quaternion.
Definition: quaternion.h:136
Quaternionf()
Definition: quaternion.h:191
Type y
Definition: quaternion.h:54
Quaternionf(float real, const Vec3< float > &imag)
Definition: quaternion.h:196
Type z
Definition: quaternion.h:55
Quaternionf(const Angle &euler_x, const Angle &euler_y, const Angle &euler_z, EulerOrder order)
Definition: quaternion.h:199
Quaternionf(float real, float i, float j, float k)
Definition: quaternion.h:195
static Quaternionx< Type > lerp(const Quaternionx< Type > &quaternion_initial, const Quaternionx< Type > &quaternion_final, Type lerp_time)
Linear Quaternion Interpolation.
Quaterniond(double real, const Vec3< double > &imag)
Definition: quaternion.h:211
Quaterniond(double euler_x, double euler_y, double euler_z, AngleUnit unit, EulerOrder order)
Definition: quaternion.h:212
AngleUnit
Angle unit.
Definition: angle.h:44
Vec3< Type > rotate_vector(const Vec3< Type > &v) const
Rotates vector by this quaternion.
Quaternion.
Definition: mat4.h:71
static Quaternionx< Type > multiply(const Quaternionx< Type > &quaternion_1, const Quaternionx< Type > &quaternion_2)
bool operator>=(const Quaternionx< Type > &other) const
Greater equal operator.
Definition: quaternion.h:176
Quaternionx(Type real, Type i, Type j, Type k)
Definition: quaternion.h:58
Type x
Definition: quaternion.h:53
Quaterniond()
Definition: quaternion.h:207
static Quaternionx< Type > axis_angle(const Angle &angle, const Vec3f &axis)
Quaternion - Float.
Definition: quaternion.h:188
Quaternionx< Type > & rotate(const Angle &angle, const Vec3f &axis)
static Quaternionx< Type > inverse(Quaternionx< Type > q)
Inverse this quaternion.
Definition: quaternion.h:143
3D vector
Definition: line_ray.h:49
Mat4< Type > to_matrix() const
Convert the quaternion to a rotation matrix.
Quaternionf(const Vec3< float > &euler, AngleUnit unit, EulerOrder order)
Definition: quaternion.h:198
void set(Type euler_x, Type euler_y, Type euler_z, AngleUnit unit, EulerOrder order)
Quaternionf(const Quaternionx< float > &copy)
Definition: quaternion.h:192
static Quaternionx< Type > rotation_between(Vec3< Type > v0, Vec3< Type > v1)
Calculates the shortest arc quaternion between two vectors.
Quaternionx(const Quaternionx< Type > &copy)
Definition: quaternion.h:60
Type magnitude() const
Get the quaternion magnitude.
EulerOrder
Euler angle rotation order.
Definition: angle.h:51
Quaterniond(const Quaternionx< double > &copy)
Definition: quaternion.h:208
4D matrix
Definition: mat2.h:52
Quaterniond(const Angle &euler_x, const Angle &euler_y, const Angle &euler_z, EulerOrder order)
Definition: quaternion.h:214
Type j
Definition: quaternion.h:54
bool operator>(const Quaternionx< Type > &other) const
Greater operator.
Definition: quaternion.h:164
4D vector
Definition: size.h:48
Type i
Definition: quaternion.h:53
Quaterniond(const Mat4< double > &rotation_matrix)
Definition: quaternion.h:209
Type k
Definition: quaternion.h:55
Quaterniond(double real, double i, double j, double k)
Definition: quaternion.h:210
bool operator!=(const Quaternionx< Type > &other) const
Not equal operator.
Definition: quaternion.h:182