export const copy = (v) => ({x: v.x, y: v.y}); 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; 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})); // Arguments must be one vector and one scalar, but can be transposed export const mult = (v, m) => { if (typeof v === 'object') return {x: v.x * m, y: v.y * m}; else if (typeof m === 'object') return {x: m.x * v, y: m.y * v}; else throw new Error('mult: no vector provided'); }; 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); }; export const components = (mag, dir) => mult(mag, { x: Math.cos(dir), y: Math.sin(dir), }); export const direction = ({x, y}) => Math.atan2(y, x); export const degrees = (rad) => rad * 180 / Math.PI; export const add = (...vectors) => { let res = zero; for (const v of vectors) { res = _add(res, v); } return res; }