如何储存坐标以表现类六边形结构?

4
我知道有很多关于像素和六边形的问题,但我仍然难以理解其中某些方面。此外,我不确定这会有多大的区别,但我正在使用Java进行开发。
首先,我理解笛卡尔坐标系可以存储在一个二维数组中,使得棋盘上的每个坐标都是二维数组中的一个条目。但是,我想使用一种六边形的网格来创建更好的游戏网格,就像Amit的页面http://www.redblobgames.com/grids/hexagons/中描述的那样。
我理解在创建六边形网格之后的概念(使用x、y、z获取相邻坐标),但是我无法存储我的坐标。以前,每个坐标对应于二维数组中的一个条目(笛卡尔坐标系)。现在,我不确定如何使其对应以获得坐标之间的六边形关系。
按照指南,我尝试在每行偏移坐标(特别是尝试链接中的偶数行偏移示例),如下所示:

enter image description here

在这个例子中,上方是坐标,下方是数组的可视化表示(空格是具有“跳过”哨兵的条目,1是与坐标相对应的条目)。
每个坐标的邻居是{{-1,1},{1,1},{1,-1},{-1,-1},{0,2},{0,-2}}。然而,我认为这并不正确?我想到了其他实现六边形网格的方法,其中之一是使用双向链表结构从中间开始,并将坐标关联为“节点”,或硬编码地图(这几乎是不可能的,因为我计划制作一个大地图)。但是,我宁愿坚持偏移量的想法,因为它更容易使用。
我认为我的问题在于每一行都应该偏移1/2,但我给它们“洞”(哨兵条目)。也许我应该使用六边形的几何来将坐标转换为六边形。但是,除非将它们存储在某些数据结构中,否则我无法在路径查找时使用这些单独的六边形。任何代码或帮助都将不胜感激。
1个回答

3
        0   1   2   3   4   5
      0   1   2   3   4   5
    0   1   2   3   4   5
  0   1   2   3   4   5
0   1   2   3   4   5

如果您不介意地图略呈菱形,您可以将一组六边形整齐地适配到一个二维数组中。在节点之间行进时,数学计算将保持一致--(东西方向改变x,东北/西南方向改变y,西北/东南方向同时改变)。
基本上,您正在使用坐标映射作为参考。您不需要实际将地图构建成二维数组。相反,您使用坐标映射来简化关系。
例如,您可以将坐标映射到哈希表中。
map.put("0,2", new Tile(0,2,"Green"));
map.put("0,3", new Tile(0,3,"Yellow"));
map.put("0,4", new Tile(0,4,"Green"));
map.put("0,5", new Tile(0,5,"Green"));
map.put("1,2", new Tile(1,2,"Blue"));
map.put("1,3", new Tile(1,3,"Red"));
map.put("1,4", new Tile(1,4,"Orange"));
map.put("2,1", new Tile(2,1,"Orange"));

对于任何给定的瓦片,您可以通过引用HashMap在O(1)时间内回答任何给定方向是否可用,并检索该方向上的瓦片。 您的节点(例如Tile对象)不需要任何相邻节点的引用。 您的坐标系统会处理这个问题。


我不确定您该如何初始化二维数组?使用双重循环,如何在分配值之前知道要在第一行留多少空间? - shanshine
这取决于你的地图形状。如果它是如图所示的菱形形状,你就不需要留下任何空格。如果你想要一个扁平的六边形形状,你可以省略(0,0)、(0,1)、(1,0)、(3,5)、(4,4)、(4,5)。你的for循环可以遍历整个地图,只处理非空值。 - phatfingers
我的地图实际上是一个矩形窗口的全部,大约有720 x 720个节点(每个节点中存储坐标)。是否有方法可以计算要留下左右哪些部分? - shanshine
每行的偏移成本为一半,因此如果您希望在数组中保持从零开始,您的左下角(取决于如何定义x和y)将从359开始。请记住,“数组”只是一种映射坐标的方式--您不一定需要构建它。例如,您的节点数据库可以存在哈希映射表中。 - phatfingers
对于一个nxn的棋盘,偏移量为n/2-1,那么对于一个nxp的棋盘,偏移量是多少呢?例如1080 x 720或600 x 800? - shanshine
这将是p/2-1。当然,如果您不打算实际存储在数组中,那么您可以随意偏移它,或允许其变为负数。任何方向的遍历或确定相邻节点的数学计算都将保持不变。 - phatfingers

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接