簡體   English   中英

3D陣列(1D平面)索引

[英]3D array (1D flat) indexing

我使用坐標系x(寬度),y(高度),z(深度)

只是為了清除混淆,如果有任何x和y是一個平面,我使用Z作為高程。

我將每秒訪問數組數百萬次,並且基准測試顯示使用索引的一維數組更快,我想盡可能多地擠壓效率,以便其他東西可以使用那個時間

例如,2D陣列 - > 1D陣列創建就是

Object[] oneDArray = new Object[width * height]

並索引數組我可以使用以下。

Object obj = oneDArray[x + y * width]

我確實在stackoverflow上找到了以下內容,但我不完全確定哪一個是正確的如何在一維數組中“展平”或“索引”3D數組?

“正確”答案表示索引數組執行以下操作

Object[] oneDArray = new Object[width * height * depth]
Object obj = oneDArray[x + WIDTH * (y + DEPTH * z)]

但另一個答案是說“正確”答案是錯誤的,並使用以下內容

Object[] oneDArray = new Object[width * height * depth]
Object obj = oneDArray[x + HEIGHT* (y + WIDTH* z)]

讀取扁平3D陣列的正確方法是什么?

這取決於你想如何在一維數組中訂購3D數據,如果你想按順序排列索引:Z,Y,X那么你的2x2x2尺寸的3D數據將被存儲如下:

index 0: [z=0,y=0,x=0]
index 1: [z=0,y=0,x=1]
index 2: [z=0,y=1,x=0]
index 3: [z=0,y=1,x=1]
index 4: [z=1,y=0,x=0]
index 5: [z=1,y=0,x=1]
index 6: [z=1,y=1,x=0]
index 7: [z=1,y=1,x=1]

DEPTH維度對應於z ,HEIGHT對應於y ,WIDTH對應於x

指數計算將是: index = HEIGHT*WIDTH*z + WIDTH*y + x

x不會乘以任何東西,因為下一個x索引就在前一個索引之后。

如果要跳過一個Y行,則必須添加整行WIDTH,在本例中為2,例如,如果您在索引1處,其中z = 0,y = 0且x = 1並且您添加WIDTH = 2要索引,你將得到索引3.只有y維度增加了1。

要從z = 0移動到z = 1,您必須跳過4個索引(查看索引列表),數字是HEIGHT * WIDTH(在此示例中為2 * 2)。

性能

為了獲得速度,最好處理您的3D數據,z,y,x坐標按順序遞增,這樣您就不必經常重新計算索引。 例如:

int z = 1, y=1, x=0;
int index = HEIGHT*WIDTH*z + WIDTH*y;
int data;

for(x=0;x<WIDTH;x++)
{
    Object obj = oneDArray[index+x];
}

在理想情況下,所有數據處理都是相互獨立的,您甚至不必計算索引,只需通過整個oneDArray遞增一個索引。 預計算的可能性取決於您的使用情況。

使用公式index = x*height*depth + y*depth + z示例java代碼插圖。

public class FlattenedArray {
    public static void main(String[] args) {
        int width = 2;
        int height = 3;
        int depth = 4;
        int[][][] d3 = new int[width][height][depth];
        int[] d1 = new int[width*height*depth];

        //3D Array :
        int w=0;
        for(int i=0;i<width;i++) 
            for(int j=0;j<height;j++)
                for(int k=0;k<depth;k++) {
                    d3[i][j][k] = ++w;
                    System.out.print(d3[i][j][k] + " ");
                }
        System.out.println();

        //1D Array :
        w=0;
        for(int i=0;i<width;i++) 
            for(int j=0;j<height;j++)
                for(int k=0;k<depth;k++) {
                    int index = i*height*depth + j*depth + k;
                    d1[index] = ++w;
                }

        for(int i=0;i<width*height*depth;i++) {
            System.out.print(d1[i] + " ");
        }
    }
}

這是一個Java解決方案,它為您提供:

  • 從3D到1D
  • 從1D到3D

我自己的微基准測試顯示,1D陣列獲得/設置值比通過3D陣列快50%。

下面是我選擇遍歷3D矩陣的路徑的圖形說明,單元格按其遍歷順序編號:

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

上面的代碼肯定會被分解為更快,但我這樣做是為了讓它更容易理解2路轉換;)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM