diff --git a/src/findAll.js b/src/findAll.js new file mode 100644 index 0000000..1abadba --- /dev/null +++ b/src/findAll.js @@ -0,0 +1,69 @@ +import Quad from "./quad"; + +export default function(x, y, radius) { + var data, + x0 = this._x0, + y0 = this._y0, + x1, + y1, + x2, + y2, + x3 = this._x1, + y3 = this._y1, + quads = [], + node = this._root, + q, + i, + result = []; + + if (node) quads.push(new Quad(node, x0, y0, x3, y3)); + if (radius == null) radius = Infinity; + else { + x0 = x - radius, y0 = y - radius; + x3 = x + radius, y3 = y + radius; + radius *= radius; + } + + while (q = quads.pop()) { + + // Stop searching if this quadrant can’t contain a closer node. + if (!(node = q.node) + || (x1 = q.x0) > x3 + || (y1 = q.y0) > y3 + || (x2 = q.x1) < x0 + || (y2 = q.y1) < y0) continue; + + // Bisect the current quadrant. + if (node.length) { + var xm = (x1 + x2) / 2, + ym = (y1 + y2) / 2; + + quads.push( + new Quad(node[3], xm, ym, x2, y2), + new Quad(node[2], x1, ym, xm, y2), + new Quad(node[1], xm, y1, x2, ym), + new Quad(node[0], x1, y1, xm, ym) + ); + + // Visit the closest quadrant first. + if (i = (y >= ym) << 1 | (x >= xm)) { + q = quads[quads.length - 1]; + quads[quads.length - 1] = quads[quads.length - 1 - i]; + quads[quads.length - 1 - i] = q; + } + } + + // Visit this point. If within radius, add it. + else { + var dx = x - +this._x.call(null, node.data), + dy = y - +this._y.call(null, node.data), + d2 = dx * dx + dy * dy; + if (d2 < radius) { + // add all coincidence points as well + do result.push(node.data); while (node = node.next); + } + } + } + + return result; +} diff --git a/src/quadtree.js b/src/quadtree.js index faf2a6b..2bafac6 100644 --- a/src/quadtree.js +++ b/src/quadtree.js @@ -3,6 +3,7 @@ import tree_cover from "./cover"; import tree_data from "./data"; import tree_extent from "./extent"; import tree_find from "./find"; +import tree_findAll from "./findAll"; import tree_remove, {removeAll as tree_removeAll} from "./remove"; import tree_root from "./root"; import tree_size from "./size"; @@ -63,6 +64,7 @@ treeProto.cover = tree_cover; treeProto.data = tree_data; treeProto.extent = tree_extent; treeProto.find = tree_find; +treeProto.findAll = tree_findAll; treeProto.remove = tree_remove; treeProto.removeAll = tree_removeAll; treeProto.root = tree_root;