【问题标题】:Need help understanding a posted algorithm (calculating step distance between hexagons on a grid)需要帮助理解已发布的算法(计算网格上六边形之间的步距)
【发布时间】:2012-03-14 17:19:10
【问题描述】:

我一直在寻找有关如何准确地将六边形网格上的两个六边形之间的距离计算为多个六边形或“步数”的答案。

我看到了这个帖子,这似乎是正确的解决方案,因为我的六边形设置完全符合 Torben 的描述,但是我正在尝试找出他提出的算法。具体来说:

mydistance((x1,y1), (x2,y2))
     = if x1>x2 then mydistance((x2,y2), (x1,y1))
       else if y2>=y1 then x2-x1 + y2-y1
       else max(x2-x1, y1-y2)

我很确定他是在描述一种算法,但是,我对他所说的“mydistance((x2,y2),(x1,y1))”等含义感到迷茫。我认为他可能指的是公式2点之间的距离?我试过了,但没有成功:(此外,他在=之前说它在上面,这让我很失望。

谁能准确理解他的意思?

谢谢!!!

编辑(重要)----这是我的六边形网格图案的图像,以提供一些启示:请访问 http://www.bart4president.com/test/hexGrid.jpg

以下是原始帖子的剪辑:


我更喜欢 x 和 y 都对应直线的编号 十六进制数,即让 x 通过向右增加(以常数 y) 并且 y 从右侧向下 60 度增加(x 为常数) (假设 (0,0) 是左上角)。

这样,如果你沿着三个“自然”方向之一移动,你 要么有常数 x、常数 y 或常数 (x+y)。

这使得距离等的计算更容易,因为您不必 奇数行和偶数行的特殊情况。

我假设您知道十六进制坐标并想在 跨边移动时的十六进制数。

如果您使用了我上面描述的替代编号,则 距离计算如下:

mydistance((x1,y1), (x2,y2))
 = if x1>x2 then mydistance((x2,y2), (x1,y1))
   else if y2>=y1 then x2-x1 + y2-y1
   else max(x2-x1, y1-y2)

使用您所访问的网页上显示的编号,您可以计算 距离如下:

yourdistance((x1,y1),(x2,y2))
 = mydistance((x1 - y1 `div` 2,y1), (x2 - y2 `div` 2,y2))

即转换为更简单的坐标系并计算距离 在那里面。您通过减去 y 坐标的一半进行转换(四舍五入 下)从 x 坐标。

托本

【问题讨论】:

  • “要了解递归,首先必须了解递归。”

标签: java algorithm distance


【解决方案1】:

为了比较,这是我计算两个十六进制之间距离的代码:

/**
 *  Hex distance calculation
 */
public static int distance(int x1, int y1, int x2, int y2) {
    int dx=x2-x1;
    int dy=y2-y1;

    if (dx*dy>0) {
        return Maths.abs(dx)+Maths.abs(dy);
    } else {
        return Maths.max(Maths.abs(dx),Maths.abs(dy));
    }
}

(x1,y1) 和 (x2,y2) 是您要计算距离的两个十六进制的坐标。请注意,这些坐标不像在方形网格上那样成直角:增加 x 和增加 y 相距 60 度。

【讨论】:

  • 我会试一试……待命!
  • P.S.如果你想直接使用它,那么你可能需要将Maths 转换为java.util.Math:上面的代码实际上使用了不同的数学库(但我认为在这种情况下函数是相同的)。
  • 知道了 Mikera.. 但是我认为我的网格设置可能有点不同.. 它在某些情况下有效.. 但在其他情况下却不行。很难解释,但如果我不能让它工作,那么我会发布一张我的板是如何设置的图片。
  • Mikera 看看bart4president.com/test/hexGrid.jpg,看看你的逻辑是否符合?
  • 如果您的 x 轴和 y 轴相距 120 度,那么我认为您可以交换 if 语句的两个分支。如果您有交错的六角列(即 x 方向在 60 度和 120 度之间交替),那么公式会变得更加复杂......
【解决方案2】:

在六角坐标系中,y 轴与 x 轴成 60 度角。这避免了奇偶行的区别。六边形坐标系中的距离为:

dx = x1 - x0
dy = y1 - y0

if sign(dx) == sign(dy)
    abs(dx + dy)
else
    max(abs(dx), abs(dy))

您可以使用以下方法将 (x', y) 从您的坐标系转换为 (x, y)

x = x' - floor(y/2)

所以dx 变成:

dx = x1' - x0' - floor(y1/2) + floor(y0/2)

使用整数除法实现此操作时要小心舍入。在 Java 中,int y floor(y/2)(y%2 ? y-1 : y)/2

【讨论】:

  • 请原谅这个菜鸟问题,但是你所说的 sign(dx) == sign(dy) .. 特别是 "sign" 是什么意思?谢谢你的回复。
  • 实际上,您的公式似乎与 mikera 给我的公式相同。我认为这只是我如何设置十六进制的问题。看看:bart4president.com/test/hexGrid.jpg 我是如何设置的。再次感谢!
  • 字面意思是标志:+ or - :)
【解决方案3】:

你写:

我很确定他在描述一种算法,但是,我得到了 迷失了他所说的“mydistance((x2,y2),(x1,y1))”等的意思。我想 他可能是指两点之间的距离公式?

只是为了了解这一点,正如对您问题的评论所暗示的那样,但似乎没有一个答案已经解决:

语句mydistance((x2,y2), (x1,y1)) 是对正在定义的函数的递归 调用。在这种情况下,如果使用x1>x2 调用该函数,则该函数将在交换点的情况下再次调用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-01
    • 2017-11-24
    • 1970-01-01
    • 2020-01-20
    • 2022-01-05
    • 1970-01-01
    相关资源
    最近更新 更多