构造3D KD树

时间:2016-05-25 03:38:19

标签: java recursion tree spatial kdtree

所以我试图从随机生成的点列表中构建一个3D KD树。我也试图以递归方式完成这项任务。但是在我的递归中,当我试图对我的点列表进行分区时,我遇到了错误。我的代码如下:

public class Scratch {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        ArrayList<Point> points = new ArrayList<Point>();
        Random rand = new Random(System.currentTimeMillis());
        for (int i = 0; i < 100; i++) {
            double x = rand.nextInt(100);
            double y = rand.nextInt(100);
            double z = rand.nextInt(100);
            Point point = new Point(x, y, z);
            points.add(point);
        }
        Node root = kdtree(points, 0);
        System.out.println("Done");
    }

    static class Node {

        Node leftChild;
        Node rightChild;
        Point location;

        Node() {

        }

        Node(Node leftChild, Node rightChild, Point location) {
            this.leftChild = leftChild;
            this.rightChild = rightChild;
            this.location = location;
        }
    }

    public static Node kdtree(ArrayList<Point> points, int depth) {
        int axis = depth % 3;
        switch (axis) {
            case 0:
                Collections.sort(points, Point.X_COMPARATOR);
                break;
            case 1:
                Collections.sort(points, Point.Y_COMPARATOR);
                break;
            case 2:
                Collections.sort(points, Point.Z_COMPARATOR);
                break;
            default:
                break;
        }
        int middle = points.size() / 2;
        Point median = points.get(middle);

        ArrayList<Point> greater = new ArrayList<Point>(points.subList(0, (middle - 1)));
        ArrayList<Point> lesser = new ArrayList<Point>(points.subList((middle + 1), (points.size())));
        Node node = new Node();
        node.location = median;
        if(greater.size() == 0 || lesser.size() == 0) {
            node.leftChild = null;
            node.rightChild = null;
        } else {
            node.leftChild = kdtree(lesser, depth + 1);
            node.rightChild = kdtree(greater, depth + 1);
        }        
        return node;
    }

}

类点是一个包含x,y和z坐标的简单对象。并且根据树的深度使用三个比较器。 我得到的错误如下:

Exception in thread "main" java.lang.IllegalArgumentException: fromIndex(0) > toIndex(-1)
    at java.util.ArrayList.subListRangeCheck(ArrayList.java:1006)
    at java.util.ArrayList.subList(ArrayList.java:996)
    at scratch.Scratch.kdtree(Scratch.java:71)
    at scratch.Scratch.kdtree(Scratch.java:80)
    at scratch.Scratch.kdtree(Scratch.java:79)
    at scratch.Scratch.kdtree(Scratch.java:79)
    at scratch.Scratch.kdtree(Scratch.java:79)
    at scratch.Scratch.kdtree(Scratch.java:79)
    at scratch.Scratch.main(Scratch.java:32)

1 个答案:

答案 0 :(得分:0)

我会在这里继续猜测并说如果你在点数组上只有一个点(或0),当你做中间= points.size / 2等于0(整数除法)然后当你尝试要创建一个从0到-1的子列表,它会抛出异常。