UNPKG

@thi.ng/geom-accel

Version:

n-D spatial indexing data structures with a shared ES6 Map/Set-like API

55 lines (54 loc) 1.71 kB
import { isNumber } from "@thi.ng/checks/is-number"; import { Heap } from "@thi.ng/heaps/heap"; import { clamp } from "@thi.ng/math/interval"; import { addN2 } from "@thi.ng/vectors/addn"; import { distSq2 } from "@thi.ng/vectors/distsq"; import { subN2 } from "@thi.ng/vectors/subn"; import { ASpatialGrid } from "./aspatial-grid.js"; import { __addResults, CMP } from "./utils.js"; const TMP = []; class SpatialGrid2 extends ASpatialGrid { constructor(min, size, res) { super(min, size, isNumber(res) ? [res, res] : res); this._cells = new Array(this._res[0] * this._res[1]); } copy() { return super.copy(); } empty() { return new SpatialGrid2(this._min, this._size, this._res); } doQuery(fn, k, r, limit = Infinity, acc = []) { const id1 = this.findIndex(subN2(TMP, k, r)); const id2 = this.findIndex(addN2(TMP, k, r)); const stride = this._res[0]; const x1 = id1 % stride; const x2 = id2 % stride; const y1 = (id1 / stride | 0) * stride; const y2 = (id2 / stride | 0) * stride; const cells = this._cells; let c; let x, y; r *= r; const heap = new Heap([[r]], { compare: CMP }); const sel = heap.values; for (y = y1; y <= y2; y += stride) { for (x = x1; x <= x2; x++) { c = cells[y + x]; c?.length && this.queryCell(distSq2, heap, c, k, limit); } } return __addResults(fn, sel, acc); } findIndex(k) { const { _min: min, _res1: res1, _invSize: invSize } = this; const kx = clamp((k[0] - min[0]) * invSize[0], 0, res1[0]); const ky = clamp((k[1] - min[1]) * invSize[1], 0, res1[1]); return (kx | 0) + (ky | 0) * this._res[0]; } } export { SpatialGrid2 };