gravity/vector.js
2026-01-03 10:34:32 -06:00

47 lines
1.3 KiB
JavaScript

export const dot = (a, b) => a.x * b.x + a.y * b.y;
export const cross = (a, b) => a.x * b.y - a.y * b.x;
export const add = (a, b) => ({x: a.x + b.x, y: a.y + b.y});
export const sub = (a, b) => ({x: a.x - b.x, y: a.y - b.y});
export const square = ({x, y}) => x ** 2 + y ** 2;
export const magnitude = ({x, y}) => Math.sqrt(square({x, y}));
export const mult = (v, m) => {
if (v.x !== undefined) return {x: v.x * m, y: v.y * m};
else return {x: m.x * v, y: m.y * v};
};
export const div = (v, m) => ({x: v.x / m, y: v.y / m});
export const zero = {x: 0, y: 0};
export const weightedAvg = (items) => {
let res = zero;
let W = 0;
for (const [v, w] of items) {
res = add(res, mult(v, w));
W += w;
}
return div(res, W);
};
// Angle is given counterclockwise, assuming screen coordinates
export const direction = ({x, y}) => Math.atan2(-y, x) * 180 / Math.PI;
export class Vector {
x = undefined;
y = undefined;
constructor({x, y}) {
this.x = x;
this.y = y;
}
dot(v) {return dot(this, v);}
cross(v) {return cross(this, v);}
add(v) {return new Vector(add(this, v));}
sub(v) {return new Vector(sub(this, v));}
magnitude() {return magnitude(this);}
mult(m) {return new Vector(mult(this, m));}
div(m) {return new Vector(div(this, m));}
toJSON() {
return {x: this.x, y: this.y};
}
}