C++ 在六边形图中,如何存储三维坐标作为一维容器的索引/如何使用三维坐标从一维容器检索元素?

C++ 在六边形图中,如何存储三维坐标作为一维容器的索引/如何使用三维坐标从一维容器检索元素?,c++,containers,coordinates,C++,Containers,Coordinates,我正在尝试使用立方体坐标存储六边形的图形,详细内容见 我想使用一个向量或一些易于迭代的容器来存储十六进制对象,基本上是三维整数坐标的集合加上一个包含相邻十六进制索引的向量 我的问题是,我很难找到将立方体X/Y/Z坐标(允许负整数值)转换为相应1D容器索引的函数。给定任何一组有效的坐标,我希望能够得到十六进制的特定索引号 我知道有一个函数的工作原理如下 1D_指数=f(x,y,z)=x+(最大宽度)*y+(最大宽度)(最大高度)*z 对于笛卡尔网格,但在六边形空间中生成类似函数时遇到困难: 我的

我正在尝试使用立方体坐标存储六边形的图形,详细内容见

我想使用一个向量或一些易于迭代的容器来存储十六进制对象,基本上是三维整数坐标的集合加上一个包含相邻十六进制索引的向量

我的问题是,我很难找到将立方体X/Y/Z坐标(允许负整数值)转换为相应1D容器索引的函数。给定任何一组有效的坐标,我希望能够得到十六进制的特定索引号

我知道有一个函数的工作原理如下

1D_指数=f(x,y,z)=x+(最大宽度)*y+(最大宽度)(最大高度)*z

对于笛卡尔网格,但在六边形空间中生成类似函数时遇到困难:

我的十六进制类和容器如下所示:

class Hex
{
private:
    int xCell, yCell, zCell;
    std::vector<int>neighbours;

public:
    Hex();
    Hex(int x, int y, int z) : _x(x), _y(y), _z(z);
    ~Hex();
};


std::vector<Hex*>hexGraph;
十六进制类
{
私人:
int xCell、yCell、zCell;
std::矢量邻居;
公众:
十六进制();
十六进制(intx,inty,intz):x(x),y(y),z(z);
~Hex();
};
矢量六角图;
为了用未连接的节点填充图形,我只使用列出所有可能存在的坐标,给定图形的正负x/y/z维度:


for(int x = effectiveWorldNegX; x < effectiveWorldPosX; x++)
        for(int y = effectiveWorldPosY; y > effectiveWorldNegY; y--)
            hexGraph.push_back(new Hex(x,y,(x*-1)-y)); // x+y+z=0, so z=(-x-y)

for(int x=effectiveWorldNegX;xeffectiveWorldNegY;y--)
六角图形。推回(新的六角(x,y,(x*-1)-y));//x+y+z=0,所以z=(-x-y)
现在我被难住了。我想使用如下循环连接节点:

for(std::vector<Hex*>iterator it = hexGraph.begin(); it != hexGraph.end(); ++it)
{
(*it)->neighbours.push_back( /* Index of upper left hex node */ )
(*it)->neighbours.push_back( /* Index of upper center hex node */ )
(*it)->neighbours.push_back( /* Index of upper right hex node */ )
...

}

for(std::vectoriator it=hexGraph.begin();it!=hexGraph.end();+it)
{
(*it)->邻居。向后推(/*左上角十六进制节点的索引*/)
(*it)->邻接。向后推(/*上中心六角节点索引*/)
(*it)->邻居。向后推(/*右上角十六进制节点的索引*/)
...
}
以此类推,但为了做到这一点,我需要一种方法来找到任何单元格+1x,-1y,+0z的索引

从上面的循环中,我所确定的是 1) 给定循环的开始/结束,将六角体推回六角图向量的确切顺序

2) 我可能需要也可能不需要将所有坐标值从0偏移负X/Y/Z距离,以删除负片

但我能从这里走到哪里


非常感谢您的帮助。

解决此问题的一种方法是为图形的每个顶点提供一个
id
,然后通过id引用相邻顶点

范例

using VertexId = size_t;

class Hex {
    std::vector<VertexId>neighbours;
  public:
    Hex(int x, int y, int z);
};

class VertexStorage {    
    std::unordered_map<VertexId, Hex> _id_to_hex;
    std::unordered_map<Hex, VertexId> _hex_to_id;
  public:
    // check if hex is in storage, return id
    // if not, assign new id an push tostorage
    // id could be increasing counter
    VertexId getId(const Hex &hex);
    Hex getHex(VertexId id);
};
使用VertexId=size\u t;
十六进制类{
std::矢量邻居;
公众:
十六进制(整数x,整数y,整数z);
};
类VertexStorage{
std::无序映射_id_到_hex;
std::无序映射到id;
公众:
//检查hex是否在存储器中,返回id
//如果没有,则为新id分配一个push-tostorage
//id可能正在增加计数器
VertexId getId(常量十六进制和十六进制);
Hex getHex(VertexId id);
};

解决此问题的一种方法是为图的每个顶点提供一个
id
,然后按id引用相邻顶点

范例

using VertexId = size_t;

class Hex {
    std::vector<VertexId>neighbours;
  public:
    Hex(int x, int y, int z);
};

class VertexStorage {    
    std::unordered_map<VertexId, Hex> _id_to_hex;
    std::unordered_map<Hex, VertexId> _hex_to_id;
  public:
    // check if hex is in storage, return id
    // if not, assign new id an push tostorage
    // id could be increasing counter
    VertexId getId(const Hex &hex);
    Hex getHex(VertexId id);
};
使用VertexId=size\u t;
十六进制类{
std::矢量邻居;
公众:
十六进制(整数x,整数y,整数z);
};
类VertexStorage{
std::无序映射_id_到_hex;
std::无序映射到id;
公众:
//检查hex是否在存储器中,返回id
//如果没有,则为新id分配一个push-tostorage
//id可能正在增加计数器
VertexId getId(常量十六进制和十六进制);
Hex getHex(VertexId id);
};