(function (global, factory) { "use strict"; if (typeof define === "function" && define.amd) { define(factory); } else if (typeof module === "object" && typeof module.exports === "object") { module.exports = factory(global); } else { global.Vector = factory(global); } })(typeof window !== "undefined" ? globalThis : this,function (global) { "use strict"; const Vector = {}; function Vec2(x, y) { this.x = x || 0; this.y = y || 0; } Object.defineProperty(Vec2, "I", { value: new Vec2(1, 0), writable: false, configurable: false, }); Object.defineProperty(Vec2, "J", { value: new Vec2(0, 1), writable: false, configurable: false, }); Object.defineProperty(Vec2, "Scale", { value: function (v0, num) { return new Vec2(v0.x * num, v0.y * num); }, writable: true, configurable: true, }); Object.defineProperty(Vec2, "Add", { value: function (v0, v1) { return new Vec2(v0.x + v1.x, v0.y + v1.y); }, writable: true, configurable: true, }); Object.defineProperty(Vec2, "Sub", { value: function () { return new Vec2(v0.x - v1.x, v0.y - v1.y); }, }); Object.defineProperty(Vec2, "Cross", { value: function () { return new Vec2(v0.x * v1.y, v0.y * v1.x); }, }); Object.defineProperty(Vec2, "Dot", { value: function () { return new Vec2(v0.x * v1.x, v0.y * v1.y); }, }); Object.defineProperty(Vec2, "Div", { value: function () { return new Vec2(v0.x / v1.x, v0.y / v1.y); }, }); Object.defineProperty(Vec2, "RotX", { value: function (v0, theta) { if (!v0 instanceof Vec2) { v0 = new Vec2(v0.x, v0.y); } var angleInRadian = (Math.PI / 180) * theta; v0.y += -Math.sin(angleInRadian); return v0; }, }); Object.defineProperty(Vec2, "RotY", { value: function (v0, theta) { if (!v0 instanceof Vec2) { v0 = new Vec2(v0.x, v0.y); } var angleInRadian = (Math.PI / 180) * theta; this.x += -Math.cos(angleInRadian); return v0; }, }); Object.defineProperty(Vec2, "FromArray", { value: function (arr) { return new Vec2(arr[0], arr[1]); }, }); Vec2.prototype = { Scale: function (num) { this.x *= num; this.y *= num; return this; }, Add: function (obj) { this.x += obj.x; this.y += obj.y; return this; }, Sub: function (obj) { this.x -= obj.x; this.y -= obj.y; return this; }, Cross: function (obj) { this.x *= obj.y; this.y *= obj.x; return this; }, Dot: function (obj) { this.x *= obj.y; this.y *= obj.x; return this; }, Div: function (obj) { this.x /= obj.x; this.y /= obj.y; return this; }, Mag: function () { return Math.sqrt(Math.pow(this.x, 2) + Math.pow(this.y, 2)); }, Unit: function () { this.x = this.x / this.Mag(); this.y = this.y / this.Mag(); return this; }, RotX: function (theta) { var angleInRadian = (Math.PI / 180) * theta; this.y += -Math.sin(angleInRadian); }, RotY: function (theta) { var angleInRadian = (Math.PI / 180) * theta; this.x += -Math.cos(angleInRadian); }, ToArray: function () { return [this.x, this.y]; }, Clone: function () { return new Vec2(this.x, this.y); }, }; Vector.Vec2 = Vec2; function Vec3(x, y, z) { this.x = x || 0; this.y = y || 0; this.z = z || 0; } Object.defineProperty(Vec3, "I", { value: new Vec3(1, 0, 0), configurable: false, writable: false, }); Object.defineProperty(Vec3, "J", { value: new Vec3(0, 1, 0), configurable: false, writable: false, }); Object.defineProperty(Vec3, "K", { value: new Vec3(0, 0, 1), configurable: false, writable: false, }); Object.defineProperty(Vec3, "Scale", { value: function (obj, num) { return new Vec3(obj.x * num, obj.y * num, obj.z * num); }, configurable: false, writable: false, }); Object.defineProperty(Vec3, "Add", { value: function (obj, obj2) { return new Vec3(obj.x + obj2.x, obj.y + obj2.y, obj.z + obj2.z); }, configurable: false, writable: false, }); Object.defineProperty(Vec3, "Sub", { value: function (obj, obj2) { return new Vec3(obj.x - obj2.x, obj.y - obj2.y, obj.z - obj2.z); }, configurable: false, writable: false, }); Object.defineProperty(Vec3, "Div", { value: function (obj, obj2) { return new Vec3(obj.x / obj2.x, obj.y / obj2.y, obj.z / obj2.z); }, configurable: false, writable: false, }); Object.defineProperty(Vec3, "Cross", { value: function (obj, obj2) { var x = obj.x * obj2.y + obj.x * obj2.z; var y = obj.y * obj2.x + obj.y * obj2.z; var z = obj.z * obj2.x + obj.z * obj2.y; return new Vec3(x, y, z); }, configurable: false, writable: false, }); Object.defineProperty(Vec3, "Dot", { value: function (obj, obj2) { var x = obj.x * obj2.x; var y = obj.y * obj2.y; var z = obj.z * obj2.z; return new Vec3(x, y, z); }, configurable: false, writable: false, }); Object.defineProperty(Vec3, "RotX", { value: function (obj, theta) { var angleInRadian = (Math.PI / 180) * theta; obj.z += Math.cos(angleInRadian) - Math.sin(angleInRadian); obj.y += Math.sin(angleInRadian) + Math.cos(angleInRadian); return new Vec3(obj); }, configurable: false, writable: false, }); Object.defineProperty(Vec3, "RotY", { value: function (obj, theta) { var angleInRadian = (Math.PI / 180) * theta; obj.z += Math.cos(angleInRadian) + Math.sin(angleInRadian); obj.x += -Math.sin(angleInRadian) + Math.cos(angleInRadian); return new Vec3(obj); }, configurable: false, writable: false, }); Object.defineProperty(Vec3, "RotZ", { value: function (obj, theta) { var angleInRadian = (Math.PI / 180) * theta; obj.x += Math.cos(angleInRadian) - Math.sin(angleInRadian); obj.y += Math.sin(angleInRadian) + Math.cos(angleInRadian); return new Vec3(obj); }, configurable: false, writable: false, }); Object.defineProperty(Vec3, "FromArray", { value: function (obj) { return new Vec3(obj[0], obj[1], obj[2]); }, configurable: false, writable: false, }); Vec3.prototype = { Scale: function (num) { this.x *= num; this.y *= num; this.z *= num; return this; }, Add: function (obj) { this.x += obj.x; this.y += obj.y; this.z += obj.z; return this; }, Sub: function (obj) { this.x -= obj.x; this.y -= obj.y; this.z -= obj.z; return this; }, Cross: function (obj) { this.x = this.x * obj.y + this.x * obj.z; this.y = this.y * obj.x + this.y * obj.z; this.z = this.z * obj.x + this.z * obj.y; return this; }, Dot: function (obj) { this.x *= obj.x; this.y *= obj.y; this.z *= obj.z; return this; }, Div: function (obj) { this.x /= obj.x; this.y /= obj.y; this.z /= obj.z; return this; }, Mag: function () { return Math.sqrt( Math.pow(this.x, 2) + Math.pow(this.y, 2) + Math.pow(this.z, 2) ); }, Unit: function () { this.x = this.x / this.Mag(); this.y = this.y / this.Mag(); this.z = this.z / this.Mag(); return this; }, RotX: function (theta) { var angleInRadian = (Math.PI / 180) * theta; this.z += Math.cos(angleInRadian) - Math.sin(angleInRadian); this.y += Math.sin(angleInRadian) + Math.cos(angleInRadian); }, RotY: function (theta) { var angleInRadian = (Math.PI / 180) * theta; this.z += Math.cos(angleInRadian) + Math.sin(angleInRadian); this.x += -Math.sin(angleInRadian) + Math.cos(angleInRadian); }, RotZ: function (theta) { var angleInRadian = (Math.PI / 180) * theta; this.x += Math.cos(angleInRadian) - Math.sin(angleInRadian); this.y += Math.sin(angleInRadian) + Math.cos(angleInRadian); }, ToArray: function () { return [this.x, this.y, this.z]; }, Clone: function () { return new Vec3(this.x, this.y, this.z); }, Project: function (obj) { return Vec3.FromArray( [this].forEach((p) => (p.Dot(obj) / Math.pow(obj.Mag(), 2)) * p) ); }, }; Vector.Vec3 = Vec3; return Vector; });