0

I'm trying to write a method, which will return the index of a point which is closest to another point in 3D space. The points are stored in a KD-tree and I'm comparing them with the point p which is a parameter of my method. Here is the method:

public int NearestPointWithDistance(KDnnTreeNode node, Point p, Double distance){
  int index = -1;
  if(node == null){
     return -1;
  }else{
      double[] point_coordinates = data[node.eltIndex];
      Point q = new Point(point_coordinates[0],point_coordinates[1], point_coordinates[2]);
      if(KDnnTree.distance(p, q) == distance){
             return index;
      }  

      if(node.left != null){
          final int left_child = NearestPointWithDistance(node.left, p, distance);
      }
      if(node.right != null){
          final int right_child = NearestPointWithDistance(node.right, p, distance);
        }
    }
  return index;

}

The problem is, there could be multiple points with the same distance. The result I get is a list of indexes of points(see below), but I want only the first element of the list (in the example below, that would be the number 54510).

54510
54511
54512
54514
54518
54526
54543
54577
65355
76175
54482
54416
54278
21929
54001
74323 

I know this is not the way to search two closes points in a KD tree, but I would like to try this way first.

TheAptKid
  • 1,559
  • 3
  • 25
  • 47

1 Answers1

0

Don't use java.lang.Double as argument. Use double.

The reason is that if your KDNTree.distance() would also return Double you will end up in comparing references of objects, not their values.

You have pretty inconvenient API. Anyway, make a helper function:

public Point getNodePoint(Node node)
{
    double[] point_coordinates = data[node.eltIndex];
    return new Point(point_coordinates[0],point_coordinates[1], point_coordinates[2]);
}

Use the best distance availabale selections:

double result = KDnnTree.distance(p, q);
if (result == distance)
{
   return node.eltIndex;
}
index = node.eltIndex; // assume given node is best
if (node.left !=  null)
{
    final int left_child = NearestPointWithDistance(node.left, p, distance);
    double left_distance = KDnnTree.distance(p, getNodePoint(left_child);

    if (Math.abs(distance - result) > Math.abs(distance - left_distance))
    {
        // result given is closer to wanted point
        result = left_distance;
        index = left_child;
    }
}
if (node.right !=  null)
{
    final int right_child = NearestPointWithDistance(node.right, p, distance);
    double right_distance = KDnnTree.distance(p, getNodePoint(right_child);

    if (Math.abs(distance - result) > Math.abs(distance - right_distance))
    {
        // result given is closer to wanted point
        result = right_distance;
        index = right_child;
    }
}
return index;
Valeri Atamaniouk
  • 5,125
  • 2
  • 16
  • 18