【问题标题】:Voxel unique ID in 3D space3D 空间中的体素唯一 ID
【发布时间】: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,您可以将 xyz 索引作为 10 位数字连接成一个 30(或更确切地说是 32)位数字。将是一个非常快速和简单的解决方案。
  • 是的,我可以通过一些工作使其达到 1024... 详细说明答案,如果没有更好的,我接受它。谢谢!
  • 使用 64 位整数,您可以消除每个维度 1024 个最大体素的限制。显然不是完全“免费”的。阅读本文以获取更多信息stackoverflow.com/questions/16841382/…
  • 我认为获取线性 ID 的规范方法是将它们交错。我相信在英特尔上有 simd 说明。

标签: c++ 3d voxels


【解决方案1】:
#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;
}

这种散列/取消散列方法应该是最快的。 请注意,我只使用 32 位整数中的 30 位。这允许最大世界大小为 4.2950e+009 x 4194304 x 4096。如果您想扩展世界限制,则必须使用更多/更大的整数。

希望这能有所帮助。

【讨论】:

  • 这似乎是目前第二点的最佳答案。如果没有更多的时间我会接受这个。谢谢!
【解决方案2】:

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

希望这会有所帮助。

【讨论】:

  • 谢谢,也许不完全适合这项任务,但将来会非常有用。
【解决方案3】:

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

【讨论】:

  • 是的,我知道,但这正是我想避免的,因为它需要复杂的比较(至少 3 次),而构建是部分离线执行的,但比较不是。无论如何,谢谢!
猜你喜欢
  • 1970-01-01
  • 2015-11-28
  • 2013-05-06
  • 2021-12-25
  • 2010-12-27
  • 1970-01-01
  • 2013-10-02
  • 1970-01-01
  • 2012-03-28
相关资源
最近更新 更多