👔Quaternion
JS ⟩ value ⟩ primitive ⟩ number ⟩ Quaternion
replit ⟩ Quaternion, require ⟩ Number+ext, Random
// 2023.03.01 - 13: 42 (+) .randomInt, .randomFloat, .toString
// 2023.02.24 - 15: 33 (+) static members, .conjugate, .norm, .inverse, ...
// 2023.02.24 - 13: 35 (•) first draft (by chatGPT)
// -------------------------------------------------
const _Number = require('./Number+ext.js'); // 2023.03.01 - 10:11
const { Random } = require('./Random.js');
const { sqrt } = Math;
// ⭐ Quaternion
// --------------------------------------------------
// - Quaternion.zero, .one, .i, .j, .k
// - Quaternion.randomInt()
// - Quaternion.randomFloat()
// --------------------------------------------------
// - .conjugate
// - .normSquare
// - .norm
// - .inverse
// --------------------------------------------------
// - .add()
// - .subtract()
// - .multiply()
// - .divide()
// - .scale()
// --------------------------------------------------
// - .distance()
// - .equal()
//
class Quaternion {
// i, j, k
static get zero() { return new Quaternion(0, 0, 0, 0) }
static get one() { return new Quaternion(1, 0, 0, 0) }
static get i() { return new Quaternion(0, 1, 0, 0) }
static get j() { return new Quaternion(0, 0, 1, 0) }
static get k() { return new Quaternion(0, 0, 0, 1) }
// init
constructor(a, b, c, d) {
this.a = a;
this.b = b;
this.c = c;
this.d = d;
}
// ----------------------
// static methods
// ----------------------
// Quaternion.randomInt()
static randomInt(min, max) {
return new Quaternion(
Random.int(min, max),
Random.int(min, max),
Random.int(min, max),
Random.int(min, max),
)
}
// Quaternion.randomFloat()
static randomFloat(min, max) {
return new Quaternion(
Random.float(min, max),
Random.float(min, max),
Random.float(min, max),
Random.float(min, max),
)
}
// ----------------------
// static methods
// ----------------------
// conjugate
get conjugate() {
const { a, b, c, d } = this;
return new Quaternion(a, -b, -c, -d);
}
// inverse (reciprocal)
get inverse() {
const n = this.normSquare;
return this.conjugate.scale(1 / n);
}
// normSquare
get normSquare() {
const { a, b, c, d } = this;
return (a * a + b * b + c * c + d * d);
}
// norm
get norm() {
const { a, b, c, d } = this;
return sqrt(this.normSquare);
}
// ---------------------------
// ⭐ + - * / operations
// ---------------------------
add(q) {
const { a, b, c, d } = this;
return new Quaternion(
a + q.a, b + q.b, c + q.c, d + q.d
);
}
subtract(q) {
const { a, b, c, d } = this;
return new Quaternion(
a - q.a, b - q.b, c - q.c, d - q.d
);
}
multiply(q) {
const { a, b, c, d } = this;
return new Quaternion(
a * q.a - b * q.b - c * q.c - d * q.d,
a * q.b + b * q.a + c * q.d - d * q.c,
a * q.c - b * q.d + c * q.a + d * q.b,
a * q.d + b * q.c - c * q.b + d * q.a,
);
}
// p/q = p q^(-1)
// ❗ note: p q^(-1) !== q^(-1) p
divide(q) {
return this.multiply(q.inverse);
}
// kq
scale(k) {
const { a, b, c, d } = this;
return new Quaternion(k * a, k * b, k * c, k * d);
}
// ---------------------------
// ⭐ helpers
// ---------------------------
// distance
distance(q) {
return this.subtract(q).norm;
}
// equal
equal(q, {threshold=1e-10}={}) {
return this.distance(q).equal(0, {threshold});
}
// toString
toString(places=3) {
const { a, b, c, d } = this;
return `(${a.round(places)},${b.round(places)},${c.round(places)},${d.round(places)})`;
}
}
// export
module.exports = {
Quaternion,
};
Last updated