UNPKG

@thi.ng/distance

Version:

N-dimensional distance metrics & K-nearest neighborhoods for point queries

80 lines (79 loc) 1.88 kB
import { clamp0 } from "@thi.ng/math/interval"; import { DIST_SQ, DIST_SQ1, DIST_SQ2, DIST_SQ3 } from "./squared.js"; class Radial { constructor(dist, target, radius = Infinity) { this.dist = dist; this.target = target; this.radius = radius; this.setRadius(radius); } _r; _items; /** * Clears current results. */ reset() { this._items = []; return this; } /** * Resets search/reference position and clears current results. * * @param target */ setTarget(target) { this.target = target; this.reset(); } /** * Resets search/query radius and clears current results. * * @param r */ setRadius(r) { this.radius = clamp0(r); this._r = this.dist.to(this.radius); this.reset(); } /** * Returns an array of current neighbor result tuples (each `[dist, val]`). * * @remarks * Use {@link Radial.values} to obtain result values **without** their * distance metrics. */ deref() { return this._items; } /** * Similar to {@link Radial.deref}, but returns array of result values **without** * their distance metrics. */ values() { return this._items.map((x) => x[1]); } includesDistance(d, eucledian = true) { return (eucledian ? this.dist.to(d) : d) <= this._r; } includesPosition(pos) { return this.dist.metric(this.target, pos) < this._r; } consider(pos, val) { const d = this.dist.metric(this.target, pos); if (d <= this._r) { this._items.push([d, val]); } return d; } } const radial = (p, r, dist = DIST_SQ) => new Radial(dist, p, r); const radial2 = (p, r, dist = DIST_SQ2) => new Radial(dist, p, r); const radial3 = (p, r, dist = DIST_SQ3) => new Radial(dist, p, r); const radialN = (p, r, dist = DIST_SQ1) => new Radial(dist, p, r); export { Radial, radial, radial2, radial3, radialN };