-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathQuaternion.h
161 lines (138 loc) · 4.38 KB
/
Quaternion.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
// Copyright (C) 2019 Martin Weigel <[email protected]>
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
/**
* @file Quaternion.h
* @brief A basic quaternion library written in C
* @date 2019-11-28
*/
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <math.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* Maximum floating point difference that is considered as equal.
*/
#define QUATERNION_EPS (1e-4)
/**
* Data structure to hold a quaternion.
*/
typedef struct Quaternion {
double w; /**< Scalar part */
double v[3]; /**< Vector part */
} Quaternion;
/**
* Sets the given values to the output quaternion.
*/
void Quaternion_set(double w, double v1, double v2, double v3, Quaternion* output);
/**
* Sets quaternion to its identity.
*/
void Quaternion_setIdentity(Quaternion* q);
/**
* Copies one quaternion to another.
*/
void Quaternion_copy(Quaternion* q, Quaternion* output);
/**
* Tests if all quaternion values are equal (using QUATERNION_EPS).
*/
bool Quaternion_equal(Quaternion* q1, Quaternion* q2);
/**
* Print the quaternion to a given file (e.g., stderr).
*/
void Quaternion_fprint(FILE* file, Quaternion* q);
/**
* Set the quaternion to the equivalent of axis-angle rotation.
* @param axis
* The axis of the rotation (should be normalized).
* @param angle
* Rotation angle in radians.
*/
void Quaternion_fromAxisAngle(double axis[3], double angle, Quaternion* output);
/**
* Calculates the rotation vector and angle of a quaternion.
* @param output
* A 3D vector of the quaternion rotation axis.
* @return
* The rotation angle in radians.
*/
double Quaternion_toAxisAngle(Quaternion* q, double output[3]);
/**
* Set the quaternion to the equivalent of euler angles.
* @param eulerZYX
* Euler angles in ZYX, but stored in array as [x'', y', z].
*/
void Quaternion_fromEulerZYX(double eulerZYX[3], Quaternion* output);
/**
* Calculates the euler angles of a quaternion.
* @param output
* Euler angles in ZYX, but stored in array as [x'', y', z].
*/
void Quaternion_toEulerZYX(Quaternion* q, double output[3]);
/**
* Set the quaternion to the equivalent a rotation around the X-axis.
* @param angle
* Rotation angle in radians.
*/
void Quaternion_fromXRotation(double angle, Quaternion* output);
/**
* Set the quaternion to the equivalent a rotation around the Y-axis.
* @param angle
* Rotation angle in radians.
*/
void Quaternion_fromYRotation(double angle, Quaternion* output);
/**
* Set the quaternion to the equivalent a rotation around the Z-axis.
* @param angle
* Rotation angle in radians.
*/
void Quaternion_fromZRotation(double angle, Quaternion* output);
/**
* Calculates the norm of a given quaternion:
* norm = sqrt(w*w + v1*v1 + v2*v2 + v3*v3)
*/
double Quaternion_norm(Quaternion* q);
/**
* Normalizes the quaternion.
*/
void Quaternion_normalize(Quaternion* q, Quaternion* output);
/**
* Calculates the conjugate of the quaternion: (w, -v)
*/
void Quaternion_conjugate(Quaternion* q, Quaternion* output);
/**
* Multiplies two quaternions: output = q1 * q2
* @param q1
* The rotation to apply on q2.
* @param q2
* The orientation to be rotated.
*/
void Quaternion_multiply(Quaternion* q1, Quaternion* q2, Quaternion* output);
/**
* Applies quaternion rotation to a given vector.
*/
void Quaternion_rotate(Quaternion* q, double v[3], double output[3]);
/**
* Interpolates between two quaternions.
* @param t
* Interpolation between the two quaternions [0, 1].
* 0 is equal with q1, 1 is equal with q2, 0.5 is the middle between q1 and q2.
*/
void Quaternion_slerp(Quaternion* q1, Quaternion* q2, double t, Quaternion* output);
#ifdef __cplusplus
}
#endif