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