定义2D方形瓦片的1D数组Resize问题:元素位置错位修复
瓦片网格1D数组的正确缩放实现方案
需求说明
我有一个定义瓦片网格的1D数组,每个瓦片包含8×8个元素(元素值为0或1),网格的宽高可自定义。需要调整该数组的大小,支持向右或底部添加/移除瓦片,且调整后必须保证原有瓦片的元素位置正确对齐。
示例
原始1×1瓦片数组(8×8元素)
每个角落的值为1:
{ 1,0,0,0,0,0,0,1, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 1,0,0,0,0,0,0,1 }
期望的2×2瓦片数组(16×16元素)
扩展后第一个瓦片的角落位置保持正确:
{ 1,0,0,0,0,0,0,1, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 1,0,0,0,0,0,0,1, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, }
现有尝试的问题
我尝试过多种缩放方法,但元素位置始终无法正确对齐。以下是最新的尝试代码:
static int[] ResizeSquare(int[] originalSquare, int originalWidth, int originalHeight, int newWidth, int newHeight) { int elementsPerTile = 8 * 8; int[] resizedSquare = new int[newWidth * newHeight * elementsPerTile]; for (int row = 0; row < Math.Min(originalHeight, newHeight); row++) { for (int col = 0; col < Math.Min(originalWidth, newWidth); col++) { int originalTileIndex = row * originalWidth + col; int newTileIndex = row * newWidth + col; for (int i = 0; i < elementsPerTile; i++) { // Calculate the position within the original and resized squares int originalPosition = originalTileIndex * elementsPerTile + i; int newPosition = newTileIndex * elementsPerTile + i; // Copy the original value to the corresponding position in the resized square resizedSquare[newPosition] = originalSquare[originalPosition]; } } } return resizedSquare; }
这段代码的运行结果不符合预期,元素位置错位:
{ 1,0,0,0,0,0,0,1, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 1,0,0,0,0,0,0,1, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, }
正确实现方案
问题出在原代码是将整个瓦片作为一个块直接复制,忽略了大网格的行结构。正确的做法是按大网格的逐行逐列映射元素,确保每个瓦片内的行和列都对应到新网格的正确位置。
代码实现
static int[] ResizeSquare(int[] originalSquare, int originalWidth, int originalHeight, int newWidth, int newHeight) { const int tileSize = 8; int newTotalElements = newWidth * newHeight * tileSize * tileSize; int[] resizedSquare = new int[newTotalElements]; // 遍历新网格的每一行 for (int gridRow = 0; gridRow < newHeight * tileSize; gridRow++) { // 计算当前行属于原网格的哪个瓦片行,以及瓦片内的行索引 int originalTileRow = gridRow / tileSize; int innerTileRow = gridRow % tileSize; // 遍历新网格的每一列 for (int gridCol = 0; gridCol < newWidth * tileSize; gridCol++) { // 计算当前列属于原网格的哪个瓦片列,以及瓦片内的列索引 int originalTileCol = gridCol / tileSize; int innerTileCol = gridCol % tileSize; // 计算当前元素在新数组中的位置 int newIndex = gridRow * newWidth * tileSize + gridCol; // 仅当当前位置属于原网格范围内时,复制值,否则保持默认0 if (originalTileRow < originalHeight && originalTileCol < originalWidth) { // 计算该元素在原数组中的位置 int originalTileIndex = originalTileRow * originalWidth + originalTileCol; int originalInnerIndex = innerTileRow * tileSize + innerTileCol; int originalIndex = originalTileIndex * tileSize * tileSize + originalInnerIndex; resizedSquare[newIndex] = originalSquare[originalIndex]; } } } return resizedSquare; }
逻辑说明
- 以大网格的行和列为遍历单位,而非瓦片整体,确保每个元素的位置映射准确。
- 对每个元素,计算它所属的瓦片以及在瓦片内的具体位置,再对应到原数组的索引。
- 超出原网格范围的新增瓦片区域,保持默认值0。
这样处理后,原有瓦片的元素会精确对应到新网格的正确位置,符合预期效果。
内容的提问来源于stack exchange,提问作者Antônio Mateus
相关产品推荐
相关产品推荐

