public Point2D nearest(Point2D p) { // a nearest neighbor in the set to p; null if set is empty Stack<Point2D> stack = new Stack<Point2D>(); nearestNode(root, p, stack, 2.0); return stack.pop(); }
private void nearestNode(Node2d node, Point2D queryP, Stack<Point2D> stack, double distance) { if (node == null) return; if (distance < node.rect.distanceSquaredTo(queryP)) return; if (queryP.distanceSquaredTo(node.p) < distance) { stack.push(node.p); distance = queryP.distanceSquaredTo(node.p); } if (node.depth % 2 == 0) { if (queryP.x() < node.p.x()) { distance = queryP.distanceSquaredTo(stack.peek()); nearestNode(node.left, queryP, stack, distance); distance = queryP.distanceSquaredTo(stack.peek()); nearestNode(node.right, queryP, stack, distance); } else { distance = queryP.distanceSquaredTo(stack.peek()); nearestNode(node.right, queryP, stack, distance); distance = queryP.distanceSquaredTo(stack.peek()); nearestNode(node.left, queryP, stack, distance); } } else { if (queryP.y() < node.p.y()) { distance = queryP.distanceSquaredTo(stack.peek()); nearestNode(node.left, queryP, stack, distance); distance = queryP.distanceSquaredTo(stack.peek()); nearestNode(node.right, queryP, stack, distance); } else { distance = queryP.distanceSquaredTo(stack.peek()); nearestNode(node.right, queryP, stack, distance); distance = queryP.distanceSquaredTo(stack.peek()); nearestNode(node.left, queryP, stack, distance); } } }