UNPKG

@lucania/vectorics

Version:
269 lines (263 loc) 10.6 kB
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.Vectorics = {})); })(this, (function (exports) { 'use strict'; class Matrix { data; size; constructor(...data) { this.data = data; this.size = Math.sqrt(data.length); } add(value) { const data = this._tuple(value); this.data.map((_, index) => this.data[index] += data[index]); return this; } subtract(value) { const data = this._tuple(value); this.data.forEach((_, index) => this.data[index] -= data[index]); return this; } multiply(value) { const data = this._tuple(value); this.data.forEach((_, index) => this.data[index] *= data[index]); return this; } divide(value) { const data = this._tuple(value); this.data.forEach((_, index) => this.data[index] /= data[index]); return this; } transpose() { const matrix = this.clone(); for (let i = 0; i < this.size; i++) { for (let j = 0; j < this.size; j++) { matrix.data[i * this.size + j] = this.data[j]; } } this.data = matrix.data; } clone() { return new Matrix(...this.data); } _tuple(value) { if (typeof value === "number") { return new Array(this.size).fill(value); } else if (value instanceof Matrix) { return value.data; } else { return value; } } } class Matrix2 extends Matrix { } class Matrix3 extends Matrix { } class Matrix4 extends Matrix { } exports.MatrixToolbox = void 0; (function (MatrixToolbox) { function tuple(size, source) { if (typeof source === "number") { return new Array(size).fill(source); } else if (source instanceof Matrix) { return source.data; } else { return source; } } MatrixToolbox.tuple = tuple; function fromSource(size, source) { const tuple = MatrixToolbox.tuple(size, source); switch (size) { case 2: return new Matrix2(...tuple); case 3: return new Matrix3(...tuple); case 4: return new Matrix4(...tuple); default: return new Matrix(...tuple); } } MatrixToolbox.fromSource = fromSource; (function (Projection) { function orthographic(left, right, bottom, top, near, far) { const width = right - left; const height = top - bottom; const depth = far - near; const translationX = -(right + left) / width; const translationY = -(top + bottom) / height; const translationZ = -(far + near) / depth; return new Matrix4(2 / width, 0, 0, translationX, 0, 2 / height, 0, translationY, 0, 0, -2 / depth, translationZ, 0, 0, 0, 1); } Projection.orthographic = orthographic; })(MatrixToolbox.Projection || (MatrixToolbox.Projection = {})); (function (Transformation) { function translate(translationX, translationY, translationZ) { return new Matrix4(1, 0, 0, translationX, 0, 1, 0, translationY, 0, 0, 1, translationZ, 0, 0, 0, 1); } Transformation.translate = translate; function rotate(angleInDegrees, axisX, axisY, axisZ) { const angleInRadians = angleInDegrees * globalThis.Math.PI / 180; const cosAngle = globalThis.Math.cos(angleInRadians); const sinAngle = globalThis.Math.sin(angleInRadians); const oneMinusCos = 1 - cosAngle; const tx = oneMinusCos * axisX; const ty = oneMinusCos * axisY; const tz = oneMinusCos * axisZ; const txy = tx * axisY; const txz = tx * axisZ; const tyz = ty * axisZ; const sinX = sinAngle * axisX; const sinY = sinAngle * axisY; const sinZ = sinAngle * axisZ; return new Matrix4(tx * axisX + cosAngle, txy - sinZ, txz + sinY, 0, txy + sinZ, ty * axisY + cosAngle, tyz - sinX, 0, txz - sinY, tyz + sinX, tz * axisZ + cosAngle, 0, 0, 0, 0, 1); } Transformation.rotate = rotate; function scale(scaleX, scaleY, scaleZ) { return new Matrix4(scaleX, 0, 0, 0, 0, scaleY, 0, 0, 0, 0, scaleZ, 0, 0, 0, 0, 1); } Transformation.scale = scale; })(MatrixToolbox.Transformation || (MatrixToolbox.Transformation = {})); })(exports.MatrixToolbox || (exports.MatrixToolbox = {})); class Vector { components; constructor(...components) { this.components = components; } add(value) { return this.operation(value, (a, b) => a + b); } subtract(value) { return this.operation(value, (a, b) => a - b); } multiply(value) { return this.operation(value, (a, b) => a * b); } divide(value) { return this.operation(value, (a, b) => a / b); } set(value) { return this.operation(value, (_, b) => b); } normalize() { return this.operation(this.getMagnitude(), (a, b) => a / b); } dot(value) { return this.clone().multiply(value).getSum(); } distance(vector) { const difference = this.clone().subtract(vector); return Math.sqrt(difference.multiply(difference).getSum()); } clone() { return new Vector(...this._components); } getSum() { return this._components.reduce((sum, value) => sum + value); } getMagnitude() { return this.distance(this.clone().set(0)); } operation(value, operation) { if (typeof value === "number") { for (let i = 0; i < this._components.length; i++) { this._components[i] = operation(this._components[i], value); } } else if (value instanceof Vector) { for (let i = 0; i < this._components.length; i++) { this._components[i] = operation(this._components[i], value._components[i]); } } else { for (let i = 0; i < this._components.length; i++) { this._components[i] = operation(this._components[i], value[i]); } } return this; } toString() { return `[ ${this._components.join(", ")} ]`; } get _components() { return this.components; } get size() { return this.components.length; } } class Vector2 extends Vector { get x() { return this.components[0]; } set x(value) { this.components[0] = value; } get y() { return this.components[1]; } set y(value) { this.components[1] = value; } get width() { return this.x; } set width(value) { this.x = value; } get height() { return this.y; } set height(value) { this.y = value; } } class Vector3 extends Vector { get x() { return this.components[0]; } set x(value) { this.components[0] = value; } get y() { return this.components[1]; } set y(value) { this.components[1] = value; } get z() { return this.components[2]; } set z(value) { this.components[2] = value; } get width() { return this.x; } set width(value) { this.x = value; } get height() { return this.y; } set height(value) { this.y = value; } get depth() { return this.z; } set depth(value) { this.z = value; } cross(vector) { return this.set([ this.y * vector.z - this.z * vector.y, this.z * vector.x - this.x * vector.z, this.x * vector.y - this.y * vector.x ]); } } class Vector4 extends Vector { get x() { return this.components[0]; } set x(value) { this.components[0] = value; } get y() { return this.components[1]; } set y(value) { this.components[1] = value; } get z() { return this.components[2]; } set z(value) { this.components[2] = value; } get w() { return this.components[3]; } set w(value) { this.components[3] = value; } get width() { return this.z; } set width(value) { this.z = value; } get height() { return this.w; } set height(value) { this.w = value; } } exports.VectorToolbox = void 0; (function (VectorToolbox) { function tuple(size, source) { if (typeof source === "number") { return new Array(size).fill(source); } else if (source instanceof Vector) { return source.components; } else { return source; } } VectorToolbox.tuple = tuple; function fromSource(size, source) { const tuple = VectorToolbox.tuple(size, source); switch (size) { case 2: return new Vector2(...tuple); case 3: return new Vector3(...tuple); case 4: return new Vector4(...tuple); default: return new Vector(...tuple); } } VectorToolbox.fromSource = fromSource; })(exports.VectorToolbox || (exports.VectorToolbox = {})); exports.Toolbox = void 0; (function (Toolbox) { Toolbox.Vector = exports.VectorToolbox; Toolbox.Matrix = exports.MatrixToolbox; })(exports.Toolbox || (exports.Toolbox = {})); exports.Matrix = Matrix; exports.Matrix2 = Matrix2; exports.Matrix3 = Matrix3; exports.Matrix4 = Matrix4; exports.Vector = Vector; exports.Vector2 = Vector2; exports.Vector3 = Vector3; exports.Vector4 = Vector4; }));