Repository navigation
Expand file tree
/
Copy patheuler.js
More file actions
56 lines (49 loc) · 1.42 KB
/
Copy patheuler.js
File metadata and controls
56 lines (49 loc) · 1.42 KB
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
/** @module euler */
/**
* Returns new euler angles at 0, 0, 0: rotations in radians around the x, y and
* z axes (pitch, yaw and roll with Y up).
*
* @returns {import("./types.js").Euler}
*/
export function create() {
return [0, 0, 0];
}
/**
* Creates euler angles from quaternion. Assumes XYZ order of rotations.
*
* @param {import("./types.js").Euler} a
* @param {import("./types.js").Quat} q
* @returns {import("./types.js").Euler}
*/
export function fromQuat(a, q) {
const x = q[0];
const y = q[1];
const z = q[2];
const w = q[3];
const xx = x * x;
const yy = y * y;
const zz = z * z;
const ww = w * w;
// Matrix entries scaled by |q|², cancelled by atan2: q needn't be unit.
const m02 = 2 * (x * z + y * w);
const m10 = 2 * (x * y + z * w);
const m11 = ww - xx + yy - zz;
const m20 = 2 * (x * z - y * w);
const m21 = 2 * (y * z + x * w);
const m22 = ww - xx - yy + zz;
const sxcy = 2 * (x * w - y * z);
const cy = Math.sqrt(sxcy * sxcy + m22 * m22);
// Mike Day, "Extracting Euler Angles from a Rotation Matrix" (2014): atan2
// keeps y precise near ±π/2, and solving z from x keeps both consistent in
// gimbal lock.
a[1] = Math.atan2(m02, cy);
if (cy) {
a[0] = Math.atan2(sxcy, m22);
a[2] = Math.atan2(m22 * m10 + sxcy * m20, m22 * m11 + sxcy * m21);
} else {
// x is arbitrary in exact gimbal lock
a[0] = 0;
a[2] = Math.atan2(m10, m11);
}
return a;
}