从理论的角度来看,我需要一些帮助头脑风暴。现在我有一些代码只是绘制一些对象。物体位于四叉树的叶子中。现在,当对象移动时,我想将它们放置在四叉树的正确叶子中。
现在我只是在改变位置后重建物体上的四叉树。我试图想出一种方法来纠正树而不是完全重建它。我能想到的只是有一堆指向相邻叶节点的指针。
有没有人知道如何找出一个对象移动到的节点,而不是在任何地方都有大量的指针或链接到这个文章?我所能找到的只是构建四叉树的不同方法,而不是更新它。
答案 0 :(得分:2)
如果我理解你的问题。您想要在四叉树上的空间坐标和叶子之间进行某种映射。
这是我一直在寻找的一种可能的解决方案:
为简单起见,让我们先做1D案例。我们假设我们在x中有32个网格点。然后,每个网格点对应于深度为五的四叉树上的一些叶子。 (深度0 =整个网格,深度1 = 2点,深度2 = 4点...深度5 = 32点)。
每个叶子可以由通向叶子的分支索引表示。在每个级别有两个分支,我们可以标记A和B.因此,一个特定的叶子可能被标记为BBAAB,这意味着,沿着B分支,然后是B分支,然后是A分支,然后是B分支,然后B分支。
那么,你如何映射,例如BBABB到x网格点在0..31之间?只需将其转换为二进制,以便BBABB-> 11011 = 27.因此,从网格点到叶节点的映射只需将字母A和B转换为0和1,然后将结果解释为二进制数
对于2D情况,它只是稍微复杂一点。现在我们从每个节点有四个分支,因此我们可以使用四个字母的字母标记每个分支路径,例如从根开始,然后取第3个分支,然后是第4个分支,然后是第一个分支,然后是第二个分支,然后是第二个分支,再次生成字符串CDABB。
现在将字符串(例如'CDABB')转换为一对网格值(x,y)。
假设A是左下角,B是右下角,C是左上角,D是右上角。然后,象征性地,我们可以写,A.x = 0,A.y = 0 / B.x = 1,B.y = 0 / C.x = 0,C.y = 1 / D.x = 1,D.y = 1.
以CDABB为例,我们首先看一下它的x值(CDABB).x =(01011),它给出了x网格点。同样适用于你。
最后,如果你想找出例如紧接着CDABB右边的节点,然后简单地将它转换为x和y中的一对二进制数,将x加1,并将新的二进制数转换回字符串。
我确信这一切都已被发现,但我还没有在网上找到这些信息。
答案 1 :(得分:1)
如果你有一个元素首先插入四元树所需的空间数据(例如:它的点或矩形),那么你有相同的数据来删除它。
一种简单的方法是在移动元素之前,使用您最初插入的相同数据将其从四叉树中移除,然后移动它,然后重新插入。
从四叉树中删除可以先从叶节点中删除元素,然后如果叶节点变空,则从父节点中删除它们。如果父母变空,将其从父母那里移除,等等。
只要您有效地实现四叉树(例如:为节点使用空闲列表),这种简单方法就足以满足每帧移动的复杂对象世界。不应该在每个节点上进行堆分配以插入它,也不必在删除每个节点时涉及堆释放。大多数节点分配/解除分配应该是一个简单的恒定时间操作,仅涉及操作几个整数或指针。
如果你愿意,你也可以把它变得更复杂一些。您可以开始存储对象的先前位置,然后移动它。如果新位置占用除前一个位置以外的节点,则从不再占用的节点中删除该对象并将其插入新节点。否则只需将其保存在同一节点中即可。
<强>更新强>
我通常会尽量避免将之前的答案联系起来,但在这种情况下,我最终对该主题做了一个非常全面的写作,这在其他任何地方都难以复制。这是:https://stackoverflow.com/a/48330314/4842163