TDME2 1.9.121
Quaternion.h
Go to the documentation of this file.
1#pragma once
2
3#include <array>
4
5#include <tdme/tdme.h>
7#include <tdme/math/Math.h>
9#include <tdme/math/Vector3.h>
10
11using std::array;
12
16
17/**
18 * Quaternion class
19 * @author Andreas Drewke
20 */
22{
23// see http://db-in.com/blog/2011/04/cameras-on-opengl-es-2-x/
24private:
25 array<float, 4> data;
26
27public:
28 /**
29 * Public constructor
30 * @param q quaternion
31 */
32 inline Quaternion(const Quaternion& q) {
33 data = q.data;
34 }
35
36 /**
37 * Public constructor
38 * @param x x
39 * @param y y
40 * @param z z
41 * @param w w
42 */
43 inline Quaternion(float x, float y, float z, float w) {
44 data[0] = x;
45 data[1] = y;
46 data[2] = z;
47 data[3] = w;
48 }
49
50 /**
51 * Public constructor
52 * @param v vector
53 * @param w w
54 */
55 inline Quaternion(const Vector3& v, float w) {
56 data[0] = v.data[0];
57 data[1] = v.data[1];
58 data[2] = v.data[2];
59 data[3] = w;
60 }
61 /**
62 * Set up this quaternion by components
63 * @param x x
64 * @param y y
65 * @param z z
66 * @param w w
67 */
68 inline Quaternion& set(float x, float y, float z, float w) {
69 data[0] = x;
70 data[1] = y;
71 data[2] = z;
72 data[3] = w;
73 return *this;
74 }
75
76 /**
77 * Sets up this quaternion by quaternion q
78 * @param q q
79 * @return
80 */
81 inline Quaternion& set(const Quaternion& q) {
82 data = q.data;
83 return *this;
84 }
85
86 /**
87 * Set quaternion
88 * @param v vector
89 * @param w w
90 */
91 inline Quaternion& set(const Vector3& v, float w) {
92 data[0] = v.data[0];
93 data[1] = v.data[1];
94 data[2] = v.data[2];
95 data[3] = w;
96 return *this;
97 }
98
99 /**
100 * @return x
101 */
102 inline float getX() const {
103 return data[0];
104 }
105
106 /**
107 * Set X
108 * @param x x
109 * @return this quaternion
110 */
111 inline Quaternion& setX(float x) {
112 data[0] = x;
113 return *this;
114 }
115
116 /**
117 * @return y
118 */
119 inline float getY() const {
120 return data[1];
121 }
122
123 /**
124 * Set Y
125 * @param y y
126 * @return this quaternion
127 */
128 inline Quaternion& setY(float y) {
129 data[1] = y;
130 return *this;
131 }
132
133 /**
134 * @return z
135 */
136 inline float getZ() const {
137 return data[2];
138 }
139
140 /**
141 * Set Z
142 * @param z z
143 * @return this quaternion
144 */
145 inline Quaternion& setZ(float z) {
146 data[2] = z;
147 return *this;
148 }
149
150 /**
151 * @return w
152 */
153 inline float getW() const {
154 return data[3];
155 }
156
157 /**
158 * Set W
159 * @param w w
160 * @return this quaternion
161 */
162 inline Quaternion& setW(float w) {
163 data[3] = w;
164 return *this;
165 }
166
167 /**
168 * Set up quaternion identity
169 * @return this quaternion
170 */
172 data[0] = 0.0f;
173 data[1] = 0.0f;
174 data[2] = 0.0f;
175 data[3] = 1.0f;
176 return *this;
177 }
178
179 /**
180 * Inverts this quaternion
181 * @return this quaternion
182 */
183 inline Quaternion& invert() {
184 data[0] *= -1.0f;
185 data[1] *= -1.0f;
186 data[2] *= -1.0f;
187 return *this;
188 }
189
190 /**
191 * Creates a rotation quaternion
192 * @param axis axis
193 * @param angle angle
194 * @return this quaternion
195 */
196 inline Quaternion& rotate(const Vector3& axis, float angle) {
197 // converts the angle in degrees to radians
198 auto radians = angle * 3.1415927f / 180.0f;
199 // finds the sin and cosin for the half angle
200 auto sin = Math::sin(radians * 0.5);
201 auto cos = Math::cos(radians * 0.5);
202 // formula to construct a new quaternion based on direction and angle
203 data[0] = axis.data[0] * sin;
204 data[1] = axis.data[1] * sin;
205 data[2] = axis.data[2] * sin;
206 data[3] = cos;
207 return *this;
208 }
209
210 /**
211 * Normalize quaternion
212 */
214 auto magnitude = Math::sqrt(data[0] * data[0] + data[1] * data[1] + data[2] * data[2] + data[3] * data[3]);
215 data[0] = data[0] / magnitude;
216 data[1] = data[1] / magnitude;
217 data[2] = data[2] / magnitude;
218 data[3] = data[3] / magnitude;
219 return *this;
220 }
221
222 /**
223 * Multiplies this quaternion with quaternion q
224 * @param q quaterion q
225 * @return this quaternion
226 */
227 inline Quaternion& multiply(const Quaternion q) {
228 array<float, 4> _data;
229 _data[0] = data[3] * q.data[0] + data[0] * q.data[3] + data[1] * q.data[2] - data[2] * q.data[1];
230 _data[1] = data[3] * q.data[1] - data[0] * q.data[2] + data[1] * q.data[3] + data[2] * q.data[0];
231 _data[2] = data[3] * q.data[2] + data[0] * q.data[1] - data[1] * q.data[0] + data[2] * q.data[3];
232 _data[3] = data[3] * q.data[3] - data[0] * q.data[0] - data[1] * q.data[1] - data[2] * q.data[2];
233 data = _data;
234 return *this;
235 }
236
237 /**
238 * Adds given quaternion q to this quaternion
239 * @param q quaterion q
240 * @return this quaternion
241 */
242 inline Quaternion& add(const Quaternion& q) {
243 data[0] += q.data[0];
244 data[1] += q.data[1];
245 data[2] += q.data[2];
246 data[3] += q.data[3];
247 return *this;
248 }
249
250 /**
251 * Subtracts given quaternion q from this quaternion
252 * @param q quaterion q
253 * @return this quaternion
254 */
255 inline Quaternion& sub(const Quaternion& q) {
256 data[0] -= q.data[0];
257 data[1] -= q.data[1];
258 data[2] -= q.data[2];
259 data[3] -= q.data[3];
260 return *this;
261 }
262
263 /**
264 * Scales this quaternion with given value
265 * @param value value
266 * @return this quaternion
267 */
268 inline Quaternion& scale(float value) {
269 data[0] *= value;
270 data[1] *= value;
271 data[2] *= value;
272 data[3] *= value;
273 return *this;
274 }
275
276 /**
277 * Multiplies a quaternion with given vector v
278 * @param v vector v
279 * @return resulting vector 3
280 */
281 inline Vector3 multiply(const Vector3& v) const {
282 // t = 2 * cross(q.xyz, v)
283 Vector3 q(data[0], data[1], data[2]);
284 auto t = Vector3::computeCrossProduct(q, v).scale(2.0f);
285 // v' = v + q.w * t + cross(q.xyz, t)
286 auto qxt = Vector3::computeCrossProduct(q, t);
287 //
288 Vector3 result;
289 result.set(v);
290 result.add(qxt);
291 result.add(t.scale(data[3]));
292 return result;
293 }
294
295 /**
296 * Computes a matrix from given
297 * @return resulting matrix
298 */
299 inline Matrix4x4 computeMatrix() const {
300 return Matrix4x4(
301 1.0f - 2.0f * (data[1] * data[1] + data[2] * data[2]),
302 2.0f * (data[0] * data[1] + data[2] * data[3]),
303 2.0f * (data[0] * data[2] - data[1] * data[3]),
304 0.0f,
305 2.0f * (data[0] * data[1] - data[2] * data[3]),
306 1.0f - 2.0f * (data[0] * data[0] + data[2] * data[2]),
307 2.0f * (data[2] * data[1] + data[0] * data[3]),
308 0.0f,
309 2.0f * (data[0] * data[2] + data[1] * data[3]),
310 2.0f * (data[1] * data[2] - data[0] * data[3]),
311 1.0f - 2.0f * (data[0] * data[0] + data[1] * data[1]),
312 0.0f,
313 0.0f,
314 0.0f,
315 0.0f,
316 1.0f
317 );
318 }
319
320 /**
321 * Returns array data
322 * @return array data
323 */
324 inline array<float, 4>& getArray() const {
325 return (array<float, 4>&)data;
326 }
327
328 /**
329 * Array access operator
330 * @param i index
331 * @return quaternion component
332 */
333 inline float& operator[](int i) {
334 return data[i];
335 }
336
337 /**
338 * Const array access operator
339 * @param i index
340 * @return quaternion component
341 */
342 inline const float& operator[](int i) const {
343 return data[i];
344 }
345
346 /**
347 * Operator +
348 * @param q quaternion to add
349 * @return new quaternion (this + q)
350 */
351 inline Quaternion operator +(const Quaternion& q) const {
352 auto r = this->clone().add(q);
353 return r;
354 }
355
356 /**
357 * Operator -
358 * @param q quaternion to subtrct
359 * @return new quaternion (this - q)
360 */
361 inline Quaternion operator -(const Quaternion& q) const {
362 auto r = this->clone().sub(q);
363 return r;
364 }
365
366 /**
367 * Operator * (float)
368 * @param f value to multiply by
369 * @return new quaternion (this * f)
370 */
371 inline Quaternion operator *(const float f) const {
372 auto r = this->clone().scale(f);
373 return r;
374 }
375
376 /**
377 * Operator * (Quaternion&)
378 * @param q quaternion to multiply by
379 * @return new quaternion (this * q)
380 */
381 inline Quaternion operator *(const Quaternion& q) const {
382 auto r = this->clone().multiply(q);
383 return r;
384 }
385
386 /**
387 * Operattor * (Vector&)
388 * @param v vector to multiply by
389 * @return new Vector ()thic * v
390 */
391 inline Vector3 operator *(const Vector3& v) const {
392 return this->multiply(v);
393 }
394
395 /**
396 * Operator / (f)
397 * @param q value to divide by
398 * @return new quaternion (this / f)
399 */
400 inline Quaternion operator /(const float f) const {
401 auto r = this->clone().scale(1.0f / f);
402 return r;
403 }
404
405 /**
406 * Operator / (Quaternion&)
407 * @param q quaternion to divide by
408 * @return new quaternion (this / q)
409 */
410 inline Quaternion operator /(const Quaternion& q) const {
411 auto qInverted = Quaternion(1.0f / q[0], 1.0f / q[1], 1.0f / q[2], 1.0f / q[3]);
412 auto r = this->clone().multiply(qInverted);
413 return r;
414 }
415
416 /**
417 * Operator +=
418 * @param q quaternion to add
419 * @return this quaternion added by q
420 */
422 return this->add(q);
423 }
424
425 /**
426 * Operator -=
427 * @param q quaternion to substract
428 * @return this quaternion substracted by q
429 */
431 return this->sub(q);
432 }
433
434 /**
435 * Operator *=
436 * @param q quaternion to multiply by
437 * @return this quaternion multiplied by q
438 */
440 return this->multiply(q);
441 }
442
443 /**
444 * Operator /=
445 * @param q quaternion to devide by
446 * @return this quaternion devided by q
447 */
449 auto qInverted = Quaternion(1.0f / q[0], 1.0f / q[1], 1.0f / q[2], 1.0f / q[3]);
450 return this->multiply(qInverted);
451 }
452
453 /**
454 * Equality comparison operator
455 * @param q quaternion to compare to
456 * @return equality
457 */
458
459 inline bool operator ==(const Quaternion& q) const {
460 return this->equals(q);
461 }
462
463 /**
464 * Non equality comparison operator
465 * @param q quaternion to compare to
466 * @return non equality
467 */
468
469 inline bool operator !=(const Quaternion& q) const {
470 return this->equals(q) == false;
471 }
472
473 /**
474 * Clones the quaternion
475 * @return new cloned vector
476 */
477 inline Quaternion clone() const {
478 return Quaternion(*this);
479 }
480
481 /**
482 * Compares this quaternion with given quaternion
483 * @param q quaternion q
484 * @return equality
485 */
486 inline bool equals(const Quaternion& q) const {
487 return equals(q, Math::EPSILON);
488 }
489
490 /**
491 * Compares this quaternion with given quaternion
492 * @param q quaternion q
493 * @param tolerance tolerance per component(x, y, z)
494 * @return equality
495 */
496 inline bool equals(const Quaternion& q, float tolerance) const {
497 return (this == &q) ||
498 (
499 Math::abs(data[0] - q.data[0]) < tolerance &&
500 Math::abs(data[1] - q.data[1]) < tolerance &&
501 Math::abs(data[2] - q.data[2]) < tolerance &&
502 Math::abs(data[3] - q.data[3]) < tolerance
503 );
504 }
505
506 /**
507 * Public constructor
508 */
509 inline Quaternion() {
510 data.fill(0.0f);
511 }
512
513};
Standard math functions.
Definition: Math.h:21
static float sqrt(float value)
Returns the square of given value.
Definition: Math.h:289
static float cos(float value)
Returns the cosine of an angle.
Definition: Math.h:165
static constexpr float EPSILON
Definition: Math.h:25
static int32_t abs(int32_t value)
Returns absolute value.
Definition: Math.h:91
static float sin(float value)
Returns the sine of an angle.
Definition: Math.h:280
4x4 3D Matrix class
Definition: Matrix4x4.h:24
Quaternion class.
Definition: Quaternion.h:22
Quaternion & rotate(const Vector3 &axis, float angle)
Creates a rotation quaternion.
Definition: Quaternion.h:196
Quaternion & setY(float y)
Set Y.
Definition: Quaternion.h:128
float getY() const
Definition: Quaternion.h:119
array< float, 4 > & getArray() const
Returns array data.
Definition: Quaternion.h:324
float getX() const
Definition: Quaternion.h:102
bool equals(const Quaternion &q, float tolerance) const
Compares this quaternion with given quaternion.
Definition: Quaternion.h:496
Quaternion & setZ(float z)
Set Z.
Definition: Quaternion.h:145
bool equals(const Quaternion &q) const
Compares this quaternion with given quaternion.
Definition: Quaternion.h:486
Quaternion(const Vector3 &v, float w)
Public constructor.
Definition: Quaternion.h:55
float getZ() const
Definition: Quaternion.h:136
Quaternion operator+(const Quaternion &q) const
Operator +.
Definition: Quaternion.h:351
Quaternion & multiply(const Quaternion q)
Multiplies this quaternion with quaternion q.
Definition: Quaternion.h:227
Quaternion operator*(const float f) const
Operator * (float)
Definition: Quaternion.h:371
Matrix4x4 computeMatrix() const
Computes a matrix from given.
Definition: Quaternion.h:299
Quaternion(float x, float y, float z, float w)
Public constructor.
Definition: Quaternion.h:43
Quaternion operator-(const Quaternion &q) const
Operator -.
Definition: Quaternion.h:361
Quaternion()
Public constructor.
Definition: Quaternion.h:509
Quaternion & identity()
Set up quaternion identity.
Definition: Quaternion.h:171
Quaternion & set(const Vector3 &v, float w)
Set quaternion.
Definition: Quaternion.h:91
Quaternion & operator/=(Quaternion &q)
Operator /=.
Definition: Quaternion.h:448
Quaternion & set(float x, float y, float z, float w)
Set up this quaternion by components.
Definition: Quaternion.h:68
Quaternion & operator*=(Quaternion &q)
Operator *=.
Definition: Quaternion.h:439
Quaternion & invert()
Inverts this quaternion.
Definition: Quaternion.h:183
Quaternion operator/(const float f) const
Operator / (f)
Definition: Quaternion.h:400
float getW() const
Definition: Quaternion.h:153
Quaternion & operator+=(const Quaternion &q)
Operator +=.
Definition: Quaternion.h:421
Quaternion(const Quaternion &q)
Public constructor.
Definition: Quaternion.h:32
const float & operator[](int i) const
Const array access operator.
Definition: Quaternion.h:342
bool operator!=(const Quaternion &q) const
Non equality comparison operator.
Definition: Quaternion.h:469
Quaternion & setW(float w)
Set W.
Definition: Quaternion.h:162
float & operator[](int i)
Array access operator.
Definition: Quaternion.h:333
Quaternion & set(const Quaternion &q)
Sets up this quaternion by quaternion q.
Definition: Quaternion.h:81
Quaternion & operator-=(Quaternion &q)
Operator -=.
Definition: Quaternion.h:430
Quaternion & setX(float x)
Set X.
Definition: Quaternion.h:111
array< float, 4 > data
Definition: Quaternion.h:25
Quaternion & normalize()
Normalize quaternion.
Definition: Quaternion.h:213
Quaternion clone() const
Clones the quaternion.
Definition: Quaternion.h:477
Quaternion & scale(float value)
Scales this quaternion with given value.
Definition: Quaternion.h:268
bool operator==(const Quaternion &q) const
Equality comparison operator.
Definition: Quaternion.h:459
Vector3 multiply(const Vector3 &v) const
Multiplies a quaternion with given vector v.
Definition: Quaternion.h:281
Quaternion & sub(const Quaternion &q)
Subtracts given quaternion q from this quaternion.
Definition: Quaternion.h:255
Quaternion & add(const Quaternion &q)
Adds given quaternion q to this quaternion.
Definition: Quaternion.h:242
3D vector 3 class
Definition: Vector3.h:22
Vector3 & set(float x, float y, float z)
Set up vector.
Definition: Vector3.h:73
Vector3 & add(const Vector3 &v)
Adds a vector.
Definition: Vector3.h:301
array< float, 3 > data
Definition: Vector3.h:28
static Vector3 computeCrossProduct(const Vector3 &v1, const Vector3 &v2)
Compute the cross product of vector v1 and v2.
Definition: Vector3.h:181
Vector3 & scale(float scale)
Scale this vector.
Definition: Vector3.h:349