Skip to content

Commit

Permalink
findInCircle
Browse files Browse the repository at this point in the history
closes #30
  • Loading branch information
Fil committed Jul 7, 2020
1 parent 9804ee5 commit c863e59
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 0 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,11 @@ Returns the total number of data in the quadtree.

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_findInCircle" href="#quadtree_findInCircle">#</a> <i>quadtree</i>.<b>findInCircle</b>(<i>x</i>, <i>y</i>[, <i>radius</i>][, <i>filter</i>])
[<>](https://github.com/d3/d3-quadtree/blob/master/src/findInCircle.js "Source")

Returns all the data within the given search *radius* of the position ⟨*x*,*y*⟩ that satisfy the filter *filter*, if specified. If *radius* is not specified, it defaults to infinity. If there is no acceptable datum within the search area, returns an empty array.

<a name="quadtree_visit" href="#quadtree_visit">#</a> <i>quadtree</i>.<b>visit</b>(<i>callback</i>)
[<>](https://github.com/d3/d3-quadtree/blob/master/src/visit.js "Source")

Expand Down
22 changes: 22 additions & 0 deletions src/findInCircle.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
export default function(x, y, radius, filter) {
const quadtree = this,
result = [],
radius2 = radius * radius,
accept = filter
? d => filter(d) && result.push(d)
: d => result.push(d);

quadtree.visit(function(node, x1, y1, x2, y2) {
if (node.length) {
return x1 >= x + radius || y1 >= y + radius || x2 < x - radius || y2 < y - radius;
}

const dx = +quadtree._x.call(null, node.data) - x,
dy = +quadtree._y.call(null, node.data) - y;
if (dx * dx + dy * dy < radius2) {
do { accept(node.data); } while (node = node.next);
}
});

return result;
}
2 changes: 2 additions & 0 deletions src/quadtree.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import tree_cover from "./cover.js";
import tree_data from "./data.js";
import tree_extent from "./extent.js";
import tree_find from "./find.js";
import tree_findInCircle from "./findInCircle.js";
import tree_remove, {removeAll as tree_removeAll} from "./remove.js";
import tree_root from "./root.js";
import tree_size from "./size.js";
Expand Down Expand Up @@ -63,6 +64,7 @@ treeProto.cover = tree_cover;
treeProto.data = tree_data;
treeProto.extent = tree_extent;
treeProto.find = tree_find;
treeProto.findInCircle = tree_findInCircle;
treeProto.remove = tree_remove;
treeProto.removeAll = tree_removeAll;
treeProto.root = tree_root;
Expand Down
21 changes: 21 additions & 0 deletions test/findInCircle-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
var tape = require("tape"),
d3_quadtree = require("../");

tape("quadtree.findInCircle(x, y, radius) returns all the points within the search radius of the given [x, y]", function(test) {
const points = [[0, 0], [100, 0], [0, 100], [100, 100]];
const q = d3_quadtree.quadtree(points);
test.deepEqual(q.findInCircle(20, 20, Infinity), points);
test.deepEqual(q.findInCircle(20, 20, 20 * Math.SQRT2 + 1e-6), [points[0]]);
test.deepEqual(q.findInCircle(20, 20, 20 * Math.SQRT2 - 1e-6), []);
test.deepEqual(q.findInCircle(50, 0, 51), [points[0], points[1]]);
test.end();
});

tape("quadtree.findInCircle(x, y, radius, filter) returns all the points within the search radius of the given [x, y] and passing filter", function(test) {
const points = [[0, 0, "a"], [0, 0, "b"], [100, 0, "a"], [0, 100, "b"], [100, 100, "a"]];
const q = d3_quadtree.quadtree(points);
const filter = d => d[2] === "a";
test.deepEqual(q.findInCircle(20, 20, Infinity, filter), points.filter(filter));
test.deepEqual(q.findInCircle(0, 0, 2, filter), [points[0]]);
test.end();
});

0 comments on commit c863e59

Please sign in to comment.