2011-09-09 93 views
15

我想在我的遊戲中將3D數組拼成一維數組以用於「塊」系統。這是一個3D塊遊戲,基本上我希望塊系統幾乎與Minecraft的系統相同(不過,這不是任何度量的Minecraft克隆)。在我以前的2D遊戲我已經訪問了扁平陣列下面的算法:如何在一維數組中「拼合」或「索引」3D數組?

Tiles[x + y * WIDTH] 

然而,這顯然不符合3D,因爲它缺少Z軸工作。我不知道如何在3D空間中實現這種算法。寬度,高度和深度都是常量(寬度和高度一樣大)。

難道僅僅x + y*WIDTH + Z*DEPTH?我對數學很不好,而且我剛剛開始3D編程,所以我非常迷茫:|

PS。這是因爲我正在循環並通過索引從中獲取東西。我知道1D陣列比多維陣列更快(因爲我不記得:P)。儘管這可能不是必要的,我想是不錯的表現越好:)

+0

我是正確的話,你想以3D陣列被放入一個一維ARR唉? – DMan

+1

爲什麼你不使用3D陣列? – svick

+0

@三月是啊你是:)我總是用最難和最長的方式解釋一切,所以沒有你不明白的驚喜:P – flai

回答

24

該算法大體相同。如果你有一個三維數組Original[HEIGHT, WIDTH, DEPTH],那麼你可以把它變成Flat[HEIGHT * WIDTH * DEPTH]通過

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

順便說一句,你應該更喜歡數組的數組在.NET中的多維數組。性能差異顯着

+3

你能指出一些來源討論性能差異嗎?另外,您不應僅僅根據性能確定您的決定。 – svick

+0

http://stackoverflow.com/questions/597720/what-is-differences-between-multidimensional-array-and-array-of-arrays-in-c和http://stackoverflow.com/questions/468832/why - 多維數組 - 網內 - 比正常數組慢 – hatchet

+0

@svick:有些源可以在hatchet提供的鏈接中看到。我的成績單只是一個旁觀而不是主要建議。鋸齒形數組有幾乎相同的語法(original [x] [y] [z]),但是需要更多工作來初始化。但是,根據使用情況,性能優勢可能會變得非常明顯(2-5倍加速)。 –

5

你幾乎沒有。您需要通過WIDTHDEPTH乘Z:

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

x + y*WIDTH + Z*WIDTH*DEPTH。將其視爲長方體:首先沿着x遍歷,然後每個y是「行」width步長,並且每個z是「面」WIDTH*DEPTH步的面積。

13

我認爲上面需要一點修正。假設你有10的高度,WIDTH爲90,單維數組爲900.通過上述邏輯,如果你在數組9 + 89 * 89的最後一個元素,顯然這是大於900。正確的算法是:

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

諷刺的是,如果你的高度>寬度將不會遇到溢出,剛剛完成瘋狂的結果;)

+3

我無法對上述評論或評論真正正確的答案,但馬丁有它正確的,目前選擇的答案是錯誤的。本質上:data [x] [y] [z] = data [x + y * maxX + z * maxX * maxY] – jking

+0

當前答案是錯誤的,應該是高度不深。花了我很長時間才弄清楚這是因爲它第一次實際上使用了一個錯誤的SO回答來編寫代碼>。< – chilleo

0

爲了更好地瞭解3D陣列的描述在一維數組將是(我猜最佳答案深度是指Y大小)

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

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

這裏是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 }; 
}