如何在1D阵列中“展平”或“索引”3D阵列?

时间:2011-09-09 21:42:04

标签: c# .net arrays 3d flatten

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

Tiles[x + y * WIDTH]

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

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

PS。这样做的原因是我循环并从索引中获取相当多的东西。我知道1D阵列比多维阵列更快(我记得的原因是:P)。即使这可能没有必要,我希望尽可能好的表现:)

10 个答案:

答案 0 :(得分:30)

算法大致相同。如果你有一个3D数组Original[HEIGHT, WIDTH, DEPTH],那么可以通过

将其转换为Flat[HEIGHT * WIDTH * DEPTH]
Flat[x + WIDTH * (y + DEPTH * z)] = Original[x, y, z]

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

答案 1 :(得分:24)

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

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

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

2 Examples of 3D matrices

转换功能:

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 };
}

答案 2 :(得分:20)

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

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

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

答案 3 :(得分:11)

x + y*WIDTH + Z*WIDTH*DEPTH。将其可视化为矩形实体:首先遍历x,然后每个y为“行”width步长,每个z为“平面”{ {1}}区域中的步骤。

答案 4 :(得分:5)

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

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

答案 5 :(得分:2)

正确的算法是:

<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">

答案 6 :(得分:2)

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。要问的问题是“ 我所在的行之前有多少行?”。答案是y

someNumberToRepresentY = width * y

someNumberToRepresentX表示我们在哪一列(width)。要知道我们在哪一列上,我们只需使用x

someNumberToRepresentX = x

我们的可视化

someNumberToRepresentZ + someNumberToRepresentY + someNumberToRepresentX

成为

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

答案 7 :(得分:1)

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

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

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

答案 8 :(得分:1)

上面Samuel Kerrien的正向和反向变换几乎是正确的。下面包括一个更简洁的(基于R的)变换图(例如“ a %% b”是表示a除以b的余数的模运算符):

CONSTRAINT con_scraps UNIQUE(scraps)

注意除法(/)和模块(%%)运算符。

答案 9 :(得分:0)

m [x] [y] [z] =数据[xYZ + yZ + z]

x-picture:
0-YZ
.
.
x-YZ

y-picture 

0-Z
.
.
.
y-Z


summing up, it should be : targetX*YZ + targetY*Z + targetZ