我正在制作四叉树,需要帮助将对象插入其中。我理解这样做的概念,但我不擅长递归和 Java 传递变量的方式。
我有一个 Quadtree 类,其中包含一个名为 root 的节点。Node 类内部有四个 Node,它们是组成它的四个四边形。创建四叉树时会创建根节点,并且在调用 createChildrenQuads() 之前不会创建每个节点内的四个节点。但是,对于根节点,在创建四叉树时会调用该方法。
所以我关于如何将项目插入节点的思考过程是这样的:
- 从根节点开始
- 对于每个节点:
- 检查并查看当前项目适合当前节点的哪个子节点
- 如果它适合其中一个,则将其插入该节点(调用递归方法并重新开始)
- 如果它不适合任何东西,请将其添加到当前节点的对象列表中并完成
基于此,我创建了这个:
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 通过值而不是引用传递参数,所以当我将它添加到正确的位置时,它并没有得到“保存”,因为它只是一个局部变量。我相信这是问题所在,但我可能是错的。
所以我尝试对其进行一些更改以使其插入方法返回当前节点,以便所有内容都应该正确“保存”。这就是我想出的:
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;
}
但是,我仍然有同样的问题。现在我不确定我的问题是什么。
我正在将它用于游戏,并且我拥有它以便它在所有四边形所在的位置绘制轮廓,并且我可以单击以将实体添加到四叉树中。我的代码的两个版本似乎都是一样的。发生的情况是,当我将实体添加到四叉树时,它会被添加并保留在那里,所以我猜我关于它没有得到“保存”的理论是因为 Java 传递引用的方式是错误的。
但是,我的代码应该(至少在我的脑海中应该)将每个实体放入四叉树中尽可能低的级别,在每个节点沿着树向下时在每个节点中创建新的子四边形。但实际发生的情况是,有时它似乎只是将新实体添加到当前四边形中,根本不下树,或者它下降一两个级别,就是这样,当它很容易下降几个更多级别。
任何人都可以看到代码或我的逻辑有什么问题吗?