我有一个很大的点云(> 100000个点),我想检测其中的平面排列。我决定使用八叉树将这些点分成非常小的平面簇,然后合并共面的相邻簇。我已经用C++编写了将点云快速拆分成小的平面簇的代码,但是如何有效地合并它们却使我难以理解。

我的Octree实现使用了一个指针结构:有OctreeNode,数组OctreeNode* children[8]包含指向其子节点的指针,或者所有NULL指针(如果它是叶节点)。

我的第一个想法是,在每个OctreeNode对象中,都保留一个指向Plane对象的指针。第一次分割点后,八叉树中的每个叶子都会得到一个Plane,该Plane* newPlane = Plane::mergePlanes(this->plane, neighbor->plane);表示与叶子中包含的所有点的最小二乘拟合。然后,我遍历树中的每个叶节点。对于每个叶子节点,我检查其每个相邻叶子节点:如果邻居的平面应与当前叶子的平面合并,则调用plane = newPlane; neighbor->plane = newPlane;创建一个新平面,该平面代表两个节点中的点。

这是我遇到麻烦的地方...我首先想到我可以简单地用新飞机(即OctreeNode)替换两个飞机,然后完成(不包括内存泄漏;我用实际代码处理了它们)。不幸的是,这在实践中不起作用。合并多个平面后,可能会有多个不同的Plane指向单个this->plane,并且简单地替换neighbor->plane和ojit_code中的指针并不能替换指向其旧平面的每个指针。

即使当我第一次提出该解决方案时,该解决方案似乎也很糟糕,现在它的缺陷更加明显。谁能想到一种解决我提出的合并方法的方法,还是想到一种更好的方法?

谢谢

最佳答案

标准修复是延迟修复节点。有一个访问方法,该方法可以查看您指向的平面,然后查看它是否已指向其他位置。如果有,请递归搜索直到找到它的位置,然后将所有对象固定回当前对象,然后再交回右平面。

这比跟随指针要昂贵得多,但是实际上这并不像您想的那样昂贵,因为在大多数情况下,最终对象位于您所看到的第一或第二位。

关于c++ - 合并八叉树中的叶子,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5808948/

10-16 00:54