Skip to content

Commit

Permalink
Optional search radius.
Browse files Browse the repository at this point in the history
  • Loading branch information
mbostock committed May 15, 2016
1 parent b21c20d commit b195931
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 9 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,9 @@ Returns an array of all data in the quadtree.

Returns the total number of data in the quadtree.

<a name="quadtree_find" href="#quadtree_find">#</a> <i>quadtree</i>.<b>find</b>(<i>x</i>, <i>y</i>)
<a name="quadtree_find" href="#quadtree_find">#</a> <i>quadtree</i>.<b>find</b>(<i>x</i>, <i>y</i>[, <i>radius</i>])

Given a point *x*,*y*, returns the closest datum in the quadtree. If the quadtree is empty, returns undefined.
Returns the datum closest to the position *x*,*y* with the given search *radius*. If *radius* is not specified, it defaults to infinity. If there is no datum within the search area, returns undefined.

<a name="quadtree_visit" href="#quadtree_visit">#</a> <i>quadtree</i>.<b>visit</b>(<i>callback</i>)

Expand Down
19 changes: 12 additions & 7 deletions src/find.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import Quad from "./quad";

export default function(x, y) {
var minDistance2 = Infinity,
minPoint,
export default function(x, y, radius) {
var data,
x0 = this._x0,
y0 = this._y0,
x1,
Expand All @@ -17,6 +16,12 @@ export default function(x, y) {
i;

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()) {

Expand Down Expand Up @@ -52,14 +57,14 @@ export default function(x, y) {
var dx = x - +this._x.call(null, node.data),
dy = y - +this._y.call(null, node.data),
d2 = dx * dx + dy * dy;
if (d2 < minDistance2) {
var d = Math.sqrt(minDistance2 = d2);
if (d2 < radius) {
var d = Math.sqrt(radius = d2);
x0 = x - d, y0 = y - d;
x3 = x + d, y3 = y + d;
minPoint = node.data;
data = node.data;
}
}
}

return minPoint;
return data;
}
19 changes: 19 additions & 0 deletions test/find-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,22 @@ tape("quadtree.find(x, y) returns the closest point to the given [x, y]", functi
test.deepEqual(q.find(15.9, 15.9), [16, 16]);
test.end();
});

tape("quadtree.find(x, y, radius) returns the closest point within the search radius to the given [x, y]", function(test) {
var q = d3_quadtree.quadtree([[0, 0], [100, 0], [0, 100], [100, 100]]);
test.deepEqual(q.find(20, 20, Infinity), [0, 0]);
test.deepEqual(q.find(20, 20, 20 * Math.SQRT2 + 1e-6), [0, 0]);
test.equal(q.find(20, 20, 20 * Math.SQRT2 - 1e-6), undefined);
test.deepEqual(q.find(0, 20, 20 + 1e-6), [0, 0]);
test.equal(q.find(0, 20, 20 - 1e-6), undefined);
test.deepEqual(q.find(20, 0, 20 + 1e-6), [0, 0]);
test.equal(q.find(20, 0, 20 - 1e-6), undefined);
test.end();
});

tape("quadtree.find(x, y, null) treats the given radius as Infinity", function(test) {
var q = d3_quadtree.quadtree([[0, 0], [100, 0], [0, 100], [100, 100]]);
test.deepEqual(q.find(20, 20, null), [0, 0]);
test.deepEqual(q.find(20, 20, undefined), [0, 0]);
test.end();
});

0 comments on commit b195931

Please sign in to comment.