我有一个非常大的点云(> 100000 个点),我想在其中检测平面排列。我决定使用八叉树将这些点分解为非常小的平面簇,然后合并共面的相邻簇。我已经用 C++ 编写了代码,可以将点云快速拆分成小的平面集群,但是如何有效地合并它们却让我望而却步……
我的Octree
实现使用指针结构:有OctreeNode
s 的数组OctreeNode* children[8]
包含指向其子节点的指针,或者NULL
如果它是叶节点,则为所有指针。
我的第一个想法是在每个OctreeNode
对象中保留一个指向Plane
对象的指针。在第一次分割点之后,八叉树中的每个叶子都会得到一个Plane
代表叶子中包含的所有点的最小二乘拟合。然后我遍历树中的每个叶节点。对于每个叶节点,我检查它的每个相邻叶节点:如果邻居的平面应该与当前叶的平面合并,我调用Plane* newPlane = Plane::mergePlanes(this->plane, neighbor->plane);
创建一个表示两个节点中的点的新平面。
这就是我遇到麻烦的地方......我首先认为我可以简单地用新平面替换两个平面,即plane = newPlane; neighbor->plane = newPlane;
完成(除了内存泄漏;我在真实代码中处理它们)。不幸的是,这在实践中不起作用。合并几个平面后,可能会有几个不同OctreeNode
的 s 指向一个 s Plane
,并且只需替换其中的指针,this->plane
而neighbor->plane
不是替换指向其旧平面的每个指针。
甚至当我第一次想出这个解决方案时,它似乎也很老套,现在它的缺陷更加明显。任何人都可以想出一种方法来修复我提出的合并方法,或者想出更好的方法吗?
谢谢