所以我试图获得六边形平铺地图的基本计算。我正在使用这个经典宝石中显示的菱形样式图(检查“菱形”选项):
https://www.redblobgames.com/grids/hexagons/#map-storage
在我的地图中,R和Q不一定相同,也就是说,地图可以是“矩形”。由于地图包含在R和Q中,因此有许多可能的正确距离,我有兴趣找到最短距离。
E.g。如果你去(0,0) - (1,0) - (2,0) - (3,0) - (4,0) - (4),从(0,0)到(4,2)的距离是6 ,1) - (4,2),但如果你去(4,2) - (5,1) - (6,0)=(0,0)
它是2所以我得到了这个正确计算这个包裹距离的代码:
public static Integer distance(HexCubeCoord origin, HexCubeCoord destination) {
// Normalize destination taking origin to (0, 0)
Integer dR = destination.getGridR() - origin.getGridR();
Integer dC = destination.getGridC() - origin.getGridC();
// Wrap normalized distance
HexCubeCoord normDest = new HexCubeCoord(HexCalculator.wrapR(dR), HexCalculator.wrapC(dC));
// Calculate distances to (0, 0) and the other three mirror origins
Integer d0 = simpleDistance(new HexCubeCoord(0, 0), normDest);
Integer d1 = simpleDistance(new HexCubeCoord(0, HexGridData.getColCount()), normDest);
Integer d2 = simpleDistance(new HexCubeCoord(HexGridData.getRowCount(), 0), normDest);
Integer d3 = simpleDistance(new HexCubeCoord(HexGridData.getRowCount(), HexGridData.getColCount()), normDest);
// Return the min of those four distances
return Math.min(Math.min(Math.min(d0, d1), d2), d3);
}
public static Integer simpleDistance(HexCubeCoord origin, HexCubeCoord destination) {
Integer dR = destination.getGridR() - origin.getGridR();
Integer dC = destination.getGridC() - origin.getGridC();
Integer dZ = - dC - dR;
return Math.max(Math.max(Math.abs(dR), Math.abs(dC)), Math.abs(dZ));
}
现在,我将使用距离计算A LOT,我希望它更简单。我已经花了很多时间试图减少所需的操作量,特别是我想避免计算到四个镜像原点的距离以获得最小的镜像原点。
我不是要求明显的优化,例如避免实例化新对象,我可以在以后弄清楚。我可以使用任何数学方法来使这个算法更简单吗?
答案 0 :(得分:0)
经过大量的工作和时间,我终于找到了一个似乎适用于我所有测试用例的距离计算。
我希望能回答我自己的问题,我将结果距离计算发布在一个环绕的六角形地图中,以防其他人发现它有趣。
public static Integer distance(HexCubeCoord origin, HexCubeCoord destination) {
// Normalize destination taking origin to (0, 0)
Integer dR = destination.getGridR() - origin.getGridR();
Integer dC = destination.getGridC() - origin.getGridC();
// Wrap normalized distance to get closer to (0, 0)
// Wrap c-wise
if (Math.abs(dC) >= HexGridData.getColCount() / 2) {
dC = (HexGridData.getColCount() - Math.abs(dC)) * (- Integer.signum(dC));
}
// Wrap r-wise
if (Math.abs(dR) >= (HexGridData.getRowCount() / 2) - Math.floor(dC / 2)) {
dR = (HexGridData.getRowCount() - Math.abs(dR)) * (- Integer.signum(dR));
}
Integer dZ = (- dC - dR);
// Calculate distance in the usual form
return Math.max(Math.max(Math.abs(dR), Math.abs(dC)), Math.abs(dZ));
}
它从https://blog.demofox.org/2017/10/01/calculating-the-distance-between-points-in-wrap-around-toroidal-space/中概述的方法开始,但是当包装r方式时,我添加“ - Math.floor(dC / 2)”部分来补偿网格上的分配( +,+)---( - , - )对角线。
编辑(1919年1月):
我发现提供的解决方案在某些极端情况下不起作用。
过了一段时间,我再次接受了这个问题,经过大量的尝试,我发现如果使用偏移坐标而不是轴向或立方体,计算环绕六边形地图中距离的问题就变得微不足道了。唯一需要注意的是,无论你决定做出什么偏移,行或列的数量必须是均匀的,这样地图才能正确包装。