2011-03-30 206 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