/**
 * @remarks A class representing a Quaternion object, used for advanced rotations in 3D space.
 */
export class Quaternion {
    get X() {
        return this.x;
    }
    get Y() {
        return this.y;
    }
    get Z() {
        return this.z;
    }
    get W() {
        return this.w;
    }
    /**
     *
     * @param x The x of the axis vector.
     * @param y The y of the axis vector.
     * @param z The z of the axis vector.
     * @param w The angle of rotation along the axis vector.
     */
    constructor(x = 0, y = 0, z = 0, w = 1) {
        this.x = x;
        this.y = y;
        this.z = z;
        this.w = w;
    }
    /**
     * @remarks Multiplies a quaternion against this.
     * @param q The quaternion to multiply against this.
     * @returns The resluting quaternion.
     */
    multiply(q) {
        return Quaternion.multiplyQuaternions(this, q);
    }
    /**
     * @remarks Creates a quaternion from an axis and a rotation.
     * @param axis The vector axis.
     * @param angle The angle of rotation along the axis.
     * @returns The quaternion representing that rotation.
     */
    static fromAxisAngle(axis, angle) {
        const halfAngle = angle / 2;
        const s = Math.sin(halfAngle);
        const x = axis.x * s;
        const y = axis.y * s;
        const z = axis.z * s;
        const w = Math.cos(halfAngle);
        return new Quaternion(x, y, z, w);
    }
    /**
     * @remarks Multiplies two quaternions together. Note that the order of multiplication is important.
     * @param a The first quaternion.
     * @param b The second quaternion.
     * @returns The resulting quaternion.
     */
    static multiplyQuaternions(a, b) {
        const qax = a.x, qay = a.y, qaz = a.z, qaw = a.w;
        const qbx = b.x, qby = b.y, qbz = b.z, qbw = b.w;
        const x = qax * qbw + qaw * qbx + qay * qbz - qaz * qby;
        const y = qay * qbw + qaw * qby + qaz * qbx - qax * qbz;
        const z = qaz * qbw + qaw * qbz + qax * qby - qay * qbx;
        const w = qaw * qbw - qax * qbx - qay * qby - qaz * qbz;
        return new Quaternion(x, y, z, w);
    }
    toString() {
        return `x: ${this.x}, y: ${this.y}, z: ${this.z}, w: ${this.w}`;
    }
}
