@casual-simulation/aux-common
Version:
Common library for AUX projects
123 lines • 4.61 kB
JavaScript
/* CasualOS is a set of web-based tools designed to facilitate the creation of real-time, multi-user, context-aware interactive experiences.
*
* Copyright (c) 2019-2025 Casual Simulation, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
export class Quaternion {
/**
* Creates a new Quaternion with the given values.
* @param x The X value.
* @param y The Y value.
* @param z The Z value.
* @param w The W value.
*/
constructor(x = 0, y = 0, z = 0, w = 1) {
this.x = x;
this.y = y;
this.z = z;
this.w = w;
Object.freeze(this);
}
/**
* Multiplies this quaternion by the other quaternion and returns the result.
* In quaternion math, multiplication can be used to combine quaternions together,
* however unlike regular multiplication quaternion multiplication is order dependent.
*
* Which frame of reference you want to use depends on which order you use.
* For example, q2.multiply(q1) starts with the identity, applies q1 to it, and then applies q2 to that.
* Whereas, q1.multiply(q2) starts with the identity, applies q2 to it, and then applies q1 to that.
*
* @param other The other quaternion.
*/
multiply(other) {
// Taken from https://www.euclideanspace.com/maths/algebra/realNormedAlgebra/quaternions/arithmetic/index.htm
const x = this.x * other.w +
this.w * other.x +
this.y * other.z -
this.z * other.y;
const y = this.w * other.y -
this.x * other.z +
this.y * other.w +
this.z * other.x;
const z = this.w * other.z +
this.x * other.y -
this.y * other.x +
this.z * other.w;
const w = this.w * other.w -
this.x * other.x -
this.y * other.y -
this.z * other.z;
return new Quaternion(x, y, z, w);
}
/**
* Calculates the conjugate of this quaternion and returns the result.
* The conjugate (or inverse) of a quaternion is similar to negating a number.
* When you multiply a quaternion by its conjugate, the result is the identity quaternion.
*/
invert() {
return new Quaternion(-this.x, -this.y, -this.z, this.w);
}
/**
* Gets the length of this vector. That is, the pathagorean theorem applied to X, Y, Z, and W.
*/
length() {
return Math.sqrt(this.x * this.x +
this.y * this.y +
this.z * this.z +
this.w * this.w);
}
/**
* Calculates the square length of this quaternion and returns the result.
* This is equivalent to length^2, but it is faster to calculate than length because it doesn't require
* calculating a square root.
*/
squareLength() {
return (this.x * this.x +
this.y * this.y +
this.z * this.z +
this.w * this.w);
}
/**
* Calculates the normalized version of this quaternion and returns it.
* A normalized quaternion is a quaternion whose length equals 1.
*
* Normalizing a quaternion preserves its rotation/reflection while making the length (i.e. scale) of it 1.
*/
normalize() {
const length = this.length();
return new Quaternion(this.x / length, this.y / length, this.z / length, this.w / length);
}
toString() {
return `Quaternion(${this.x}, ${this.y}, ${this.z}, ${this.w})`;
}
/**
* Determines if this quaternion equals the other quaternion.
* @param other The other quaternion to apply.
*/
equals(other) {
if (!other) {
return false;
}
return (this.x === other.x &&
this.y === other.y &&
this.z === other.z &&
this.w === other.w);
}
}
/**
* The identity quaternion.
*/
export const IDENTITY = new Quaternion(0, 0, 0, 1);
//# sourceMappingURL=Quaternion.js.map