【发布时间】:2023-04-08 16:35:01
【问题描述】:
我正在寻找一种方法来收集一组体素。体素是一个 3D 单元,可以是完整的/空的/未知的,并且建立在点云之上(用于数据缩减)。一旦构建的体素集合永远不会被修改(每轮销毁和重建),但需要不同类型的访问(邻域,迭代所有,直接)。 体素空间非常稀疏,在空间中可能有 1.000.000 个体素无序,最多仅使用 1000 个。
所以我决定使用(因为使用 c++ 后无序)hashmap 以体素 ID 作为键来收集它们(我认为八叉树是一种矫枉过正)。现在我需要一个函数来将 3D 点转换为体素 ID,并将 ID 转换为体素 3D 点质心。
我发现困难的是一种非常快速的方法,我希望将它们键为单个 int 值,例如:
unsigned int VoxelsMap::pointToVoxelId(const Vector3f & point){
unsigned int id = 0;
int x = (int)floor(roundpoint[0]);
int y = (int)floor(roundpoint[1]);
int z = (int)floor(roundpoint[2]);
id = A-BIJECTIVE-FUNCTION(x, y, z);
return id;
}
但是对于双射函数,我不能很快提出任何东西(至于之前的演员表等,我不喜欢必须经常使用的函数(200FPS x ~1000 x 3))。
所以:
- hashmap 是不是一个好的数据结构(让我担心的是邻域搜索)
- 什么可以是 A-BIJECTIVE-FUNCTION 或整个函数的函数
谢谢。
【问题讨论】:
-
体素空间一维的最大可能尺寸是多少?如果它不超过 1024,您可以将
x、y和z索引作为 10 位数字连接成一个 30(或更确切地说是 32)位数字。将是一个非常快速和简单的解决方案。 -
是的,我可以通过一些工作使其达到 1024... 详细说明答案,如果没有更好的,我接受它。谢谢!
-
使用 64 位整数,您可以消除每个维度 1024 个最大体素的限制。显然不是完全“免费”的。阅读本文以获取更多信息stackoverflow.com/questions/16841382/…
-
我认为获取线性 ID 的规范方法是将它们交错。我相信在英特尔上有 simd 说明。