【问题标题】:How to calculate grid index如何计算网格指数
【发布时间】:2015-09-15 02:03:29
【问题描述】:

我有一个 C++ 光线投射器,它将数百万个点插入到 (-1,-1,-1) 到 (1,1,1) 的范围内。为了避免在顶点缓冲区中插入重复点,我想检查某个范围是否已经包含一个点。

这就是我设置网格的方式:

const int size = 500 * 500 * 500;
bool *grid = new bool[size];

for(int i = 0; i < size; i++)
  grid[i] = false;

unsigned double divide = 2.0 / size;

现在我想检查要添加的交点:

// In my code i handle negative and positive cases
int  x = intersection.X / divide;
int  y = intersection.Y / divide;
int  z = intersection.Z / divide;

if(!grid[x * y *z])
  //insert
else
  //discard

我面临的问题是divide总是0,因为size太大了。但我不知道如何解决这个问题。我已经在使用 unsigned double 了。

【问题讨论】:

  • 不存在无符号双精度数。我不确定它是如何编译的。你也在混合类型。 2.0 / size,其中 size 是一个 int。我认为除法是无符号的。在这种情况下,如果 size > 2(四舍五入),则除法将为零。
  • 你能解释一下divide的用途吗?默认情况下,grid 分配有false,因此不需要for 循环。
  • 把它改成multiply = size / 2.0; int x = intersection.X * multipliy; 或者干脆intersection.X * size / 2

标签: c++ arrays floating-point-precision


【解决方案1】:

您需要使用 3 维数组来存储布尔值。

How to initialize 3D array in C++

另外,x * y * z 索引数组的方法也不起作用,因为同一索引有多种解决方案 (3 * 4 * 5 = 4 * 3 * 5)。

【讨论】:

    【解决方案2】:

    假设您的点 (x,y,z) 具有整数坐标,您可以将它们重写为 3 进制系统中的数字。基本上,它只是意味着将+1 添加到每个坐标:

    (x,y,z) --> x+1,y+1,z+1
    (-1,1,0) --> 021
    (1,1,1) ---> 222
    (-1,-1,-1) --> 000
    

    这样每个点都是唯一的,取值范围从000到222,也就是3^3 = 27个不同的值。

    因此,您可以只存储一个包含 27 个值的数组:

    bool grid[27];
    /* initialize to false, e.g. memset(grid, false, sizeof(grid)) */
    
    if(!grid[9*(x+1) + 3*(y+1) + z]) // converting to ternary
       //insert
    else
       //discard
    

    不客气! ;)

    【讨论】:

      【解决方案3】:

      感谢您的回答。我在我的解决方案中遗漏了一些东西,现在重新设计了。

      我现在使用 3D 网格并计算我的网格大小,它的名称为 divide

      const int value = 500;
      
      bool ***grid = new bool**[value];
      for(int i = 0; i < value; ++i)
      {
        grid[i] = new bool*[value];
        for(int j = 0; j < value; ++j)
        {
          grid[i][j] = new bool[value];
        }
      }
      
      double divide = 2.0 / value;
      

      因为我的点云区域从 (-1,-1,-1) 到 (1, 1, 1) 我映射它从 (0, 0, 0) 到 (2, 2, 2) 并计算网格单元数量。演员表很脏,当我知道我的确切分辨率时,我会避开它们。

           Vector3F gridIntersection(intersection.X + 1.0f, intersection.Y + 1.0f, intersection.Z + 1.0f);
      
            x = (int) ((double) gridIntersection.X / divide);
            y = (int) ((double) gridIntersection.Y / divide);
            z = (int) ((double) gridIntersection.Z / divide);
      
            if(!grid[x][y][z])
            {
              grid[x][y][z] = true;
            }
      

      这样,我的内存使用量约为 119 MB。我还将通过使用 char 而不是 bool 来改进它,以检查单元格中的多个成员。

      【讨论】:

        猜你喜欢
        • 2012-02-08
        • 1970-01-01
        • 2020-08-30
        • 2019-06-24
        • 1970-01-01
        • 2011-02-10
        • 2013-02-25
        • 1970-01-01
        相关资源
        最近更新 更多