如何在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矩阵的路径的图形说明,单元格按其遍历顺序编号:
转换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