我正在制作一个四叉树,需要帮助插入一个物体。我理解这样做的概念,但我对递归和Java传递变量的方式不太了解。
我有一个Quadtree类,其中包含一个名为root的节点。 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通过值传递参数而不是引用,所以当我在正确的位置添加它时,它不会被“保存”,因为它只是一个局部变量。我相信这是问题,但我可能是错的。
所以我尝试更改它以使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传递了引用是错误的。
但是,我的代码应该(至少在我看来应该)将每个实体放入四叉树中尽可能低的级别,在每个节点中沿着树向下创建新的子四边形。实际上发生的事情是,有时它似乎只是将新实体添加到当前的四边形中,而不是完全从树上下来,或者它下降到一两级,就是它,当它可以很容易地减少一些更多层次。
任何人都可以看到代码或我的逻辑有什么问题吗?
答案 0 :(得分:2)
我认为这是你构建程序的方式。四叉树可以测试每个象限,但它总是在最后添加元素......所以即使它会以递归的方式向下移动,但在备份的过程中,它将始终运行您的最后一个n.m_objects.add(e);
因此,在通过递归的方式上更改它的添加位置。您需要将其更改为If (..) else if (...) else (...)