From a5430ba82da82b6728c16e87bf2b30876162d6e4 Mon Sep 17 00:00:00 2001 From: Stefan Eckert Date: Wed, 26 Aug 2020 21:32:45 +0200 Subject: [PATCH] feat(math): add multiplyVecMat4 function --- src/array.js | 9 -- src/color.js | 155 +---------------------------- src/degree.js | 36 ------- src/index.js | 14 --- src/operator.js | 20 ---- src/point.js | 183 ----------------------------------- src/quaternion.js | 138 -------------------------- src/utils/math.js | 9 ++ src/vector.js | 242 ---------------------------------------------- 9 files changed, 13 insertions(+), 793 deletions(-) diff --git a/src/array.js b/src/array.js index db81fe6a..c7720785 100644 --- a/src/array.js +++ b/src/array.js @@ -19,15 +19,6 @@ export class VectorArray extends Array { cachedValueOf(VectorArray, src => src); -/** - * @typedef {Array & number} ArrayType - * @typedef {(arr: Array) => ArrayType} ArrArr - * @typedef {(...number) => ArrayType} NumberArr - * @typedef {ArrArr & NumberArr} - * - * @param {Array | ...number} vals - * @returns {ArrayType} - */ export function vectorArray(...vals) { return new VectorArray(...vals); } diff --git a/src/color.js b/src/color.js index 3b74ed65..2f8d1bd4 100644 --- a/src/color.js +++ b/src/color.js @@ -11,15 +11,6 @@ const Z = 2; const W = 3; const AXES = Symbol('axes'); -/** - * @typedef {IColor & number} IColorType - * @typedef {Color & number} ColorType - * @typedef {() => number} Alg - * @typedef {AColor & number} AColorType - */ -/** - * @abstract - */ class AColor { constructor(x, y, z, w) { if (typeof x === 'function') { @@ -35,133 +26,72 @@ class AColor { } } - /** - * @throws NotImplementedError - */ + dot(v) { + return this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w; + } + valueOf() { throw new Error('valueOf() not implemented, looks like you try to calculate outside of calc'); } - /** - * - * @returns {[number, number]} - */ toArray() { return [this.x, this.y, this.z, this.w]; } - /** - * @param {(color: AColorType) => number} alg - * @returns {this} - * @throws NotImplementedError ⚠ - */ calc(alg) { throw new Error('calc() not implemented'); } - /** - * @throws NotImplementedError ⚠ - * @returns {AColor} - */ clone() { throw new Error('clone() not implemented'); } - /** - * - * @param {AColor} v - * @returns {boolean} - */ equals(v) { return this.x === v.x && this.y === v.y && this.z === v.z && this.w === v.w; } - /** - * - * @returns {object} - */ toJSON() { return { x: this.x, y: this.y, z: this.z, w: this.w }; } - /** - * - * @returns {string} - */ toString() { return JSON.stringify(this.toJSON()); } - /** - * - * @returns {object} - */ toCSSVars(name, target) { return convertToCSSVars(name, this.toJSON(), target); } - /** - * - * @returns {number} - */ get x() { return this[AXES][X]; } - /** - * - * @throws SetNotImplementedError - */ set x(_) { throw new Error('set x() not implemented'); } - /** - * - * @returns {number} - */ get y() { return this[AXES][Y]; } - /** - * - * @throws SetNotImplementedError - */ set y(_) { throw new Error('set y() not implemented'); } - /** - * - * @returns {number} - */ get z() { return this[AXES][Z]; } - /** - * - * @throws SetNotImplementedError - */ set z(_) { throw new Error('set z() not implemented'); } - /** - * - * @returns {number} - */ get w() { return this[AXES][W]; } - /** - * - * @throws SetNotImplementedError - */ set w(_) { throw new Error('set w() not implemented'); } @@ -176,138 +106,61 @@ defineVectorLength(AColor, 4); cachedMethod(AColor, 'toArray'); export class Color extends AColor { - /** - * - * @param {number} x - */ set x(x) { this[AXES][X] = x; } - /** - * - * @param {number} y - */ set y(y) { this[AXES][Y] = y; } - /** - * - * @param {number} z - */ set z(z) { this[AXES][Z] = z; } - /** - * - * @param {number} w - */ set w(w) { this[AXES][W] = w; } - /** - * - * @returns {number} - */ get x() { return this[AXES][X]; } - /** - * - * @returns {number} - */ get y() { return this[AXES][Y]; } - /** - * - * @returns {number} - */ get z() { return this[AXES][Z]; } - /** - * - * @returns {number} - */ get w() { return this[AXES][W]; } - /** - * @param {(color: ColorType) => number} alg - * @returns {this} - */ calc(alg) { return operatorCalc(alg, this); } - /** - * @returns {AColor} - */ clone() { return new Color(this.x, this.y); } } export class IColor extends AColor { - /** - * @returns {ColorType} - */ toColor() { return new Color(this.x, this.y, this.z, this.w); } } -/** - * @param {Alg} alg - * @return {ColorType | IColorType} - */ export function calc(alg) { return operatorCalc(alg); } -/** - * @template P - * @typedef {() => P} PZero - */ -/** - * @template P - * @typedef {(alg: Alg) => P} PAlg - */ -/** - * @template P - * @typedef {(x: number, y: number, z: number, w: number) => P} PCon - */ -/** - * @template P - * @typedef {(data: [number, number, number, number]) => P} PArr - */ -/** - * @template P - * @typedef {(vec: { x: number, y: number, z: number, w: number }) => P} PObj - */ -/** - * @template P - * @typedef {PZero

& PAlg

& PCon

& PArr

& PObj

} Po - */ - const colorFactory = cachedFunction((x, y, z, w) => new Color(x, y, z, w)); -/** - * @type {Po} - */ export const color = (x, y, z, w) => colorFactory(x, y, z, w); const icolorFactory = cachedFunction((x, y, z, w) => new IColor(x, y, z, w)); -/** - * @type {Po} - */ export const icolor = (x, y, z, w) => icolorFactory(x, y, z, w); diff --git a/src/degree.js b/src/degree.js index 91d8c038..f61160ae 100644 --- a/src/degree.js +++ b/src/degree.js @@ -6,16 +6,7 @@ const ANGLE = Symbol('angle rad'); const DEG_TO_RAD = Math.PI / 180; const RAD_TO_DEG = 180 / Math.PI; -/** - * @typedef {Degree & number} DegreeType - * @typedef {IDegree & number} IDegreeType - * @abstract - */ class ADegree { - /** - * - * @param {number | ADegree} angle - */ constructor(angle) { if (angle instanceof ADegree) { this[ANGLE] = angle[ANGLE]; @@ -24,40 +15,24 @@ class ADegree { } } - /** - * @returns {number} - */ valueOf() { return this[ANGLE]; } - /** - * @returns {object} - */ toJSON() { return { angle: this[ANGLE] }; } - /** - * @returns {string} - */ toString() { return JSON.stringify(this.toJSON()); } - /** - * @returns {object} - */ toCSSVars(name, target) { return convertToCSSVars(name, this.toJSON(), target); } } export class Degree extends ADegree { - /** - * - * @param {number | Degree | IDegree} [angle] - */ set(angle) { if (angle instanceof ADegree) { this[ANGLE] = angle[ANGLE]; @@ -68,9 +43,6 @@ export class Degree extends ADegree { } export class IDegree extends ADegree { - /** - * @returns {Degree} - */ toDegree() { return new Degree(this[ANGLE]); } @@ -78,18 +50,10 @@ export class IDegree extends ADegree { const ZERO = new IDegree(0); -/** - * @param {number | Degree | IDegree} angle - * @returns {DegreeType} - */ export function degree(angle) { return new Degree(angle); } -/** - * @param {number | Degree | IDegree} angle - * @returns {IDegreeType} - */ export function idegree(angle) { if (angle instanceof IDegree) { return angle; diff --git a/src/index.js b/src/index.js index 11bfdf3d..fb2f043b 100644 --- a/src/index.js +++ b/src/index.js @@ -21,20 +21,6 @@ export { } from './color'; export { IMat3 } from './mat3'; -/** - * @typedef {Vector & number} IndexVector - * @typedef {Victor & number} IndexVictor - * @typedef {Point & number} IndexPoint - * @typedef {IPoint & number} IndexIPoint - * @typedef {Quaternion & number} IndexQuaternion - * @typedef {IQuaternion & number} IndexIQuaternion - * @typedef {IMat3 & number} IndexIMat3 - */ - -/** - * @param {() => number} alg - * @return {IndexVector | IndexVictor | IndexPoint | IndexIPoint | IndexQuaternion | IndexIQuaternion | IndexIMat3 | number} - */ export function calc(alg) { return operatorCalc(alg); } diff --git a/src/operator.js b/src/operator.js index 9703a8ce..629ad249 100644 --- a/src/operator.js +++ b/src/operator.js @@ -209,11 +209,6 @@ export function cachedValueOf(VectorClass, getSource) { }; } -/** - * @template {Function} F - * @param {F} org - * @returns {org} - */ function bindCache(org) { return function (...args) { if (inProgress === X) { @@ -275,25 +270,10 @@ export function defineMatrixLength(MatrixClass) { defineVectorLength(MatrixClass, CHECK_SUM); } -/** - * @template {} F, A - * @param {{new(...args: A[]): F}} VectorClass - * @returns {(...args: A[]) => F} - */ export function cachedFactory(VectorClass) { return bindCache((...args) => new VectorClass(...args)); } -/** - * @template T - * @typedef {{new(...args: any[]): T}} IsClass - */ - -/** - * @template {Function} F - * @param {F} fun - * @returns {F} - */ export function cachedFunction(fun) { return bindCache(fun); } diff --git a/src/point.js b/src/point.js index 375e771c..b269f60c 100644 --- a/src/point.js +++ b/src/point.js @@ -20,15 +20,6 @@ function square(val) { return val * val; } -/** - * @typedef {IPoint & number} IPointType - * @typedef {Point & number} PointType - * @typedef {() => number} Alg - * @typedef {APoint & number} APointType - */ -/** - * @abstract - */ class APoint { constructor(x, y) { if (typeof x === 'function') { @@ -44,24 +35,15 @@ class APoint { } } - /** - * @throws NotImplementedError - */ valueOf() { throw new Error('valueOf() not implemented, looks like you try to calculate outside of calc'); } - /** - * @returns {APointType} - */ normalize() { const { length } = this; return new this.constructor(this.x / length, this.y / length); } - /** - * @returns {APointType} - */ norm() { return this.normalize(); } @@ -69,42 +51,18 @@ class APoint { // methods ispired by // https://evanw.github.io/lightgl.js/docs/point.html - /** - * - * @param {APoint} v - * @returns {number} - */ dot(v) { return this.x * v.x + this.y * v.y; } - /** - * - * @returns {number} - */ getRad() { return normRad(Math.atan2(this.y, this.x)); } - /** - * - * @param {APoint} v - * @returns {number} - */ angleTo(v) { return angleOverGround(this.y, this.x, v.y, v.x); } - /** - * @typedef {import('./degree').Degree} Degree - * @typedef {import('./degree').IDegree} IDegree - * @typedef {IDegree | Degree | number} DegreeType - */ - /** - * - * @param {DegreeType} angle - * @returns {APointType} - */ rotate(angle) { const sa = Math.sin(angle); const ca = Math.cos(angle); @@ -115,158 +73,78 @@ class APoint { return new this.constructor(x, y); } - /** - * - * @param {APoint} v - * @returns {number} - */ distance(v) { return Math.sqrt(square(this.x - v.x) + square(this.y - v.y)); } - /** - * - * @param {APoint} v - * @returns {number} - */ dist(v) { return this.distance(v); } - /** - * - * @returns {[number, number]} - */ toArray() { return [this.x, this.y]; } - /** - * @param {(point: APointType) => number} alg - * @returns {this} - * @throws NotImplementedError ⚠ - */ calc(alg) { throw new Error('calc() not implemented'); } - /** - * @throws NotImplementedError ⚠ - * @returns {APoint} - */ clone() { throw new Error('clone() not implemented'); } - /** - * - * @param {APoint} v - * @returns {boolean} - */ equals(v) { return this.x === v.x && this.y === v.y; } - /** - * - * @returns {object} - */ toJSON() { return { x: this.x, y: this.y }; } - /** - * - * @returns {string} - */ toString() { return JSON.stringify(this.toJSON()); } - /** - * - * @returns {object} - */ toCSSVars(name, target) { return convertToCSSVars(name, this.toJSON(), target); } - /** - * - * @returns {number} - */ get lengthSq() { return this.dot(this); } - /** - * - * @returns {number} - */ get length() { return Math.sqrt(this.lengthSq); } - /** - * - * @returns {number} - */ get lensq() { return this.lengthSq; } - /** - * - * @returns {number} - */ get len() { return this.length; } - /** - * - * @returns {number} - */ get x() { return this[AXES][X]; } - /** - * - * @throws SetNotImplementedError - */ set x(_) { throw new Error('set x() not implemented'); } - /** - * - * @returns {number} - */ get y() { return this[AXES][Y]; } - /** - * - * @throws SetNotImplementedError - */ set y(_) { throw new Error('set y() not implemented'); } - /** - * - * @returns {number} - */ get z() { throw new Error('get z() not implemented'); } - /** - * - * @throws SetNotImplementedError - */ set z(_) { throw new Error('set z() not implemented'); } @@ -287,108 +165,47 @@ cachedGetter(APoint, 'length'); cachedGetter(APoint, 'lengthSq'); export class Point extends APoint { - /** - * - * @param {number} x - */ set x(x) { this[AXES][X] = x; } - /** - * - * @param {number} y - */ set y(y) { this[AXES][Y] = y; } - /** - * - * @returns {number} - */ get x() { return this[AXES][X]; } - /** - * - * @returns {number} - */ get y() { return this[AXES][Y]; } - /** - * @param {(point: PointType) => number} alg - * @returns {this} - */ calc(alg) { return operatorCalc(alg, this); } - /** - * @returns {APoint} - */ clone() { return new Point(this.x, this.y); } } export class IPoint extends APoint { - /** - * @returns {PointType} - */ toPoint() { return new Point(this.x, this.y); } } -/** - * @param {Alg} alg - * @return {PointType | IPointType} - */ export function calc(alg) { return operatorCalc(alg); } -/** - * @template P - * @typedef {() => P} PZero - */ -/** - * @template P - * @typedef {(alg: Alg) => P} PAlg - */ -/** - * @template P - * @typedef {(x: number, y: number) => P} PCon - */ -/** - * @template P - * @typedef {(data: [number, number]) => P} PArr - */ -/** - * @template P - * @typedef {(vec: { x: number, y: number }) => P} PObj - */ -/** - * @template P - * @typedef {PZero

& PAlg

& PCon

& PArr

& PObj

} Po - */ - const pointFactory = cachedFunction((x, y) => new Point(x, y)); -/** - * @type {Po} - */ export const point = (x, y) => pointFactory(x, y); const ipointFactory = cachedFunction((x, y) => new IPoint(x, y)); -/** - * @type {Po} - */ export const ipoint = (x, y) => ipointFactory(x, y); export const ZERO = ipoint(0, 0); diff --git a/src/quaternion.js b/src/quaternion.js index 403315a5..d46a564f 100644 --- a/src/quaternion.js +++ b/src/quaternion.js @@ -125,9 +125,6 @@ class AQuaternion { normalize(this[AXES]); } - /** - * @throws SetNotImplementedError - */ set(x, y, z, w) { throw new Error('set x() not implemented'); } @@ -178,11 +175,6 @@ class AQuaternion { return this.inverse; } - /** - * - * @param {AQuaternion} v - * @returns {boolean} - */ equals(v) { return this.x === v.x && this.y === v.y && this.z === v.z && this.w === v.w; } @@ -211,74 +203,38 @@ class AQuaternion { return this.up; } - /** - * - * @returns {number} - */ get x() { return this[AXES][X]; } - /** - * - * @throws SetNotImplementedError - */ set x(_) { throw new Error('set x() not implemented'); } - /** - * - * @returns {number} - */ get y() { return this[AXES][Y]; } - /** - * - * @throws SetNotImplementedError - */ set y(_) { throw new Error('set y() not implemented'); } - /** - * - * @returns {number} - */ get z() { return this[AXES][Z]; } - /** - * - * @throws SetNotImplementedError - */ set z(_) { throw new Error('set z() not implemented'); } - /** - * - * @returns {number} - */ get w() { return this[AXES][W]; } - /** - * - * @throws SetNotImplementedError - */ set w(_) { throw new Error('set w() not implemented'); } - /** - * - * @returns {object} - */ toJSON() { const { x, y, z, w @@ -301,18 +257,10 @@ class AQuaternion { }; } - /** - * - * @returns {string} - */ toString() { return JSON.stringify(this.toJSON()); } - /** - * - * @returns {object} - */ toCSSVars(name, target) { return convertToCSSVars(name, this.toJSON(), target); } @@ -322,12 +270,6 @@ cachedValueOf(AQuaternion); defineMatrixLength(AQuaternion); export class Quaternion extends AQuaternion { - /** - * @param {number | Quaternion | IQuaternion | Vector | Victor | [number, number, number, number] } [x] - * @param {number | Vector | Victor} [y] - * @param {number} [z] - * @param {number} [w] - */ set(x, y, z, w) { if (x instanceof AQuaternion) { this[AXES] = [...x[AXES]]; @@ -337,66 +279,34 @@ export class Quaternion extends AQuaternion { } } - /** - * - * @param {number} x - */ set x(x) { this[AXES][X] = x; } - /** - * - * @param {number} y - */ set y(y) { this[AXES][Y] = y; } - /** - * - * @param {number} z - */ set z(z) { this[AXES][Z] = z; } - /** - * - * @param {number} w - */ set w(w) { this[AXES][W] = w; } - /** - * - * @returns {number} - */ get x() { return this[AXES][X]; } - /** - * - * @returns {number} - */ get y() { return this[AXES][Y]; } - /** - * - * @returns {number} - */ get z() { return this[AXES][Z]; } - /** - * - * @returns {number} - */ get w() { return this[AXES][W]; } @@ -438,62 +348,14 @@ const q = new Quaternion(); const quaternionFactory = cachedFunction((x, y, z, w) => new Quaternion(x, y, z, w)); -/** - * @typedef {Vector | Victor} VectorType - */ -/** - * @template Q - * @typedef {() => Q} QuatZero - */ -/** - * @template Q - * @typedef {(x: number, y: number, z: number, w: number) => Q} QuatNumber - */ -/** - * @template Q - * @typedef {(dir: VectorType) => Q} QuatDir - */ -/** - * @template Q - * @typedef {(dir: VectorType, up: VectorType) => Q} QuatDirUp - */ -/** - * @template Q - * @typedef {(axis: VectorType, angle: number) => Q} QuatAxis - */ -/** - * @template Q - * @typedef {(arr: [number, number, number, number]) => Q} QuatArr - */ -/** - * @template Q - * @typedef {(q: { x: number, y: number, z: number, w: number }) => Q} QuatOther - */ -/** - * @template Q - * @typedef {QuatZero & QuatDir & QuatDirUp & QuatAxis & QuatArr & QuatZero & QuatOther} QuatFac - */ - -/** - * @type {QuatFac} - */ export const quaternion = (x, y, z, w) => quaternionFactory(x, y, z, w); const iquaternionFactory = cachedFunction((x, y, z, w) => new IQuaternion(x, y, z, w)); -/** - * @type {QuatFac} - */ export const iquaternion = (x, y, z, w) => iquaternionFactory(x, y, z, w); const LEFT90 = new IQuaternion(LEFT, degree(90)); -/** - * - * @param {{ alpha: number, beta: number, gamma: number }} orientationEvent - * @param {number} orientation - * @returns {IQuaternion & number} - */ export function fromOrientation({ alpha, beta, gamma }, orientation) { let rot = iquaternion(UP, degree(alpha)) .mul(RIGHT, degree(beta)) diff --git a/src/utils/math.js b/src/utils/math.js index df4da1e5..e6708071 100644 --- a/src/utils/math.js +++ b/src/utils/math.js @@ -85,6 +85,15 @@ export function multiplyVecMat3(vecLeft, [column0, column1, column2]) { ); } +export function multiplyVecMat4(vecLeft, [column0, column1, column2, column3]) { + return new vecLeft.constructor( + vecLeft.dot(column0), + vecLeft.dot(column1), + vecLeft.dot(column2), + vecLeft.dot(column3) + ); +} + export function isNumber(nr) { if (typeof nr === 'number' || (nr && nr.constructor === Number)) { return true; diff --git a/src/vector.js b/src/vector.js index c316f3fa..0cd6ec55 100644 --- a/src/vector.js +++ b/src/vector.js @@ -17,17 +17,6 @@ function square(val) { return val * val; } -/** - * @typedef {IPoint & number} VecIPointType - * @typedef {Victor & number} VictorType - * @typedef {Vector & number} VectorType - * @typedef {() => number} Alg - * @typedef {AVector & number} AVectorType - */ - -/** - * @abstract - */ class AVector { constructor(x, y, z) { if (typeof x === 'function') { @@ -43,16 +32,10 @@ class AVector { } } - /** - * @throws NotImplementedError - */ valueOf() { throw new Error('valueOf() not implemented, looks like you try to calculate outside of calc'); } - /** - * @returns {AVectorType} - */ normalize() { const { length } = this; return new this.constructor( @@ -62,9 +45,6 @@ class AVector { ); } - /** - * @returns {AVectorType} - */ norm() { return this.normalize(); } @@ -72,19 +52,10 @@ class AVector { // methods ispired by // https://evanw.github.io/lightgl.js/docs/vector.html - /** - * - * @param {AVectorType} v - * @returns {number} - */ dot(v) { return this.x * v.x + this.y * v.y + this.z * v.z; } - /** - * @param {AVectorType} v - * @returns {AVectorType} - */ cross(v) { return new this.constructor( this.y * v.z - this.z * v.y, @@ -93,10 +64,6 @@ class AVector { ); } - /** - * @param {AVectorType} v - * @returns {AVectorType} - */ crossNormalize(v) { const vec = this.cross(v); const { length } = vec; @@ -106,18 +73,10 @@ class AVector { return vec; } - /** - * @param {AVectorType} v - * @returns {AVectorType} - */ cn(v) { return this.crossNormalize(v); } - /** - * - * @returns {{ theta: number, phi: number }} - */ toAngles() { return { theta: Math.atan2(this.z, this.x), @@ -125,20 +84,10 @@ class AVector { }; } - /** - * - * @param {AVectorType} v - * @returns {number} - */ angleTo(v) { return normRad(acos(this.dot(v) / (this.length * v.length))); } - /** - * - * @param {{ x: number, y: number, z: number, w: number }} quat - * @returns {AVectorType} - */ multiply(quat) { if (quat.x === undefined) { return this.multiplyMat3(quat); @@ -161,38 +110,20 @@ class AVector { ); } - /** - * - * @param {AVectorType} v - * @returns {number} - */ distance(v) { return Math.sqrt( square(this.x - v.x) + square(this.y - v.y) + square(this.z - v.z), ); } - /** - * - * @param {AVectorType} v - * @returns {number} - */ dist(v) { return this.distance(v); } - /** - * - * @returns {[number, number, number]} - */ toArray() { return [this.x, this.y, this.z]; } - /** - * @param {string} target - * @returns {VectorType | VictorType | VecIPointType} - */ swizzle(target) { const data = target.split('') .map(t => this[t]); @@ -202,207 +133,106 @@ class AVector { return new this.constructor(data[0], data[1], data[2]); } - /** - * @param {(vector: AVectorType) => number} arg - * @returns {this} - * @throws NotImplementedError ⚠ - */ calc(arg) { throw new Error('calc() not implemented'); } - /** - * - * @throws NotImplementedError ⚠ - * @return {AVectorType} - */ clone() { throw new Error('clone() not implemented'); } - /** - * - * @param {AVectorType} v - * @returns {boolean} - */ equals(v) { return this.x === v.x && this.y === v.y && this.z === v.z; } - /** - * - * @returns {object} - */ toJSON() { return { x: this.x, y: this.y, z: this.z }; } - /** - * - * @returns {string} - */ toString() { return JSON.stringify(this.toJSON()); } - /** - * - * @returns {object} - */ toCSSVars(name, target) { return convertToCSSVars(name, this.toJSON(), target); } - /** - * - * @returns {number} - */ get lengthSq() { return this.dot(this); } - /** - * - * @throws SetNotImplementedError - */ set lengthSq(_) { throw new Error('set lengthSq() not implemented'); } - /** - * - * @returns {number} - */ get length() { return Math.sqrt(this.lengthSq); } - /** - * - * @throws SetNotImplementedError - */ set length(_) { throw new Error('set length() not implemented'); } - /** - * - * @returns {number} - */ get lensq() { return this.lengthSq; } - /** - * - * @throws SetNotImplementedError - */ set lensq(_) { throw new Error('set lensq() not implemented'); } - /** - * - * @returns {number} - */ get len() { return this.length; } - /** - * - * @throws SetNotImplementedError - */ set len(_) { throw new Error('set len() not implemented'); } - /** - * - * @returns {number} - */ get x() { return this[AXES][X]; } - /** - * - * @throws SetNotImplementedError - */ set x(_) { throw new Error('set x() not implemented'); } - /** - * - * @returns {number} - */ get y() { return this[AXES][Y]; } - /** - * - * @throws SetNotImplementedError - */ set y(_) { throw new Error('set y() not implemented'); } - /** - * - * @returns {number} - */ get z() { return this[AXES][Z]; } - /** - * - * @throws SetNotImplementedError - */ set z(_) { throw new Error('set z() not implemented'); } - /** - * @returns {VecIPointType} - */ get xy() { return new IPoint(this[AXES][X], this[AXES][Y]); } - /** - * @throws SetNotImplementedError - */ set xy(_) { throw new Error('set xz() not implemented'); } - /** - * @returns {VecIPointType} - */ get xz() { return new IPoint(this[AXES][X], this[AXES][Z]); } - /** - * @throws SetNotImplementedError - */ set xz(_) { throw new Error('set xz() not implemented'); } - /** - * @returns {VecIPointType} - */ get yz() { return new IPoint(this[AXES][Y], this[AXES][Z]); } - /** - * @throws SetNotImplementedError - */ set yz(_) { throw new Error('set yz() not implemented'); } @@ -426,131 +256,59 @@ cachedGetter(AVector, 'length'); cachedGetter(AVector, 'lengthSq'); export class Vector extends AVector { - /** - * - * @param {number} x - */ set x(x) { this[AXES][X] = x; } - /** - * - * @param {number} y - */ set y(y) { this[AXES][Y] = y; } - /** - * - * @param {number} z - */ set z(z) { this[AXES][Z] = z; } - /** - * - * @returns {number} - */ get x() { return this[AXES][X]; } - /** - * - * @returns {number} - */ get y() { return this[AXES][Y]; } - /** - * - * @returns {number} - */ get z() { return this[AXES][Z]; } - /** - * @param {(vector: AVectorType) => number} alg - * @returns {this} - */ calc(alg) { return operatorCalc(alg, this); } - /** - * @returns {AVectorType} - */ clone() { return new Vector(this.x, this.y, this.z); } } export class Victor extends AVector { - /** - * @returns {VictorType} - */ toVector() { return new Vector(this.x, this.y, this.z); } - /** - * @returns {AVectorType} - */ clone() { return this; } } -/** - * @param {Alg} alg - * @return {VectorType | VictorType} - */ export function calc(alg) { return operatorCalc(alg); } -/** - * @template V - * @typedef {() => V} VecZero - */ -/** - * @template V - * @typedef {(alg: Alg) => V} VecAlg - */ -/** - * @template V - * @typedef {(x: number, y: number, z: number) => V} VecCon - */ -/** - * @template V - * @typedef {(data: [number, number, number]) => V} VecArr - */ -/** - * @template V - * @typedef {(vec: { x: number, y: number, z: number }) => V} VecObj - */ -/** - * @template V - * @typedef {VecZero & VecAlg & VecCon & VecArr & VecObj} Vec - */ - const vectorFactory = cachedFunction((x, y, z) => new Vector(x, y, z)); -/** - * @type {Vec} - */ export const vector = (x, y, z) => vectorFactory(x, y, z); const victorFactory = cachedFunction((x, y, z) => new Victor(x, y, z)); -/** - * @type {Vec} - */ export const victor = (x, y, z) => victorFactory(x, y, z); export const ZERO = victor(0, 0, 0);