@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
JavaScript
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
};