Files
ai-coding-workflow-labs/gstack/src/geom-engine/vec.js
T
tiennm99 51a4b90163 refactor: migrate quiz-project, gstack, and superpowers to JS+JSDoc
Convert all 41 TypeScript source/config files in cc4e-course/quiz-project
(Next.js), gstack (Astro), and superpowers (Vite/React/Phaser) to plain
JavaScript with JSDoc type annotations, replacing tsconfig.json with
jsconfig.json (strict + checkJs) in each subproject. No behavior changes:
lint, typecheck, test, and build gates match their TypeScript baselines
exactly in all three subprojects. Update stack references in the affected
READMEs accordingly.
2026-08-18 09:49:42 +07:00

91 lines
1.5 KiB
JavaScript

/**
* @typedef {{ readonly x: number, readonly y: number }} Vec2
*/
export const EPSILON_LEN = 0.5;
export const EPSILON_ANGLE_DEG = 0.5;
/**
* @param {number} x
* @param {number} y
* @returns {Vec2}
*/
export function vec(x, y) {
return { x, y };
}
/**
* @param {Vec2} a
* @param {Vec2} b
* @returns {Vec2}
*/
export function add(a, b) {
return { x: a.x + b.x, y: a.y + b.y };
}
/**
* @param {Vec2} a
* @param {Vec2} b
* @returns {Vec2}
*/
export function sub(a, b) {
return { x: a.x - b.x, y: a.y - b.y };
}
/**
* @param {Vec2} a
* @param {number} k
* @returns {Vec2}
*/
export function scale(a, k) {
// `+ 0` normalizes IEEE-754 -0 back to +0 so consumers comparing coordinates
// with === or Object.is don't see a signed-zero ghost from k=0 paths.
return { x: a.x * k + 0, y: a.y * k + 0 };
}
/**
* @param {Vec2} a
* @param {Vec2} b
* @returns {number}
*/
export function dot(a, b) {
return a.x * b.x + a.y * b.y;
}
/**
* @param {Vec2} a
* @returns {number}
*/
export function len(a) {
return Math.hypot(a.x, a.y);
}
/**
* @param {Vec2} a
* @param {Vec2} b
* @returns {number}
*/
export function dist(a, b) {
return Math.hypot(a.x - b.x, a.y - b.y);
}
/**
* @param {Vec2} a
* @returns {Vec2}
*/
export function normalize(a) {
const l = len(a);
if (l === 0) return { x: 0, y: 0 };
return { x: a.x / l, y: a.y / l };
}
/**
* @param {number} a
* @param {number} b
* @param {number} [eps]
* @returns {boolean}
*/
export function approxEqualLen(a, b, eps = EPSILON_LEN) {
return Math.abs(a - b) < eps;
}