在Java中将对象插入到四叉树中

时间:2011-10-20 00:27:53

标签: java algorithm tree quadtree

我正在制作一个四叉树,需要帮助插入一个物体。我理解这样做的概念,但我对递归和Java传递变量的方式不太了解。

我有一个Quadtree类,其中包含一个名为root的节点。 Node类里面有四个节点,它们是构成它的四个四边形。创建四叉树时会创建根节点,并且在调用createChildrenQuads()之前不会创建每个节点内的四个节点。但是,对于根节点,在创建四叉树时会调用该方法。

所以关于如何将项目插入节点的思考过程是这样的:

  1. 从根节点开始
  2. 对于每个节点:
    1. 检查并查看当前节点的子节点当前的四倍 项目适合
    2. 如果它适合其中一个,请将其插入其中 node(调用递归方法并重新开始)
    3. 如果不适合 any,将其添加到当前节点的对象列表中并完成
  3. 基于此,我创建了这个:

    public void insert(Entity e) {
        insert(root, e);
    }
    
    private void insert(Node n, Entity e){
        Rectangle temp = e.getRectangle();
    
        if (!n.childrenHaveBeenCreated())
            n.createChildrenQuads(n.m_quadRect);
    
        //first check which node it can go into
    
        if ( n.NW.m_quadRect.contains(temp)) {
            n.NW = insert(n.NW, e);
            return;
        }
    
        if ( n.NE.m_quadRect.contains(temp)) {
            n.NE = insert(n.NE, e);
            return;
        }
    
        if ( n.SW.m_quadRect.contains(temp)) {
            n.SW = insert(n.SW, e);
            return;
        }
    
        if ( n.SE.m_quadRect.contains(temp)) {
            n.SE = insert(n.SE, e);
            return;
        }
    
        n.m_objects.add(e);
    }
    

    我认为四分法,我在那里的逻辑很好。当我调试代码时,看起来一切正常。但是,我认为我的问题是Java通过值传递参数而不是引用,所以当我在正确的位置添加它时,它不会被“保存”,因为它只是一个局部变量。我相信这是问题,但我可能是错的。

    所以我尝试更改它以使insert方法返回当前节点,以便所有内容都能正确“保存”。这就是我想出的:

    public void insert(Entity e) {
        root = insert(root, e);
    }
    
    private Node insert(Node n, Entity e) {
        Rectangle temp = s.getRectangle();
    
        if (!n.childrenHaveBeenCreated())
            n.createChildrenQuads(n.m_quadRect);
    
        //first check which node it can go into
    
        if ( n.NW.m_quadRect.contains(temp)) {
            n.NW = insert(n.NW, e);
            return n;
        }
    
        if ( n.NE.m_quadRect.contains(temp)) {
            n.NE = insert(n.NE, e);
            return n;
        }
    
        if ( n.SW.m_quadRect.contains(temp)) {
            n.SW = insert(n.SW, e);
            return n;
        }
    
        if ( n.SE.m_quadRect.contains(temp)) {
            n.SE = insert(n.SE, e);
            return n;
        }
    
        n.m_objects.add(e);
        return n;
    }
    

    但是,我仍有同样的问题。现在我不确定我的问题是什么。

    我正在将它用于游戏,并且我已经拥有它以便绘制所有四边形所在的轮廓,并且我可以单击以将实体添加到四叉树中。我的代码的两个版本似乎都是一样的。当我向quadtree添加一个实体时,它会被添加并保留在那里,所以我猜我的理论没有得到“保存”,因为Java传递了引用是错误的。

    但是,我的代码应该(至少在我看来应该)将每个实体放入四叉树中尽可能低的级别,在每个节点中沿着树向下创建新的子四边形。实际上发生的事情是,有时它似乎只是将新实体添加到当前的四边形中,而不是完全从树上下来,或者它下降到一两级,就是它,当它可以很容易地减少一些更多层次。

    任何人都可以看到代码或我的逻辑有什么问题吗?

1 个答案:

答案 0 :(得分:2)

我认为这是你构建程序的方式。四叉树可以测试每个象限,但它总是在最后添加元素......所以即使它会以递归的方式向下移动,但在备份的过程中,它将始终运行您的最后一个n.m_objects.add(e); 因此,在通过递归的方式上更改它的添加位置。您需要将其更改为If (..) else if (...) else (...)

的更多内容