2013-10-23 39 views
1

要記住點的空間座標,哪種方法更加正確?用於空間座標的3D數組

int spacial[][][] = new int[1024][768][100]; 

// first point at 
spacial[0][0][0] = 100; // x 
spacial[0][0][1] = 200; // y 
spacial[0][0][2] = 10; // z 

還是這個,

//  x y z 
spacial[100][200][10] = 1; // 1 set that a point is present 
+1

爲什麼關閉lool?請看這個答案和我的評論:http://stackoverflow.com/a/19541461/529543 75-78Mb分配可能會有點浪費資源,但一個布爾[]恢復到18Mb,並在3Mb下位級管理!我會存儲這些3Mb而不是迭代列表。 – 2013-10-23 12:41:19

+0

看到3Mb的實施:http://stackoverflow.com/a/19542553/529543修復索引,如果是錯誤的 – 2013-10-23 13:08:32

回答

3

這取決於您的代碼的使用情況。創建三維數組在資源(內存)方面非常昂貴,因此您只應在創建體素結構時使用它,或者您知道需要填充空間x*y*z中的所有點。對於這種情況的代碼

int spacial[][][] = new int[1024][768][100]; 
spacial[100][200][10] = 1; // 1 set that a point is present 

使得使用更有意義。如果您想快速查找是否存在某個空間座標,這也很有用。

對於其他情況下,你可以創建結構

struct Coord 
{ 
    int x, y, z 
} 

,然後創建該結構的實例數組來代替。這樣可以爲您提供更多的內存效率,因爲您不必擁有每個單一的座標(即使它不在那裏)。您仍然可以使用算法來使用八進制搜索進行高效搜索,但它們實施起來更加複雜。 你可以在我對另一個question的回答中找到更多關於八叉樹的信息。

2

我會用第二個:

//  x y z 
spacial[100][200][10] = 1; // 1 set that a point is present 

但是有更多的表示:與角度,半徑,不僅座標,更多信息查詢Wiki

2

使用3D數組意味着您同時存儲1024x768x100 = 78 643 200個整數值。這些值大部分使用內存,但包含零 - 我認爲這對於良好的性能來說太糟糕了。

我認爲你應該使用列表<>只存儲點,即包含有價值的座標:

public struct Point3D 
    { 
    public int x {get;set;} 
    public int y {get;set;} 
    public int z {get;set;} 
    public int value {get;set;} 
//any other properties.... 
    } 

List<Point3D>MyPoints=new List<Point3D>(); 

//to check if something exists by my coordinates: 

List<Point3D> ResultList=MyPoints.FindAll(coords=>coords.x==25&&coords.y==250&&coords.z==70); 
if(ResultList.Count>0) //points exists 
{ 
    // do something with ResultList[0], that should contains your point data 
} 
+0

+ 1,好的方法78 Mb有時是相當可觀的,有時我會分配更快的操作。在你的列表中想要迭代78 643 200個單位來查找是否存在或不存在?如果真的內存很短,可以將它縮減爲bool []或其他位級別的改進 – 2013-10-23 12:38:30

+0

否檢查某些座標是否存在某些內容我簡單地執行此操作:列表 ResList = MyPoints.SelectAll(coord => coord.x = = 100 && coord.y == 250 && coord.z == 500);如果在那裏沒有任何東西,ResList將包含Point3D或null。 –

+0

我已經通過這個示例修改了我的帖子 –

0

我寫了一個Java這個時候 - 作爲例外 - 一個完整的代碼:) 我沒有帶跑可能我會錯過索引的東西,但是如果有超過20個點的話,我會用類似的方法。超過1000點是毫無疑問使用這個或列表。

public class Spatial { 

    public static final int maxX = 1024; 
    public static final int maxY = 768; 
    public static final int maxZ = 100; 

    // 1024x768x100= 78 643 200 
    // int max value:2,147,483,647 

    private byte[] indexData; 

    public Spatial() { 
     int totalDataCount = maxX * maxY * maxZ; 

     int byteAarraySizeNeeded = totalDataCount/8 + totalDataCount % 8; 

     indexData = new byte[byteAarraySizeNeeded]; // inited with all 0 
    } 

    public void markPresent(int x, int y, int z, boolean present) { 
     // TODO: check parameters!!! minimum and max values! 

     int index = (z * 1 + y * maxZ + maxX * (maxX * maxY)); 
     // transform the index to our storage index : maybe a bug here, cheack t pls! 

     int arrayIndex = index/8 + index % 8; 

     byte dataChunck = indexData[arrayIndex]; 

     if (present) { // bitwise Or with 1 
      dataChunck = (byte) (dataChunck | (1 << index % 8)); 
     } else { // bitwise And with 0 
      byte helper = (byte) (1 << index % 8); 
      byte all1ExceptOne = (byte) (~helper & 0xFF); 
      dataChunck = (byte) (dataChunck & all1ExceptOne); 
     } 
     // put back: 
     indexData[arrayIndex] = dataChunck; 
    } 

    public boolean isPresent(int x, int y, int z) { 
     // TODO: check parameters!!! minimum and max values! 

     int index = (z * 1 + y * maxZ + maxX * (maxX * maxY)); 
     // transform the index to our storage index : maybe a bug here, cheack t pls! 

     int arrayIndex = index/8 + index % 8; 

     byte dataChunck = indexData[arrayIndex]; 

     return (dataChunck & (1 << index % 8)) > 0; 

    } 
}