算法 & 数据结构——导航网格

这是之前写的寻路算法《栅格导航寻路》

栅格导航: 顾名思义,所有格子大小都是一致的。格子大小决定寻路精度,对于大地图而言,格子数量会非常多,从而极度影响效率。

导航网格: 弥补了栅格的缺陷,网格可以由不同多边形构成,在数量上比栅格少很多。但是实现的难度比栅格导航复杂很多倍。算法分两部分,一部分 生成网格 ,一部分 搜索路径

生成网格:
  将区域用多边形划分,产生可用于寻路的网格信息。通常多边形的顶点都是有序的,这样有利于算法实现。其次虽然多边形的大小不用一致,但使用大小相差不大的多边形也有利于算法实现。

搜索路径:
  通过任意一种寻路算法,从网格信息中锁定一组网格路径,这组网格路径就是导航网格,再通过这组导航网格确定一条最快的路径。

本文使用相关算法与数据结构:
网格生成算法:德洛内三角剖分
锁定导航网格算法:A*
导航网格寻路算法:拐角算法

拐角算法:
  这是新学的算法,百度搜索结果不少,但全部都是转载的,原文是英文的,链接已经访问不了了。

参考博文中是这样描述的:

下图的5个凸多边形是已经生成的导航网格,多边形外部的区域为不可行走区域,current为起点,goal为终点,从图中就可以看出最短路径为图中红线,蓝色圈出的点为我们需要找出的点。所有多边形顶点均按逆时针方向存储。


算法 & 数据结构——导航网格_第1张图片
image

(1)下图显示出各区域之间的入口,即多边形的临边。由图中可以看出每个临边均为起点穿出该多边形区域的边,故以下称该边为穿出边。


算法 & 数据结构——导航网格_第2张图片
image

(2)首先找到起始点所在的多边形和穿出边的两个端点,由起点连接两个端点,形成两个线段lineLeft 和lineRight。如下图。绿色圈表示左点,红色表示右点(左点、右点是根据多边形顶点保存顺序而来)。


算法 & 数据结构——导航网格_第3张图片
image

(3)继续找到下一个穿出边的两个端点,判断新的左点是否在lineLeft 和lineRigh之间,如果在,则更新lineLeft为起点到新左点的线段。


算法 & 数据结构——导航网格_第4张图片
image

同样处理新穿出边的右点,如下图


算法 & 数据结构——导航网格_第5张图片
image

该步最后得到两个新的线段,如下图。


算法 & 数据结构——导航网格_第6张图片
image

(4) 继续判断下一个穿出边的两个端点,如下图,新的左点在lineLeft和lineRight的外面,则不更新线段。


算法 & 数据结构——导航网格_第7张图片
image

下图说明新的右点在两条直线之间,更新lineRight。


算法 & 数据结构——导航网格_第8张图片
image

该步最后得到两个新的线段,如下图。


算法 & 数据结构——导航网格_第9张图片
image

(5) 继续循环判断下一个穿出边的两个端点,该穿出边的两个端点都在lineRight的右侧,表示lineRight的终点即为路径的一个拐角点。


算法 & 数据结构——导航网格_第10张图片
image

(6) 循环以上步骤都可以找到从起点到终点的一条完整路径。

思路还算简单。

运行效果:

算法 & 数据结构——导航网格_第11张图片
TIM截图20180323151549.png

算法 & 数据结构——导航网格_第12张图片
TIM截图20180323151556.png
算法 & 数据结构——导航网格_第13张图片
TIM截图20180323151615.png

内部有圆圈的三角形为可走区域,空白为不可走区域,红圈表示被锁定的导航网格,红线是最优路径。

GitHub 包含寻路&网格生成两部分,附带已编译好的exe文件bin/目录下

你可能感兴趣的:(算法 & 数据结构——导航网格)