mirror of
https://github.com/Azgaar/Fantasy-Map-Generator.git
synced 2025-12-17 09:41:24 +01:00
84 lines
2.4 KiB
JavaScript
84 lines
2.4 KiB
JavaScript
import * as d3 from "d3";
|
||
|
||
// findAll d3.quandtree search from https://bl.ocks.org/lwthatcher/b41479725e0ff2277c7ac90df2de2b5e
|
||
export function addFindAll() {
|
||
const Quad = function (node, x0, y0, x1, y1) {
|
||
this.node = node;
|
||
this.x0 = x0;
|
||
this.y0 = y0;
|
||
this.x1 = x1;
|
||
this.y1 = y1;
|
||
};
|
||
|
||
const tree_filter = function (x, y, radius) {
|
||
var t = {x, y, x0: this._x0, y0: this._y0, x3: this._x1, y3: this._y1, quads: [], node: this._root};
|
||
if (t.node) {
|
||
t.quads.push(new Quad(t.node, t.x0, t.y0, t.x3, t.y3));
|
||
}
|
||
radiusSearchInit(t, radius);
|
||
|
||
var i = 0;
|
||
while ((t.q = t.quads.pop())) {
|
||
i++;
|
||
|
||
// Stop searching if this quadrant can’t contain a closer node.
|
||
if (
|
||
!(t.node = t.q.node) ||
|
||
(t.x1 = t.q.x0) > t.x3 ||
|
||
(t.y1 = t.q.y0) > t.y3 ||
|
||
(t.x2 = t.q.x1) < t.x0 ||
|
||
(t.y2 = t.q.y1) < t.y0
|
||
)
|
||
continue;
|
||
|
||
// Bisect the current quadrant.
|
||
if (t.node.length) {
|
||
t.node.explored = true;
|
||
var xm = (t.x1 + t.x2) / 2,
|
||
ym = (t.y1 + t.y2) / 2;
|
||
|
||
t.quads.push(
|
||
new Quad(t.node[3], xm, ym, t.x2, t.y2),
|
||
new Quad(t.node[2], t.x1, ym, xm, t.y2),
|
||
new Quad(t.node[1], xm, t.y1, t.x2, ym),
|
||
new Quad(t.node[0], t.x1, t.y1, xm, ym)
|
||
);
|
||
|
||
// Visit the closest quadrant first.
|
||
if ((t.i = ((y >= ym) << 1) | (x >= xm))) {
|
||
t.q = t.quads[t.quads.length - 1];
|
||
t.quads[t.quads.length - 1] = t.quads[t.quads.length - 1 - t.i];
|
||
t.quads[t.quads.length - 1 - t.i] = t.q;
|
||
}
|
||
}
|
||
|
||
// Visit this point. (Visiting coincident points isn’t necessary!)
|
||
else {
|
||
var dx = x - +this._x.call(null, t.node.data),
|
||
dy = y - +this._y.call(null, t.node.data),
|
||
d2 = dx * dx + dy * dy;
|
||
radiusSearchVisit(t, d2);
|
||
}
|
||
}
|
||
return t.result;
|
||
};
|
||
|
||
d3.quadtree.prototype.findAll = tree_filter;
|
||
|
||
var radiusSearchInit = function (t, radius) {
|
||
t.result = [];
|
||
(t.x0 = t.x - radius), (t.y0 = t.y - radius);
|
||
(t.x3 = t.x + radius), (t.y3 = t.y + radius);
|
||
t.radius = radius * radius;
|
||
};
|
||
|
||
var radiusSearchVisit = function (t, d2) {
|
||
t.node.data.scanned = true;
|
||
if (d2 < t.radius) {
|
||
do {
|
||
t.result.push(t.node.data);
|
||
t.node.data.selected = true;
|
||
} while ((t.node = t.node.next));
|
||
}
|
||
};
|
||
}
|