ProtoTracer  1.0
Real-time 3D rendering and animation engine
Loading...
Searching...
No Matches
Quaternion.h
Go to the documentation of this file.
1/**
2 * @file Quaternion.h
3 * @brief Defines the Quaternion class for 3D rotations and transformations.
4 *
5 * This header provides a Quaternion class that supports various quaternion operations
6 * (addition, multiplication, division, interpolation, etc.) as well as methods for
7 * rotating 2D and 3D vectors. Quaternions are commonly used for representing rotations
8 * in 3D space without suffering from some of the limitations of Euler angles (e.g.,
9 * gimbal lock).
10 *
11 * @date 22/12/2024
12 * @version 1.0
13 * @author Coela Can't
14 */
15
16#pragma once
17
18#include "Mathematics.h"
19#include "Vector2D.h"
20#include "Vector3D.h"
21
22/**
23 * @class Quaternion
24 * @brief A mathematical construct representing a rotation in 3D space.
25 *
26 * Quaternions consist of a scalar part (W) and a vector part (X, Y, Z). They allow
27 * smooth interpolation (slerp), concatenation of rotations, and are often used to
28 * avoid gimbal lock problems that can occur when using Euler angles.
29 */
31public:
32 float W; ///< Scalar part of the quaternion.
33 float X; ///< X component of the quaternion's vector part.
34 float Y; ///< Y component of the quaternion's vector part.
35 float Z; ///< Z component of the quaternion's vector part.
36
37 /**
38 * @brief Default constructor. Initializes the quaternion to identity (1,0,0,0).
39 */
40 Quaternion();
41
42 /**
43 * @brief Copy constructor. Clones the values of another quaternion.
44 * @param quaternion The quaternion to copy from.
45 */
47
48 /**
49 * @brief Constructs a quaternion purely from a 3D vector (0, X, Y, Z).
50 * @param vector The vector that forms the (X, Y, Z) part of the quaternion.
51 *
52 * The W component is initialized to 0.0f.
53 */
55
56 /**
57 * @brief Constructs a quaternion with individual scalar and vector components.
58 * @param w Scalar (real) component.
59 * @param x X component of the vector part.
60 * @param y Y component of the vector part.
61 * @param z Z component of the vector part.
62 */
63 Quaternion(const float& w, const float& x, const float& y, const float& z);
64
65 /**
66 * @brief Rotates a 2D vector by this quaternion, projecting it in 2D.
67 *
68 * This method uses quaternion-based rotation to transform a 2D vector.
69 *
70 * Mathematical formulation:
71 *
72 * @f[
73 * s_2 = 2 \cdot w
74 * @f]
75 *
76 * @f[
77 * d_{PUV} = 2 \cdot (x \cdot v_x + y \cdot v_y)
78 * @f]
79 *
80 * @f[
81 * d_{PUU} = w^2 - (x^2 + y^2 + z^2)
82 * @f]
83 *
84 * The rotated vector is computed as:
85 *
86 * @f[
87 * v'_x = x \cdot d_{PUV} + v_x \cdot d_{PUU} + (-z \cdot v_y) \cdot s_2
88 * @f]
89 *
90 * @f[
91 * v'_y = y \cdot d_{PUV} + v_y \cdot d_{PUU} + (z \cdot v_x) \cdot s_2
92 * @f]
93 *
94 * Resulting in:
95 *
96 * @f[
97 * \vec{v'} = (v'_x, v'_y)
98 * @f]
99 *
100 * @param v The 2D vector to rotate.
101 * @return A new 2D vector that has been rotated.
102 *
103 * @note If the quaternion is close to zero (no rotation), the input vector is returned unchanged.
104 */
105 Vector2D RotateVector(const Vector2D& v) const;
106
107 /**
108 * @brief Rotates a 2D vector by a unit quaternion (assumes normalized),
109 * allowing a different quaternion to be used if desired.
110 * @param v The 2D vector to rotate.
111 * @param q The (unit) quaternion to apply for the rotation.
112 * @return A new 2D vector that has been rotated using \p q.
113 */
114 Vector2D RotateVectorUnit(const Vector2D& v, const Quaternion& q) const;
115
116 /**
117 * @brief Applies the inverse of this quaternion's rotation to a 2D vector.
118 * @param coordinate The 2D vector to transform.
119 * @return The unrotated 2D vector.
120 */
122
123 /**
124 * @brief Rotates a 3D vector by this quaternion.
125 * @param v The 3D vector to rotate.
126 * @return A new 3D vector that has been rotated.
127 */
128 Vector3D RotateVector(const Vector3D& v) const;
129
130 /**
131 * @brief Applies the inverse of this quaternion's rotation to a 3D vector.
132 * @param coordinate The 3D vector to transform.
133 * @return The unrotated 3D vector.
134 */
136
137 /**
138 * @brief Retrieves the bi-vector (X, Y, Z) portion of the quaternion (with W=0).
139 * @return A 3D vector representing the (X, Y, Z) parts of this quaternion.
140 */
141 Vector3D GetBiVector() const;
142
143 /**
144 * @brief Retrieves the normal vector part of the quaternion, typically its axis of rotation.
145 * @return A 3D vector representing the axis (X, Y, Z).
146 */
147 Vector3D GetNormal() const;
148
149 /**
150 * @brief Performs spherical linear interpolation (slerp) between two quaternions.
151 * @param q1 The start quaternion.
152 * @param q2 The end quaternion.
153 * @param ratio A normalized value (0 to 1) indicating how far to interpolate from \p q1 to \p q2.
154 * @return A new quaternion representing the slerped result.
155 */
156 static Quaternion SphericalInterpolation(const Quaternion& q1, const Quaternion& q2, const float& ratio);
157
158 /**
159 * @brief Computes a small rotation quaternion given an angular velocity and time delta.
160 * @param angularVelocity A 3D vector representing the angular velocity (e.g., degrees/sec or radians/sec).
161 * @param timeDelta The time step.
162 * @return A new quaternion representing the rotation over the given time delta.
163 */
164 Quaternion DeltaRotation(const Vector3D& angularVelocity, const float& timeDelta) const;
165
166 /**
167 * @brief Adds two quaternions component-wise.
168 * @param quaternion The quaternion to add to the current one.
169 * @return A new quaternion representing the sum.
170 */
171 Quaternion Add(const Quaternion& quaternion) const;
172
173 /**
174 * @brief Subtracts a quaternion from this quaternion component-wise.
175 * @param quaternion The quaternion to subtract.
176 * @return A new quaternion representing the difference.
177 */
179
180 /**
181 * @brief Multiplies (composes) this quaternion with another (order matters).
182 * @param quaternion The right-hand side quaternion.
183 * @return The resulting quaternion from the multiplication.
184 */
186
187 /**
188 * @brief Scales this quaternion by a scalar factor.
189 * @param scalar The scalar to multiply.
190 * @return A new quaternion scaled by \p scalar.
191 */
192 Quaternion Multiply(const float& scalar) const;
193
194 /**
195 * @brief Divides this quaternion by another quaternion component-wise (not a typical quaternion operation).
196 * @param quaternion The quaternion to divide by.
197 * @return A new quaternion representing the component-wise result.
198 */
200
201 /**
202 * @brief Divides this quaternion by a scalar.
203 * @param scalar The scalar divisor.
204 * @return A new quaternion scaled by the reciprocal of \p scalar.
205 */
206 Quaternion Divide(const float& scalar) const;
207
208 /**
209 * @brief Raises this quaternion to the power of another quaternion (component-wise).
210 * @param exponent The quaternion exponent.
211 * @return A new quaternion representing the powered result.
212 */
213 Quaternion Power(const Quaternion& exponent) const;
214
215 /**
216 * @brief Raises this quaternion to a scalar power.
217 * @param exponent The exponent (e.g., 2.0f).
218 * @return A new quaternion representing this^exponent.
219 */
220 Quaternion Power(const float& exponent) const;
221
222 /**
223 * @brief Performs a permutation operation using a 3D vector (custom transform).
224 * @param permutation A vector used for permuting the quaternion's components.
225 * @return The permuted quaternion.
226 */
228
229 /**
230 * @brief Returns a quaternion where each component is the absolute value of the original.
231 * @return A quaternion with absolute-valued components.
232 */
233 Quaternion Absolute() const;
234
235 /**
236 * @brief Negates each component (an additive inverse).
237 * @return A quaternion representing -this.
238 */
240
241 /**
242 * @brief Returns the multiplicative inverse of this quaternion, such that q * q^-1 = identity.
243 * @return The multiplicative inverse.
244 */
246
247 /**
248 * @brief Returns the conjugate of this quaternion (W stays the same, X/Y/Z get negated).
249 * @return The conjugated quaternion.
250 */
251 Quaternion Conjugate() const;
252
253 /**
254 * @brief Returns a unit quaternion (normalized) version of this quaternion.
255 * @return A normalized quaternion.
256 */
258
259 /**
260 * @brief Computes the magnitude (length) of this quaternion.
261 * @return The magnitude (sqrt(W^2 + X^2 + Y^2 + Z^2)).
262 */
263 float Magnitude() const;
264
265 /**
266 * @brief Computes the dot product between this quaternion and another.
267 * @param q Another quaternion.
268 * @return The dot product (W*W' + X*X' + Y*Y' + Z*Z').
269 */
270 float DotProduct(const Quaternion& q) const;
271
272 /**
273 * @brief Computes the quaternion's norm (equivalent to squared magnitude).
274 * @return (W^2 + X^2 + Y^2 + Z^2).
275 */
276 float Normal() const;
277
278 /**
279 * @brief Checks if any component of this quaternion is NaN.
280 * @return \c true if any component is NaN, otherwise \c false.
281 */
282 bool IsNaN() const;
283
284 /**
285 * @brief Checks if all components are finite.
286 * @return \c true if finite, otherwise \c false.
287 */
288 bool IsFinite() const;
289
290 /**
291 * @brief Checks if any component is infinite.
292 * @return \c true if infinite, otherwise \c false.
293 */
294 bool IsInfinite() const;
295
296 /**
297 * @brief Checks if the quaternion is non-zero (i.e., any component != 0).
298 * @return \c true if non-zero, otherwise \c false.
299 */
300 bool IsNonZero() const;
301
302 /**
303 * @brief Checks if two quaternions are exactly equal (component-wise).
304 * @param quaternion The quaternion to compare to.
305 * @return \c true if all components match exactly.
306 */
307 bool IsEqual(const Quaternion& quaternion) const;
308
309 /**
310 * @brief Checks if two quaternions are nearly equal within a tolerance.
311 * @param quaternion The quaternion to compare to.
312 * @param epsilon The tolerance for comparison.
313 * @return \c true if each component differs by less than \p epsilon.
314 */
315 bool IsClose(const Quaternion& quaternion, const float& epsilon) const;
316
317 /**
318 * @brief Converts this quaternion to a string representation (e.g. "(W, X, Y, Z)").
319 * @return A \c String displaying the quaternion's components.
320 */
321 String ToString() const;
322
323 // --- Operator Overloads ---
324
325 /**
326 * @brief Equality operator. Checks if two quaternions match exactly (component-wise).
327 * @param quaternion The quaternion to compare.
328 * @return \c true if equal, otherwise \c false.
329 */
330 bool operator ==(const Quaternion& quaternion) const;
331
332 /**
333 * @brief Inequality operator. Checks if two quaternions differ in any component.
334 * @param quaternion The quaternion to compare.
335 * @return \c true if not equal, otherwise \c false.
336 */
337 bool operator !=(const Quaternion& quaternion) const;
338
339 /**
340 * @brief Assignment operator. Copies another quaternion's components to this one.
341 * @param quaternion The quaternion to copy.
342 * @return A reference to this quaternion.
343 */
345
346 /**
347 * @brief Adds two quaternions (component-wise).
348 * @param quaternion The right-hand side quaternion to add.
349 * @return A new quaternion representing the sum.
350 */
352
353 /**
354 * @brief Subtracts one quaternion from another (component-wise).
355 * @param quaternion The right-hand side quaternion to subtract.
356 * @return A new quaternion representing the difference.
357 */
359
360 /**
361 * @brief Multiplies (composes) two quaternions.
362 * @param quaternion The right-hand side quaternion.
363 * @return A new quaternion representing the multiplication result.
364 */
366
367 /**
368 * @brief Divides this quaternion by another quaternion, component-wise.
369 * @param quaternion The right-hand side quaternion divisor.
370 * @return A new quaternion after division.
371 */
373
374 /**
375 * @brief Divides this quaternion by a scalar.
376 * @param value The scalar divisor.
377 * @return A new quaternion scaled by 1.0 / \p value.
378 */
379 Quaternion operator /(const float& value) const;
380
381 /**
382 * @brief Scalar multiplication operator (on the left).
383 * @param scalar The scalar to multiply.
384 * @param q The quaternion to scale.
385 * @return A new quaternion scaled by \p scalar.
386 */
387 friend Quaternion operator *(const float& scalar, const Quaternion& q);
388
389 /**
390 * @brief Scalar multiplication operator (on the right).
391 * @param q The quaternion to scale.
392 * @param scalar The scalar to multiply.
393 * @return A new quaternion scaled by \p scalar.
394 */
395 friend Quaternion operator *(const Quaternion& q, const float& scalar);
396
397 // --- Static Utility Functions ---
398
399 /**
400 * @brief Static convenience function: Adds two quaternions.
401 * @param q1 The first quaternion.
402 * @param q2 The second quaternion.
403 * @return A new quaternion representing the sum.
404 */
405 static Quaternion Add(const Quaternion& q1, const Quaternion& q2);
406
407 /**
408 * @brief Static convenience function: Subtracts one quaternion from another.
409 * @param q1 The first quaternion.
410 * @param q2 The second quaternion to subtract from \p q1.
411 * @return A new quaternion representing the difference.
412 */
413 static Quaternion Subtract(const Quaternion& q1, const Quaternion& q2);
414
415 /**
416 * @brief Static convenience function: Multiplies (composes) two quaternions.
417 * @param q1 The first quaternion.
418 * @param q2 The second quaternion.
419 * @return The resulting quaternion composition.
420 */
421 static Quaternion Multiply(const Quaternion& q1, const Quaternion& q2);
422
423 /**
424 * @brief Static convenience function: Divides one quaternion by another (component-wise).
425 * @param q1 The first quaternion.
426 * @param q2 The second quaternion (divisor).
427 * @return A new quaternion representing the division result.
428 */
429 static Quaternion Divide(const Quaternion& q1, const Quaternion& q2);
430
431 /**
432 * @brief Static convenience function: Raises one quaternion to the power of another (component-wise).
433 * @param q1 The base quaternion.
434 * @param q2 The exponent quaternion.
435 * @return A new quaternion representing the power result.
436 */
437 static Quaternion Power(const Quaternion& q1, const Quaternion& q2);
438
439 /**
440 * @brief Static convenience function: Computes the dot product of two quaternions.
441 * @param q1 The first quaternion.
442 * @param q2 The second quaternion.
443 * @return The scalar dot product.
444 */
445 static float DotProduct(const Quaternion& q1, const Quaternion& q2);
446
447 /**
448 * @brief Static convenience function: Raises a quaternion to a scalar power.
449 * @param quaternion The base quaternion.
450 * @param exponent The scalar exponent.
451 * @return A new quaternion representing the power result.
452 */
453 static Quaternion Power(const Quaternion& quaternion, const float& exponent);
454
455 /**
456 * @brief Static convenience function: Permutates a quaternion with a 3D vector input.
457 * @param quaternion The base quaternion.
458 * @param vector A 3D vector used for permutation.
459 * @return The permuted quaternion.
460 */
462
463 /**
464 * @brief Static convenience function: Returns a quaternion with absolute values of its components.
465 * @param quaternion The input quaternion.
466 * @return A quaternion whose components are the absolute values of \p quaternion's components.
467 */
469
470 /**
471 * @brief Static convenience function: Returns the additive inverse of a quaternion.
472 * @param quaternion The input quaternion.
473 * @return A quaternion representing -q.
474 */
476
477 /**
478 * @brief Static convenience function: Returns the multiplicative inverse of a quaternion.
479 * @param quaternion The input quaternion.
480 * @return A quaternion such that q * q^-1 = identity.
481 */
483
484 /**
485 * @brief Static convenience function: Returns the conjugate of a quaternion.
486 * @param quaternion The input quaternion.
487 * @return A quaternion with (W, -X, -Y, -Z).
488 */
490
491 /**
492 * @brief Static convenience function: Normalizes a quaternion, returning a unit quaternion.
493 * @param quaternion The input quaternion.
494 * @return A normalized quaternion.
495 */
497
498 /**
499 * @brief Static convenience function: Computes the magnitude of a quaternion.
500 * @param quaternion The input quaternion.
501 * @return The magnitude (length) of \p quaternion.
502 */
503 static float Magnitude(const Quaternion& quaternion);
504
505 /**
506 * @brief Static convenience function: Computes the norm (squared magnitude) of a quaternion.
507 * @param quaternion The input quaternion.
508 * @return The squared length of \p quaternion.
509 */
510 static float Normal(const Quaternion& quaternion);
511};
Provides a collection of mathematical utility functions and constants.
Defines a 2D vector and various related operations.
Defines a 3D vector and various related operations.
Implements a generic Kalman Filter for 1D data.
A mathematical construct representing a rotation in 3D space.
Definition Quaternion.h:30
Vector3D GetBiVector() const
Retrieves the bi-vector (X, Y, Z) portion of the quaternion (with W=0).
float DotProduct(const Quaternion &q) const
Computes the dot product between this quaternion and another.
Quaternion Power(const Quaternion &exponent) const
Raises this quaternion to the power of another quaternion (component-wise).
bool IsFinite() const
Checks if all components are finite.
Quaternion Divide(const Quaternion &quaternion) const
Divides this quaternion by another quaternion component-wise (not a typical quaternion operation).
static Quaternion SphericalInterpolation(const Quaternion &q1, const Quaternion &q2, const float &ratio)
Performs spherical linear interpolation (slerp) between two quaternions.
Quaternion Conjugate() const
Returns the conjugate of this quaternion (W stays the same, X/Y/Z get negated).
bool IsInfinite() const
Checks if any component is infinite.
Quaternion AdditiveInverse() const
Negates each component (an additive inverse).
Quaternion UnitQuaternion() const
Returns a unit quaternion (normalized) version of this quaternion.
bool IsNaN() const
Checks if any component of this quaternion is NaN.
Quaternion operator/(const Quaternion &quaternion) const
Divides this quaternion by another quaternion, component-wise.
Quaternion operator+(const Quaternion &quaternion) const
Adds two quaternions (component-wise).
Quaternion operator-(const Quaternion &quaternion) const
Subtracts one quaternion from another (component-wise).
bool operator==(const Quaternion &quaternion) const
Equality operator. Checks if two quaternions match exactly (component-wise).
Quaternion()
Default constructor. Initializes the quaternion to identity (1,0,0,0).
Definition Quaternion.cpp:4
bool operator!=(const Quaternion &quaternion) const
Inequality operator. Checks if two quaternions differ in any component.
Quaternion MultiplicativeInverse() const
Returns the multiplicative inverse of this quaternion, such that q * q^-1 = identity.
Quaternion DeltaRotation(const Vector3D &angularVelocity, const float &timeDelta) const
Computes a small rotation quaternion given an angular velocity and time delta.
Quaternion Permutate(const Vector3D &permutation) const
Performs a permutation operation using a 3D vector (custom transform).
Vector2D RotateVector(const Vector2D &v) const
Rotates a 2D vector by this quaternion, projecting it in 2D.
Vector2D RotateVectorUnit(const Vector2D &v, const Quaternion &q) const
Rotates a 2D vector by a unit quaternion (assumes normalized), allowing a different quaternion to be ...
float W
Scalar part of the quaternion.
Definition Quaternion.h:32
bool IsEqual(const Quaternion &quaternion) const
Checks if two quaternions are exactly equal (component-wise).
String ToString() const
Converts this quaternion to a string representation (e.g. "(W, X, Y, Z)").
bool IsClose(const Quaternion &quaternion, const float &epsilon) const
Checks if two quaternions are nearly equal within a tolerance.
float Z
Z component of the quaternion's vector part.
Definition Quaternion.h:35
float X
X component of the quaternion's vector part.
Definition Quaternion.h:33
Vector3D GetNormal() const
Retrieves the normal vector part of the quaternion, typically its axis of rotation.
float Normal() const
Computes the quaternion's norm (equivalent to squared magnitude).
float Y
Y component of the quaternion's vector part.
Definition Quaternion.h:34
Quaternion Absolute() const
Returns a quaternion where each component is the absolute value of the original.
Quaternion Add(const Quaternion &quaternion) const
Adds two quaternions component-wise.
Vector2D UnrotateVector(const Vector2D &coordinate) const
Applies the inverse of this quaternion's rotation to a 2D vector.
friend Quaternion operator*(const float &scalar, const Quaternion &q)
Scalar multiplication operator (on the left).
float Magnitude() const
Computes the magnitude (length) of this quaternion.
Quaternion Multiply(const Quaternion &quaternion) const
Multiplies (composes) this quaternion with another (order matters).
Quaternion operator=(const Quaternion &quaternion)
Assignment operator. Copies another quaternion's components to this one.
bool IsNonZero() const
Checks if the quaternion is non-zero (i.e., any component != 0).
Quaternion Subtract(const Quaternion &quaternion) const
Subtracts a quaternion from this quaternion component-wise.
Represents a 2D vector (X, Y) and provides methods for vector arithmetic.
Definition Vector2D.h:27
Represents a 3D vector (X, Y, Z) and provides methods for vector arithmetic.
Definition Vector3D.h:26