AStar 拐点 算法实现AI寻路

一般来说,在项目中实现完整的寻路解决方案,是使用寻路算法(AStar只是其中一种)和拐点算法共同实现的。AStar这个算法相对知名,网上有大量的博文介绍,本文着重介绍拐点算法。

演示

在这里插入图片描述
具体项目可以在我的GitHub仓库中查看:传送门

AStar

AStar被称为启发式寻路算法,终点在于其启发函数的设置,在网上文章可以看到FGH值,其中F就是最终的启发函数的值。

  1. 可以根据自己的需求进行相对应的GH值计算,也可以进行加权重。例如:地图中有沼泽地,那么相应的沼泽地通过时候,它的启发函数计算权重就要加大。
  2. 大部分都是用方格进行平铺地图,这样只是方便好理解,真正项目中大多数使用的是凸多边形或者Unity的NavMesh,无论什么样的网格,核心都是AStar的启发函数的计算。(本文使用方格)
    具体AStar算法可以在网上找些其他博主的文章来看。

为什么要使用拐点算法

在这里插入图片描述

如上图:
其中绿色是起点,红色是终点。
正常的AStar寻路找到的路径是格子的路径,如图中绿色、蓝色、红色的点的,但是寻路后进行移动,按照这些点来移动,一定是不符合常理的,看起来很呆。而我们期望的是按照红色的线段来走(绿色、黑色、红色这些点)。而拐点算法就是在已有的格子路径中通过算法找到发生拐弯的点,这些点组成最终的寻路轨迹点。

实现文章开头效果的整体思路

1. 准备地图网格数据
- 每个格子的位置、范围
- 每个格子需要存储相邻的网格
- 每个格子需要存储相邻的网格公用的边
2. 寻找起点格子和终点格子

通过鼠标点击的点,判断点落在哪个格子内。
如果是统一的格子,可以直接通过坐标计算点坐在的格子下标(更省计算量)
如果不是统一的格子,遍历查找点

3. AStar搜索路径

前一步找到起点和终点格子,通过AStar算法搜索格子路径

4. 计算拐点

依据上一步找到的路径,通过拐点算法找出拐点
(本文着重介绍)

5. 按需移动

找到拐点后按移动路径移动即可
起点 → 拐点1 → 拐点2 → … → 拐点n → 终点

拐点算法介绍

例如我们某一次AStar搜索的格子路径如下图在这里插入图片描述
绿色是起点,红色是终点。

算法核心如下图:

在这里插入图片描述
格子中0、1、2分别代表当前格子,下一个格子、下下一个格子
P01Left、P01Right 代表格子0和格子1的邻边的左右点
P12Left、P12Right 代表格子1和格子2的邻边的左右点
需要判断两组顶点的位置关系,也就是判断棕色开口和黑色开口的位置关系。unity中Vector3.Cross可以判断向量的左右方向,所以只需要判断当前点(起点或某一拐点)和各个顶点组成的向量方向即可。

两个开口有如下几种位置关系:
在这里插入图片描述
需要按照各个位置关系更新黑色的开口(更新确定黑色开口的三个点,一个拐点,两个顶点)
更新的方式:
1. 两点均在开口内侧 顶点更新为新的两个点
2. 两点在开口外两侧 不操作
3. 左右点均在开口左侧 左点为拐点
4. 左右点均在开口右侧 右点为拐点
5. 左点在开口左侧,右点在开口内侧 左顶点是拐点 更新左顶点
6. 左点在开口内侧,右点在开口右侧 右顶点是拐点 更新顶右点

接下来就按照上面的位置关系实际处理格子路径:
在这里插入图片描述
实际移动效果
在这里插入图片描述

如果看动图不容易理解的话,可以自己试着根据规则画画看。
拐点的计算主要是要考虑考多种情况,尤其向量重合时候的区分。
代码部分可以在我的GitHub工程查看:传送门

PS:目前一些特殊情况的处理还有点问题,但核心算法已完成,无论是方格还是凸多边形的网格,都需要多次测试调优,仅供参考

猜你喜欢

转载自blog.csdn.net/YuAnHandSome/article/details/120489189