我正在寻找一种收集一组体素的方法。体素是可以是满/空/未知的3D单元,并且建立在点云上(用于数据缩减)。构建后的体素集合永远不会被修改(每轮都会被破坏和重建),但需要不同类型的访问(睦邻、迭代、直接)。体素空间非常非常稀疏,在1.000.000的数量级之外,空间中最多只使用1000个可能的体素。
因此,我决定使用一个(由于使用c++,所以是无序的)哈希图来收集它们(我认为八叉树是一种过度处理),并将体素ID作为关键字。现在我需要一个函数来转换三维点到体素ID和ID到体素三维点质心。
我发现困难的是一种非常快速的方法,我想让它们作为一个单一的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;
}
但对于双射函数,我不能很快想出任何东西(就像之前的cast等,我不喜欢经常使用的函数(200FPS x ~ 1000 x 3))。
因此:
- hashmap是一个好的数据结构吗(让我担心的是邻居搜索)
- 什么是a-BIJECTIVE-function的函数或整个函数
谢谢。
#include <iostream>
using namespace std;
int main()
{
int x = 2.1474e+009;
int y = -2097152;
int z = -2048;
int rx = x;
int ry = y << 10;
int rz = z << 20;
int hashed = rx + ry + rz;
x = rx;
y = ry >> 10;
z = rz >> 20;
cout << hashed << endl;
cout << x << " " << y << " " << z << endl;
return 0;
}
这个hash/unhash方法应该是最快的。注意,我只使用了32位整数中的30位。这允许最大世界大小为4.2950e+009 x 4194304 x 4096。如果你想扩展世界极限,你必须使用更多/更大的整数。
希望这能有所帮助。
是否希望以链接每个相邻体素的方式按空间收集它们?如果这是你想要的,那么你可以在3D中使用Hoshen Kopelman算法。为此编写代码应该需要一两天的时间,你就完成了。链接中的exmaple用于2D;将其扩展到3D根本不是问题。
希望这能有所帮助。
为什么不为哈希图使用更精细的键?您可以使用x、y、z坐标构建元组,或者实现自己的结构,而不是简单的int。后面的选项需要实现运算符==()和散列函数。关于一个好的散列函数的一些信息可以在这里找到。