Skip to content

Instantly share code, notes, and snippets.

@ToJans
Created February 17, 2022 21:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ToJans/b3817a63c25295bcc86e701f5a94e593 to your computer and use it in GitHub Desktop.
Save ToJans/b3817a63c25295bcc86e701f5a94e593 to your computer and use it in GitHub Desktop.
Here's a super compact vector class that supports multiple dimensions
class CVector {
constructor(components = []) { this.components = components; }
get lengthSquared() { return this.components.reduce((p, c) => p + c * c); }
get length() { return Math.sqrt(this.lengthSquared); }
get normalized() { return new CVector(this.components.map(x => x / this.length)); }
get sum() { return Math.sum(this.components); }
add(other, missingComponentValue = 0) { return this._zip(other, (a, b) => a + b, missingComponentValue); }
sub(other, missingComponentValue = 0) { return this._zip(other, (a, b) => a - b, missingComponentValue); }
mul(other, missingComponentValue = 1) { return this._zip(other, (a, b) => a * b, missingComponentValue); }
div(other, missingComponentValue = 1) { return this._zip(other, (a, b) => a / b, missingComponentValue); }
dist(other, missingComponentValue = 0) { return this.sub(other).length }
lerp(other, p) { return this._zip(other, (a, b) => a * p + b * (1 - p)); }
lerpScalar(other, p) { return this.lerp(other, p / this.dist(other)); }
clamp(min, max) { return this._zip(min, Math.min)._zip(max, Math.max); }
clampLength(min, max) { return this.mul(new CVector(), Math.max(min, Math.min(max, this.length)) / this.length) };
cross(other) { return this._rol(1).mul(other); }
dot(other) { return this.mul(other).sum; }
_rol(n = 1) { return new CVector(this.components.splice(n).concat(this.components.splice(0, n))); }
_zip(other, fn = (a, b) => [a, b], missingComponentValue = NaN) {
let cA = this.components, cB = other.components, diff = cA.length - cB.length;
if (diff != 0) {
const filler = new Array(Math.abs(diff)).fill(missingComponentValue);
if (diff < 0) {
cA = cA.concat(filler);
} else if (diff > 0) {
cB = cB.concat(filler);
}
}
return new CVector(cA.map((x, i) => fn(x, cB[i])));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment