UNPKG

@thi.ng/geom-arc

Version:

2D circular / elliptic arc operations

50 lines (49 loc) 1.64 kB
import { isNumber } from "@thi.ng/checks/is-number"; import { isPlainObject } from "@thi.ng/checks/is-plain-object"; import { DEFAULT_SAMPLES } from "@thi.ng/geom-resample/api"; import { Sampler } from "@thi.ng/geom-resample/sampler"; import { TAU } from "@thi.ng/math/api"; import { cartesian2 } from "@thi.ng/vectors/cartesian"; import { pointAtTheta } from "./point-at.js"; const sample = (pos, r, axis, start, end, opts) => { if (isPlainObject(opts) && opts.dist !== void 0) { return new Sampler( sample( pos, r, axis, start, end, opts.num || DEFAULT_SAMPLES ) ).sampleUniform(opts.dist, opts.last !== false); } opts = isNumber(opts) ? { num: opts, last: true } : { num: DEFAULT_SAMPLES, ...opts }; let delta = end - start; let num = opts.theta ? Math.round(delta / opts.theta) : opts.num; delta /= num; opts.last !== false && num++; const pts = new Array(num); for (let i = 0; i < num; i++) { pts[i] = pointAtTheta(pos, r, axis, start + i * delta); } return pts; }; const sampleCircular = (origin, r, a, b, out = [], steps = 8, outwards = true, addLast = true) => { let ta = Math.atan2(a[1] - origin[1], a[0] - origin[0]); let tb = Math.atan2(b[1] - origin[1], b[0] - origin[0]); ta < 0 && (ta += TAU); tb < 0 && (tb += TAU); const theta = ta > tb ? ta - tb : ta + TAU - tb; const delta = (outwards ? -theta : TAU - theta) / steps; out.push(a); for (let i = 1; i < steps; i++) { out.push(cartesian2(null, [r, ta + delta * i], origin)); } addLast && out.push(b); return out; }; export { sample, sampleCircular };