计算2D阵列中的2个点

时间:2015-02-23 12:10:51

标签: java algorithm coordinates shortest-path

我正在做2D阵列贴图:

* 0 1 2 3 4 5 6
0 # # # # # P #
1 # # # # # # #
2 # # # # # # #
3 # # T # # # #
4 # # # # # # #

这是一款游戏。 'T'是巨魔,'P'是玩家。 Troll在这场比赛中追逐球员。假设玩家现在不会移动。 Troll的位置(行,列)是(3,2)和玩家(0,5)

Troll可以通过向右上方向走来追逐玩家。这意味着,到达P位置只需3个步骤:

(3,2)->(2,3)->(1,4)->(0,5)

但是,当我使用欧几里德距离公式时:

    (int) Math.floor(Math.sqrt(Math.pow((0-3) , 2) + Math.pow((5-2) , 2))) ;

去那里需要4个步骤。

我对距离公式很困惑。在这种情况下我不能用它吗?但在某些情况下,它需要采取正确的步骤。

希望有人能解释这个问题,谢谢。

1 个答案:

答案 0 :(得分:6)

我认为你指的是能够在对角线上移动。如果你在对角线上移动,你实际上会移动sqrt(2)“单位”,这样你就可以“移动得更快”,因为当你使用对角线时,每步需要多个单位。

当你有巨魔并且玩家使用相同的x或y值对齐时,它适用于某些情况,所以你只需要一个单位就可以找到他。


如果你想避免对角线,那么你不能采取“更快”的动作,一个好的距离度量是manhattan distance,这基本上是

manhattan_distance(a,b) = abs(a.x - b.x) + abs(a.y - b.y)

添加:如果您要启用digonals,可以将距离计算为:

diffX = abs(a.x - b.x)
diffY = abs(a.y - b.y)
numSteps = max(diffX, dixxY) //max is returning the higher value of both.

这是有效的,因为你要做尽可能多的对角线移动,这个数字是min(diffX,diffY),然后你只需要移动一个轴来提醒移动,你就“接近”在这个轴上min(diffX,diffY)步,所以你要做max(diffX-diffY) - min(diffX,diffY)次移动,现在将两种“移动(对角线/非对角线)移动”加起来,得到:

numMoves = max(diffX-diffY) - min(diffX,diffY) + min(diffX,diffY) = max(diffX-diffY)

示例,在您的矩阵上:

diffX = abs(3-0) = 3
diffY = abs(2-5) = 3
max(diffX,diffY) = 3 

<强> TL; DR:

  • 经典欧几里德距离不起作用,因为对角线处于 长度sqrt(2) - 所以你在使用它时移动得更快。
  • 可以通过避免对角线和使用曼哈顿来解决 距离dist(a,b) = abs(a.x - b.x) + abs(a.y - b.y)
  • 或者通过允许对角线和使用距离度量: dist(a,b) = max{abs(a.x-b.x),(a.y-b.y)}