2011-03-30 78 views
3

數組我很新的C++,所以我不知道我會約以正確的方式這個問題。我正在處理一個體素數據的3D數組,我想創建一個並行數據結構來存儲等值面法線向量。內存效率是一個問題,所以我想使用一個二維地圖數組,這些地圖由一個整數索引幷包含一個3D矢量。函數來填充地圖

這個想法是2D陣列索引每x和y座標與地圖索引僅包含一個值的Z座標(沿z軸的每行分散通常介於0和3的值)。

問題1:我怎麼創建地圖的二維數組一樣std::map<int, Vector3f> surfaceNormals;

問題2:我的想法是聲明二維數組,然後全球與由指針處理它和每一個陣單元創建一個映射函數來填充它,是下面的代碼在正確的軌道上?該?????的指明我不知道把什麼給我的問題關於不確定性1.

特別是我在管理指針/引用/值正確,如實際最終存儲的所有數據我需要?

????? isoSurfaces1 [256][100]; 

????? *extractIS(float Threshold, ????? *pointy){ 

    ????? *surfacePointer = pointy; 

    for loop over x and y { 

     std::map<int, Vector3f> surfaceNormals; 

     for loop over z { 

     [ ... find surface voxels and their normal vectors ... ] 

     Vector3f newNormalVector(x,y,z); 

     surfaceNormals[zi] = newNormalVector; 
     }   

     surfacePointer[x][y] = surfaceNormals; 
    } 

    return surfacePointer; 
} 

extractIS(0.45, isoSurfaces1); 
+0

您的問題描述很不清楚。你爲什麼不簡單地將所有數據存儲在一個'std :: vector'中,並使用數組算術來訪問元素?你爲什麼想在那裏使用地圖? – 2011-03-30 16:48:21

+0

花了我一些時間,但我想我明白了。當你在你的問題中說* 3D矢量*時,你的意思是像幾何中的矢量,對嗎?不是嵌套的'std :: vector'。那是對的嗎? – 2011-03-30 16:56:09

回答

4

如果我正確理解了你,你想使用座標作爲std :: map鍵嗎?

你可以只創建1只維的std ::地圖,並轉換XYZ座標爲1個三維座標系:

int pos1d = z*max_x*max_y+y*max_x+x; 

,然後只把那地圖鍵。

編輯:或者你可以只使用一個結構與X,Y,Z爲整數作爲Space_C0wb0y表現,當然,將採取每性病::地圖鍵3倍的內存,也注意到,比如我發現將具有最大的多維數據集大小:1625x1625x1625(如果是unsigned int),所以如果您需要更長的座標,則使用一個結構,但請注意,使用結構必須爲std :: map關鍵數據類型編寫比較函數。

EDIT3: 我覺得這是你在找什麼,因爲我注意到你使用最多256個座標值,這裏是我想出了:

// NOTE: max 256x256x256 cube coordinates with this struct. change unsigned char to short or int etc if you need larger values. 
// also note that if you change to something else than unsigned char, you cant use nor compare the union: v1.Pos > v2.Pos anymore. 
// (unless you use unsigned short for each coordinate, and unsigned __int64 for the union Pos value) 

union PosXYZ { 
    struct { 
     unsigned char x, y, z, padding; // use full 32bits for better performance 
    }; 
    unsigned __int32 Pos; // assure its 32bit even on 64bit machines 

    PosXYZ(unsigned char x, unsigned char y, unsigned char z) : x(x), y(y), z(z), padding(0) {} // initializer list, also set padding to zero so Pos can be compared correctly. 
}; 


inline bool operator>(const PosXYZ &v1, const PosXYZ &v2){ 
    return v1.Pos > v2.Pos; 
} 


typedef map<PosXYZ, Vector3f, greater<PosXYZ> > MyMap; 


void extractIS(float Threshold, MyMap &surfacePointer){ 
    for loop over x and y { 
     for loop over z { 
      // [ ... find surface voxels and their normal vectors ... ] 
      Vector3f newNormalVector(x,y,z); 

      surfacePointer[PosXYZ(x,y,z)] = newNormalVector; 
     }   
    } 
} 


MyMap isoSurfaces1; 

extractIS(0.45, isoSurfaces1); 

另一種方式來做到這一點的std ::地圖的關鍵結構是隻使用純整數值,您將通過自己的功能類似於產生:((X < < 16)|(Y < < 8)| Z),這將簡化事情,因爲你一點點不再需要std :: map的比較函數。

#define PosXYZ(x,y,z) (((x) << 16) | ((y) << 8) | (z)) // generates the std::map key for 256x256x256 max cube coords. 

typedef map<unsigned __int32, Vector3f, greater<unsigned __int32> > MyMap; 


void extractIS(float Threshold, MyMap &surfacePointer){ 
    for loop over x and y { 
     for loop over z { 
      // [ ... find surface voxels and their normal vectors ... ] 
      Vector3f newNormalVector(x,y,z); 

      surfacePointer[PosXYZ(x,y,z)] = newNormalVector; 
     }   
    } 
} 


MyMap isoSurfaces1; 

extractIS(0.45, isoSurfaces1); 
+0

謝謝菜鳥,但是我怎樣才能將地圖傳遞給函數? – Nat 2011-03-30 17:21:59

+0

我認爲你不應該從函數返回std :: map作爲返回值,而是使用std :: map作爲函數參數引用:'void extractIS(float Threshold,MyMap&surfacePointer){'從現在開始,你可以發送和以相同的參數返回std :: map。 – Rookie 2011-03-30 17:37:34

1

首先,地圖具有higher memory overheada vector。這引出了一個問題,那裏有多少元素?具有部分空的媒介是否可行?請看下面的實現:

struct 3dvec { 
    3dvec(int x, int y, int z) : x(x), y(y), z(z) {} 

    int x; 
    int y; 
    int z; 
}; 
std::vector<3dvec> empty_z_vector(4, 3dvec(0, 0, 0)); 
std::vector< std::vector<3dvec> > data(width*height, empty_z_vector); 

您簡單地將所有值在內存中,基於這樣的假設,只有少數人會是空的,而且永遠不會有超過4 z值。您可以在X, Y, Z位置訪問3dvec這樣的:

data[X + Y*width][Z] 

這使得很多的假設,但最終,你將有可能比較的解決方案,因爲可行性取決於數據。

+0

謝謝,林不知道我完全理解,但我已經有一個3D(幾何)矢量類,我想使用...數據由256 * 256 * 100體素,可能高達3 * 256 * 256表面法線向量需要並行存儲。這會工作嗎? – Nat 2011-03-30 17:36:27

+0

我是否正確假設,對於每個向量存儲3 * 256 * 256表面法向量?在那種情況下,用Rookie的解決方案你肯定會變得更好。 – 2011-03-30 20:37:12