不是试图推导转折点,而是使用对算法在2D中的直观理解会更有帮助。因为两个位置之间的最短距离是一条直线,我们知道对角移动是最快的,因为它相当于在1D中走了
两步。在3D中,这意味着对角线相当于
三步(实际上,这些值分别是
sqrt(2)
和
sqrt(3)
)。基于此,我们选择通过
尽可能多地跨越轴来进行优化...沿着2D轴移动比沿着3D轴移动转弯更差。同样,沿着1D(直线)移动甚至比2D移动更
差。这就是JPS的核心假设。
在选材算法中,有一个假设,即如果您正在跳到最不理想的轴(1D),则在同一轴序上直到出现平行墙壁之前,没有更高轴序的最佳转弯(转向2D轴)。例如,请参见
图2(d),代码在1D中看到平行墙壁并将2D移动添加回列表中。
作为一种启发式方法,评估前进,直到只剩下一个空格(并且离墙还有2个空格),然后将此点添加到跳跃列表中。对于跳跃列表上的任何点,请朝新方向跳跃。目标> 2D运动向前> 1D运动向前> 1D运动向后> 2D运动向后。我们可以将此启发式方法推广到任何n维度...
评估下一步的方向,以+表示朝着目标方向,n表示增加的维数的数量,给我们这个方程式...
+
nD > +
n-1 D > ... +1D > 0D > -1D > ... > -
n-1 D > -
nD
在3D中最佳->最差转折点的顺序
- 3D+ = [1, 1, 1]
- 2D+ = [1, 1, 0], [1, 0, 1], [0, 1, 1]
- 1D+ = [1, 0, 0], [0, 1, 0], [0, 0, 1], [-1, 1, 1], [1, -1, 1], [1, 1, -1]
(以下为次优解;[0, 0, 0]是无用的,因此我没有包含它)
- 0D = [1, -1, 0], [1, 0, -1], [-1, 1, 0], [-1, 0, 1], [0, -1, 1], [0, 1, -1]
- 1D- = [-1, 0, 0], [0, -1, 0], [0, 0, -1], [-1, -1, 1], [1, -1, -1], [-1, 1, -1]
- 2D- = [-1, -1, 0], [-1, 0, -1], [0, -1, -1]
- 3D- = [-1, -1, -1]
呼 打这些真的很痛苦,但它应该能解决你的问题。
请记住,当你“跳跃”时,要记录你跳跃的轴顺序;你需要在
同一轴上找到平行的墙壁。因此,向[1,0,1]方向移动,您要找到位于[1,1,0]和[0,1,1]的墙壁,以便“解锁”朝向[1,1,1]的跳跃点。
用相同的逻辑,如果您沿着1D [1,0,0]移动,则检查[0,1,0]是否有墙壁可添加[0,1,1]和[1,1,0]。您还要检查[0,0,1]以添加[1,0,1]和[0,1,1]作为跳跃点。
希望您明白我的意思,因为这很难想象和计算,但一旦掌握了数学知识,就很容易理解。
结论
使用A*启发式算法...
- 迪杰斯特拉=距离起点的距离
- 贪婪优先=距离目标的距离
然后添加我们的新启发式算法!
- +nD > +n-1 D > ... +1D > -1D > ... > -n-1 D > -nD
- 如果任何一个点nD有平行障碍,您可以为每个打开的n+1 D方向添加跳跃点。
编辑:
您代码中“平行”的定义
- 与您移动的方向相同顺序的任何点
- 不是该方向上的下一个点
- 具有与下一个点相同数量的正维度移动和负维度移动(例如,[1、1、-1]与[1、-1、1]和[-1、1、1]平行,但不是与[1、0、0])