C++ 八叉树容器

Posted

技术标签:

【中文标题】C++ 八叉树容器【英文标题】:C++ Octree Container 【发布时间】:2012-07-13 11:17:36 【问题描述】:

我在整个网络上搜索了有关八叉树容器如何工作的解释。我找不到任何关于如何工作的明确解释。 (至少,这对我来说很有意义......)有谁知道如何实现一个八叉树容器?一个有 8 个孩子(左右)。如果是这样,你介意分享/解释逻辑......或者我可以去哪里学习如何实现一个。

【问题讨论】:

en.wikipedia.org/wiki/Octree - 这能告诉你你需要知道什么吗? 先尝试学习四叉树。然后将想法从 2d 扩展到 3d,您将得到八叉树。 @OliCharlesworth 不,这并不能告诉我任何事情。 :( @Ohmages:那你卡在哪里了?***文章中的第三句话说“八叉树是四叉树的 3D 等价物”...... @OliCharlesworth 我是编码高级主题的新手。我不知道八叉树容器只是四叉树的扩展。我被困在你如何从头开始合乎逻辑地构建一个。其背后的逻辑是什么?它使用两个容器吗?它在类中使用虚函数吗?孩子们的部分是如何工作的?生病研究四叉树(因为有更多信息),看看它是否有意义:/ 【参考方案1】:

你的问题很笼统。但我会试着给你这个想法。请注意,有很多方法可以实现八叉树,这都取决于您的应用程序。在这个例子中,我将专注于简单的情况,你总是在中间分开。

让我们先从简单的开始。假设您有一组数字(一维数据)。您可能希望对它们进行分组,以便更轻松地搜索它们。一种方法(即使在这种特殊情况下存在更好的方法)是创建一棵树。让我们称它为 bittree(这样它就不会与二叉树混为一谈,尽管它一种二叉树)。

在这个比特树中,每个节点将代表一个范围的中间。左边的值会小于这个值,右边的值会更大。树的根当然代表最小值和最大值之间的中间值。在每个叶子中,如果您的值超出您的处理能力,则拆分并创建一个子树。例如,如果您的值介于 0 和 100 之间,则比特树可能如下所示:

                  50
              /        \
           25            75
         /    \        /    \
        12   27,33  62    
      /    \        /    \
   1,3  13   51,52 72

这棵树代表这个数组:

1, 3, 13, 27, 33, 51, 52, 72

我假设你熟悉二叉树,所以实现这样的树对你来说应该不是问题。

这里的关键是,每个叶子最多可以包含一定数量的节点。每次插入bittree时,如果叶子溢出,则获取其范围的中间,创建一个节点并将值划分为两个叶子。

现在让我们将其扩展到 2d。想象一下,您的值采用(x,y) 的形式(而不仅仅是x)。我们可以像上面一样划分这些值,但不是将它们划分为中间的左右,而是将它们划分为中心的左上、左下、右上和右下。其余的完全一样。我们称之为四叉树,因为它有 4 个孩子。这个四叉树的实现和二叉树完全一样,所以你现在应该可以理解了。

一个来自***的例子,其中每个叶子只能包含 1 个值:

最后一步是将其扩展到 3d。和以前一样,现在的值是(x,y,z) 的形式。这次,不是将值划分为 4 个区域,而是将它们划分为 8 个区域:左上前、左上后、左下前、左下后、右上前、右上-后,右前和右后。我们称之为八叉树,其实现又与其他的完全相同。

我对你如何从头开始构建一个逻辑感到困惑。其背后的逻辑是什么?它使用两个容器吗?它在类中使用虚函数吗?儿童部分如何工作?

同样,实现二叉树的方式完全相同。如果你在那里使用虚函数,你也可以在八叉树中使用虚函数。

【讨论】:

哇!非常感谢!这很有帮助。但是现在我被困在如何在八叉树(或四叉树)中迭代(向前)。我有代码,但不知道是否应该提出新问题或在此处发布。 @Ohmages,这取决于你想如何迭代。如果你想要所有的值,BFS、有序、DFS 或你在二叉树上使用的任何东西也适用于四叉树和八叉树。如果你想搜索某些东西,你决定使用与二叉搜索树相同的方式。例如,在四叉树中,如果您在节点n 寻找位置(x,y),则应根据x > node.xy > node.y 是真还是假(4 种组合)转到其中一个子树。如果您的问题更复杂,请尝试将其作为其他问题发布。

以上是关于C++ 八叉树容器的主要内容,如果未能解决你的问题,请参考以下文章

在八叉树中合并叶子

点云 | 求异(附C++源码)

PCL学习八叉树

PCL——八叉树Octree

Mark四叉树与八叉树

何时使用二进制空间分区、四叉树、八叉树?