private Point2D Nearest(KdNode node, RectHV rect, double x, double y, Point2D candidate)
{
if (node == null)
{
return(candidate);
}
double dqn = 0;
double drq = 0;
var query = new Point2D(x, y);
var nearest = candidate;
if (nearest != null)
{
dqn = query.DistanceSquaredTo(nearest);
drq = rect.DistanceSquaredTo(query);
}
if (nearest == null || dqn < drq)
{
var point = new Point2D(node.X, node.Y);
if (nearest == null || dqn > query.DistanceSquaredTo(point))
{
nearest = point;
}
}
var left = LeftRect(rect, node);
var right = RightRect(rect, node);
if (node.Vertical)
{
if (x < node.X)
{
nearest = Nearest(node.Left, left, x, y, nearest);
nearest = Nearest(node.Right, right, x, y, nearest);
}
else
{
nearest = Nearest(node.Right, right, x, y, nearest);
nearest = Nearest(node.Left, left, x, y, nearest);
}
}
else
{
if (y < node.Y)
{
nearest = Nearest(node.Left, left, x, y, nearest);
nearest = Nearest(node.Right, right, x, y, nearest);
}
else
{
nearest = Nearest(node.Right, right, x, y, nearest);
nearest = Nearest(node.Left, left, x, y, nearest);
}
}
return(nearest);
}