public List<T> findClosestNeighbours(double x, double y, double radius, int maxCount) { NearestNeighborGatherer<T> gatherer = new NearestNeighborGatherer<>(x, y, radius, maxCount); if (root != null) { root.findNearestNeighbors(0, gatherer); } return gatherer.getResults(); }
@Override public void findNearestNeighbors(int depth, NearestNeighborGatherer<T> gatherer) { final int visitedTree; final boolean xAxis = (depth % 2) == 0; if (xAxis) { // split on X-axis if (gatherer.x < splitValue) { // left subtree visitedTree = LEFT; if (left != null) { if (left.isLeaf()) { gatherer.addCandidate((LeafNode<T>) left); } else { left.findNearestNeighbors(depth + 1, gatherer); } } } else { // right subtree visitedTree = RIGHT; if (right != null) { if (right.isLeaf()) { gatherer.addCandidate((LeafNode<T>) right); } else { right.findNearestNeighbors(depth + 1, gatherer); } } } } else // split on Y-axis { if (gatherer.y < splitValue) { // left subtree visitedTree = LEFT; if (left != null) { if (left.isLeaf()) { gatherer.addCandidate((LeafNode<T>) left); } else { left.findNearestNeighbors(depth + 1, gatherer); } } } else { // right subtree visitedTree = RIGHT; if (right != null) { if (right.isLeaf()) { gatherer.addCandidate((LeafNode<T>) right); } else { right.findNearestNeighbors(depth + 1, gatherer); } } } } if (!gatherer.isFull()) { // check if the other subtree may contain values that are closer // than the point farthest out we've found so far final double distance; if (xAxis) { distance = Math.abs(gatherer.x - splitValue); } else { distance = Math.abs(gatherer.y - splitValue); } final boolean isWithinRadius = distance <= gatherer.radius; if (right != null && isWithinRadius && visitedTree == LEFT) { if (right.isLeaf()) { gatherer.addCandidate((LeafNode<T>) right); } else { right.findNearestNeighbors(depth + 1, gatherer); } } else if (left != null && isWithinRadius && visitedTree == RIGHT) { if (left.isLeaf()) { gatherer.addCandidate((LeafNode<T>) left); } else { left.findNearestNeighbors(depth + 1, gatherer); } } } }