【问题标题】:Wrapping 2d grid indices包装二维网格索引
【发布时间】:2021-09-08 16:10:43
【问题描述】:

我有这个函数,我在 python 中创建了用于导航网格索引的原型。它在 python 中完美运行,但由于模运算符处理负数的方式,它在 c++ 中下降。任何人都可以提出一项修改以使其工作吗?

当坐标nxny 为负时,函数会失败。

int wrap_grid(int index, int x, int y, int nx, int ny) {

        //first calculate positon on row by adding nx -
        //assuming an infinite grid of indices (no limits or wrap)
        int a = (index + (y * nx));
        //then wrap around the width (x) of the row
        int b = a % (x * y);

        //now do column, calculate the bottom index of the column
        int start = b - b % y;
        //and the top index
        int limit = b - b % y + y;

        //now wrap the ny value around the columns
        return start + (b + ny) % (limit - start);
}

编辑:解释函数参数

index是矩形网格的索引,像这样:

col1 col2 col3
5 11 17
4 10 16
3 9 15
2 8 14
1 7 13
0 6 12

x是网格的宽度,这里是3。
y是网格的高度,这里是6。
nx是坐标网格正方形偏移量,所以nx = 1 是右侧的一个方格,ny=1 类似的是“向上”一个方格。

返回值为index与坐标nxny变换后的新索引号。

编辑:基于 jwezorek 方法的更新功能。请注意,唯一有效的更改(功能因素除外)是必须允许零值的比较运算符。

int wrap_grid(int index, int rows, int columns, int offset_x, int offset_y) {

    //index to grid coordinates always positive
    int x = (index / rows) + (offset_x);
    x = x >= 0 ? x : x + columns;

    int y = (index % rows) + (offset_y);
    y = y >= 0 ? y : y + rows;

    //grids to coords
    int column = x % columns;
    column = column >= 0 ? column : column + columns;

    int row = y % rows;
    row = row >= 0 ? row : row + rows;

    int bottom_of_column_index = column * rows;

    return bottom_of_column_index + row;
    }

【问题讨论】:

  • 什么是indexxynxny
  • 返回值是多少?
  • 答案中的表格没有格式化,预览看起来不错。它基本上是一个从下到上、从左到右的索引编号网格,从 0 开始。
  • 使用xnx 计算新的xfirst(与yny 相同)。 然后进行索引计算。对于负值,将它们添加到行(或列)计数中。

标签: c++ modulo


【解决方案1】:

您只需要一个只会给您非负值的 mod 函数。要做到这一点,直接的方式如下所示(为了清晰起见,在移动代码之后)。

#include <tuple>
#include <iostream>

int grid_coords_to_index(int cols, int rows, int x, int y) {
    // wrap the coordinates...
    int column = x % cols;
    column = column >= 0 ? column : column + cols;

    int row = y % rows;
    row = row >= 0 ? row : row + rows;

    int bottom_of_column_index = column * rows;
    return bottom_of_column_index + row;
}

std::tuple<int,int> index_to_grid_coords(int cols, int rows, int index) {
    // TODO: handle negatives correctly here too, if we cannot 
    // assume indices are positive.
    return { index / rows, index % rows };
}

int wrap_grid(int initial_index, int cols, int rows, int x_offset, int y_offset) {
    auto [x, y] = index_to_grid_coords(cols, rows, initial_index);
    return grid_coords_to_index(cols, rows, x + x_offset, y + y_offset);
}

int main()
{  
    /*
    5   11  17
    4   10  16
    3   9   15
    2   8   14
    1   7   13
    0   6   12

    index 9 is (1,3) so two to the left and one down should be 14 given wrapping

    */

    std::cout << wrap_grid(9, 3, 6, -2, -1) << "\n";
}

【讨论】:

  • 这种方法效果很好。我不得不将比较运算符从&gt; 更改为&gt;=,因为允许零索引并且会在上方移动一行或一列。我已经用我的功能更新了这个问题以供参考。非常感谢,非常感谢。
  • 我更新了我的代码以使用 &gt;= 这是一个错误。
猜你喜欢
  • 2021-12-05
  • 1970-01-01
  • 1970-01-01
  • 2019-09-15
  • 2023-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多