如何在1Darrays中“展平”或“索引”3Darrays?

我试图在我的游戏中将3D数组压缩为1D数组中的“块”系统。 这是一个3D块游戏,基本上我希望块系统几乎与Minecraft的系统完全相同(但是,这不是Minecraft克隆的任何措施)。 在我以前的2D游戏中,我使用以下算法访问了扁平化数组:

Tiles[x + y * WIDTH] 

然而,这显然不适用于3D,因为它缺少Z轴。 我不知道如何在3D空间中实现这种算法。 宽度,高度和深度都是常量(宽度和高度一样大)。

它只是x + y*WIDTH + Z*DEPTH ? 我的数学非常糟糕,我只是开始进行3D编程,所以我很遗憾:|

PS。 这样做的原因是我循环并通过索引从中获取相当多的东西。 我知道1Darrays比多维arrays更快(出于我无法记住的原因:P)。 即使这可能没有必要,我希望尽可能好的表现:)

算法大致相同。 如果您有3DarraysOriginal[HEIGHT, WIDTH, DEPTH]那么您可以将其转换为Flat[HEIGHT * WIDTH * DEPTH]

 Flat[x + WIDTH * (y + DEPTH * z)] = Original[x, y, z] 

顺便说一句,你应该更喜欢.NET中多维数组的数组数组。 性能差异很大

这是Java中的一个解决方案,它为您提供:

  • 从3D到1D
  • 从1D到3D

下面是我选择遍历3D矩阵的路径的图形说明,单元格按其遍历顺序编号:

2 3D矩阵的示例

转换function:

 public int to1D( int x, int y, int z ) { return (z * xMax * yMax) + (y * xMax) + x; } public int[] to3D( int idx ) { final int z = idx / (xMax * yMax); idx -= (z * xMax * yMax); final int y = idx / xMax; final int x = idx % xMax; return new int[]{ x, y, z }; } 

我认为以上需要一点修正。 假设您的高度为10,宽度为90,单维数组将为900.通过上述逻辑,如果您位于arrays9 + 89 * 89的最后一个元素,显然这大于900。正确的算法是:

 Flat[x + HEIGHT* (y + WIDTH* z)] = Original[x, y, z], assuming Original[HEIGHT,WIDTH,DEPTH] 

具有讽刺意味的是,如果您的高度>宽度,您将不会遇到溢出,只需完成疯狂的结果;)

x + y*WIDTH + Z*WIDTH*DEPTH 。 将其可视化为矩形实体:首先沿x移动,然后每个y是“线” width步长,并且每个z是区域中的“平面” WIDTH*DEPTH步长。

你快到了。 你需要将Z乘以WIDTH DEPTH

 Tiles[x + y*WIDTH + Z*WIDTH*DEPTH] = elements[x][y][z]; // or elements[x,y,z] 

为了更好地理解1Darrays中3Darrays的描述(我猜最佳答案中的深度是指Y尺寸)

 IndexArray = x + y * InSizeX + z * InSizeX * InSizeY; IndexArray = x + InSizeX * (y + z * InSizeY); 

正确的算法是:

 Flat[ x * height * depth + y * depth + z ] = elements[x][y][z] where [WIDTH][HEIGHT][DEPTH] 

TL; DR

正确的答案可以用各种方式编写,但我最喜欢它,它可以用一种非常容易理解和可视化的方式编写。 这是确切的答案:

 (width * height * z) + (width * y) + x 

TS; DR

可视化:

 someNumberToRepresentZ + someNumberToRepresentY + someNumberToRepresentX 

someNumberToRepresentZ表示我们在哪个矩阵( depth )。 要知道我们在哪个矩阵,我们必须知道每个矩阵有多大。 矩阵的大小为width * height ,简单。 要问的问题是“我在矩阵之前有多少矩阵 ?” 答案是z

 someNumberToRepresentZ = width * height * z 

someNumberToRepresentY表示我们在哪一行( height )。 要知道我们在哪一行,我们必须知道每行有多大:每行为1d,大小为width 。 要问的问题是“在我开的行之前有多少行 ?”。 答案是:

 someNumberToRepresentY = width * y 

someNumberToRepresentX指示我们所在的列( width )。 要知道我们所在的列,我们只需使用x

 someNumberToRepresentX = x 

我们的可视化然后

 someNumberToRepresentZ + someNumberToRepresentY + someNumberToRepresentX 

 (width * height * z) + (width * y) + x