我试图在我的游戏中将3D阵列压平为1D阵列中的"块"系统.这是一个3D块游戏,基本上我希望块系统几乎与Minecraft的系统相同(但是,这不是Minecraft克隆的任何措施).在我以前的2D游戏中,我使用以下算法访问了扁平化数组:
Tiles[x + y * WIDTH]
Run Code Online (Sandbox Code Playgroud)
然而,这显然不适用于3D,因为它缺少Z轴.我不知道如何在3D空间中实现这种算法.宽度,高度和深度都是常量(宽度和高度一样大).
是x + y*WIDTH + Z*DEPTH
吗?我的数学非常糟糕,我只是开始进行3D编程,所以我很丢失:|
PS.这样做的原因是我循环并从索引中获取相当多的东西.我知道1D阵列比多维阵列更快(我记得的原因是:P).即使这可能没有必要,我希望尽可能好的表现:)
Gid*_*rth 34
算法大致相同.如果你有一个三维阵列Original[HEIGHT, WIDTH, DEPTH]
,那么你可以把它变成Flat[HEIGHT * WIDTH * DEPTH]
由
Flat[x + WIDTH * (y + DEPTH * z)] = Original[x, y, z]
Run Code Online (Sandbox Code Playgroud)
顺便说一下,你应该更喜欢.NET中多维数组的数组数组.性能差异很大
Sam*_*ien 26
这是一个Java解决方案,它为您提供:
下面是我选择遍历3D矩阵的路径的图形说明,单元格按其遍历顺序编号:
转换功能:
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 };
}
Run Code Online (Sandbox Code Playgroud)
小智 24
我认为以上需要一点修正.假设您的高度为10,宽度为90,单维数组将为900.通过上述逻辑,如果您位于阵列9 + 89*89的最后一个元素,显然这大于900.正确的算法是:
Flat[x + HEIGHT* (y + WIDTH* z)] = Original[x, y, z], assuming Original[HEIGHT,WIDTH,DEPTH]
Run Code Online (Sandbox Code Playgroud)
具有讽刺意味的是,如果您的高度>宽度,您将不会遇到溢出,只需完成疯狂的结果;)
Tom*_*ych 11
x + y*WIDTH + Z*WIDTH*DEPTH
.将其可视化为一个矩形实体:首先你遍历x
,然后每个y
是一个"线" width
步长,每个z
是一个"平面" WIDTH*DEPTH
步骤区域.
长话短说
正确答案可以用多种方式编写,但我最喜欢以易于理解和可视化的方式编写。这是确切的答案:
(width * height * z) + (width * y) + x
Run Code Online (Sandbox Code Playgroud)
TS;DR
可视化它:
someNumberToRepresentZ + someNumberToRepresentY + someNumberToRepresentX
Run Code Online (Sandbox Code Playgroud)
someNumberToRepresentZ
指示我们位于哪个矩阵 ( depth
) 上。要知道我们在哪个矩阵上,我们必须知道每个矩阵有多大。矩阵的二维大小为width * height
,很简单。要问的问题是“我所在的矩阵之前有多少个矩阵?” 答案是z
:
someNumberToRepresentZ = width * height * z
Run Code Online (Sandbox Code Playgroud)
someNumberToRepresentY
指示我们位于哪一行 ( height
)。要知道我们在哪一行,我们必须知道每行有多大:每行都是 1d,大小为width
。要问的问题是“我所在的行之前有多少行?”。答案是y
:
someNumberToRepresentY = width * y
Run Code Online (Sandbox Code Playgroud)
someNumberToRepresentX
指示我们位于哪一列 ( width
)。要知道我们在哪一列,我们只需使用x
:
someNumberToRepresentX = x
Run Code Online (Sandbox Code Playgroud)
我们的可视化然后
someNumberToRepresentZ + someNumberToRepresentY + someNumberToRepresentX
Run Code Online (Sandbox Code Playgroud)
成为
(width * height * z) + (width * y) + x
Run Code Online (Sandbox Code Playgroud)
你快到了.您需要通过乘ž WIDTH
和 DEPTH
:
Tiles[x + y*WIDTH + Z*WIDTH*DEPTH] = elements[x][y][z]; // or elements[x,y,z]
Run Code Online (Sandbox Code Playgroud)
小智 5
上面 Samuel Kerrien 的正向和反向变换几乎是正确的。下面包含一个更简洁的(基于 R 的)转换映射和一个示例(“a %% b”是表示 a 除以 b 的余数的模运算符):
dx=5; dy=6; dz=7 # dimensions
x1=1; y1=2; z1=3 # 3D point example
I = dx*dy*z1+dx*y1+x1; I # corresponding 2D index
# [1] 101
x= I %% dx; x # inverse transform recovering the x index
# [1] 1
y = ((I - x)/dx) %% dy; y # inverse transform recovering the y index
# [1] 2
z= (I-x -dx*y)/(dx*dy); z # inverse transform recovering the z index
# [1] 3
Run Code Online (Sandbox Code Playgroud)
请注意除法 (/) 和模数 (%%) 运算符。
归档时间: |
|
查看次数: |
51746 次 |
最近记录: |