UNPKG

pocket-physics

Version:

Verlet physics extracted from pocket-ces demos

129 lines (128 loc) 3.49 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.angleOf = exports.rotate2d = exports.vd = exports.translate = exports.perpDot = exports.normal = exports.normalize = exports.magnitude = exports.distance2 = exports.distance = exports.scale = exports.dot = exports.sub = exports.add = exports.set = exports.copy = exports.v2 = void 0; function v2(x, y) { return { x: x || 0, y: y || 0 }; } exports.v2 = v2; const copy = (out, a) => { out.x = a.x; out.y = a.y; return out; }; exports.copy = copy; const set = (out, x, y) => { out.x = x; out.y = y; return out; }; exports.set = set; const add = (out, a, b) => { out.x = (a.x + b.x); out.y = (a.y + b.y); return out; }; exports.add = add; const sub = (out, a, b) => { out.x = (a.x - b.x); out.y = (a.y - b.y); return out; }; exports.sub = sub; const dot = (a, b) => a.x * b.x + a.y * b.y; exports.dot = dot; const scale = (out, a, factor) => { out.x = (a.x * factor); out.y = (a.y * factor); return out; }; exports.scale = scale; const distance = (v1, v2) => { const x = v1.x - v2.x; const y = v1.y - v2.y; return Math.sqrt(x * x + y * y); }; exports.distance = distance; const distance2 = (v1, v2) => { const x = v1.x - v2.x; const y = v1.y - v2.y; return x * x + y * y; }; exports.distance2 = distance2; const magnitude = (v1) => { const x = v1.x; const y = v1.y; return Math.sqrt(x * x + y * y); }; exports.magnitude = magnitude; const normalize = (out, a) => { const x = a.x; const y = a.y; let len = x * x + y * y; if (len > 0) { len = 1 / Math.sqrt(len); out.x = (a.x * len); out.y = (a.y * len); } return out; }; exports.normalize = normalize; /** * Compute the normal pointing away perpendicular from two vectors. * Given v1(0,0) -> v2(10, 0), the normal will be (0, 1) * */ const normal = (out, v1, v2) => { out.y = (v2.x - v1.x); out.x = (v1.y - v2.y); return (0, exports.normalize)(out, out); }; exports.normal = normal; // the perpendicular dot product, also known as "cross" elsewhere // http://stackoverflow.com/a/243977/169491 const perpDot = (v1, v2) => { return v1.x * v2.y - v1.y * v2.x; }; exports.perpDot = perpDot; /** * This is mostly useful for moving a verlet-style [current, previous] * by the same amount, translating them while preserving velocity. * @param by the vector to add to each subsequent vector * @param vN any number of vectors to translate */ const translate = (by, ...vN) => { for (let i = 0; i < vN.length; i++) { const v = vN[i]; (0, exports.add)(v, v, by); } }; exports.translate = translate; /** * * @param v Print this vector for nice logs */ function vd(v) { return `(${v.x}, ${v.y})`; } exports.vd = vd; /** * Rotate a vector around another point. Taken nearly verbatim from gl-matrix */ const rotate2d = (out, target, origin, rad) => { //Translate point to the origin const p0 = target.x - origin.x; const p1 = target.y - origin.y; const sinC = Math.sin(rad); const cosC = Math.cos(rad); //perform rotation and translate to correct position out.x = p0 * cosC - p1 * sinC + origin.x; out.y = p0 * sinC + p1 * cosC + origin.y; return out; }; exports.rotate2d = rotate2d; /** * Compute the Theta angle between a vector and the origin. */ function angleOf(v) { return Math.atan2(v.y, v.x); } exports.angleOf = angleOf;