47 lines
1.3 KiB
JavaScript
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};
|
|
}
|
|
}
|