-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathquaternions.ts
More file actions
86 lines (69 loc) · 2.11 KB
/
quaternions.ts
File metadata and controls
86 lines (69 loc) · 2.11 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
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
// A library for adding, subtracting, and multiplying quaternions.
interface QuaternionLike {
n: number
i: number
j: number
k: number
}
type QuaternionTuple = [n: number, i: number, j: number, k: number]
export class Quaternion implements QuaternionLike {
static from(like: QuaternionLike | QuaternionTuple): Quaternion {
if (Array.isArray(like)) {
return new Quaternion(like[0], like[1], like[2], like[3])
}
return new Quaternion(like.n, like.i, like.j, like.k)
}
static of(text: string): Quaternion {
let n = 0
let i = 0
let j = 0
let k = 0
for (let part of text.split(/(?=[+-])/g)) {
part = part.replace(/\s+/g, "")
const numeric = parseFloat(part)
if (Number.isNaN(numeric)) {
continue
}
if (part.endsWith("i")) {
i = numeric
} else if (part.endsWith("j")) {
j = numeric
} else if (part.endsWith("k")) {
k = numeric
} else {
n = numeric
}
}
return new Quaternion(n, i, j, k)
}
constructor(
readonly n = 0,
readonly i = 0,
readonly j = 0,
readonly k = 0,
) {}
plus({ n, i, j, k }: QuaternionLike) {
return new Quaternion(this.n + n, this.i + i, this.j + j, this.k + k)
}
minus({ n, i, j, k }: QuaternionLike) {
return new Quaternion(this.n - n, this.i - i, this.j - j, this.k - k)
}
times({ n: on, i: oi, j: oj, k: ok }: QuaternionLike) {
const { n, i, j, k } = this
return new Quaternion(
n * on - i * oi - j * oj - k * ok,
n * oi + i * on + j * ok - k * oj,
n * oj + j * on + k * oi - i * ok,
n * ok + k * on + i * oj - j * oi,
)
}
abs() {
return Math.hypot(this.n, this.i, this.j, this.k)
}
scale(v: number) {
return new Quaternion(v * this.n, v * this.i, v * this.j, v * this.k)
}
normalize() {
return this.scale(this.abs())
}
}