3D空间中的体素唯一ID

时间:2013-11-29 12:45:35

标签: c++ 3d voxels

我正在寻找一种收集一组体素的方法。体素是可以是满/空/未知的3D单元,并且构建在点云上(用于数据缩减)。一旦建成的体素集合永远不会被修改(每一轮被破坏和重建),但需要不同类型的访问(相邻,迭代,直接)。 体素空间非常稀疏,在空间中仅使用最多1000个可能的体素1.000.000。

所以我决定使用(使用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))。

所以:

  • 是一个很好的数据结构的哈希映射(让我担心的是邻居搜索)
  • 什么可以是A-BIJECTIVE-FUNCTION或整个功能的功能

感谢。

3 个答案:

答案 0 :(得分:3)

#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.如果要扩展世界限制,则必须使用更多/更大的整数。

希望这可以提供帮助。

答案 1 :(得分:1)

你想以链接每个相邻体素的方式在空间上收集它们吗?如果这是您想要的,那么您可以在3D中使用Hoshen-Kopelman算法。为此编写代码应该花费一两天时间,然后就完成了。链接中的例子是2D;将其扩展到3D根本不是问题。

希望这有帮助。

答案 2 :(得分:0)

为什么不为hashmap使用更精细的密钥?您可以使用x,y,z坐标构建tuple,或者实现自己的结构,而不是简单的int。后面的选项需要实现operator ==()和哈希函数。可以找到有关良好哈希函数的一些信息here