寻路优化(二)——二维地图上theta*算法的设计探索
这篇文章是基于上一篇文章的研究上进行的,使得路径更加的平滑和自然,特此记录。有错误欢迎大家批评指正。如需转载请注明出处,http://www.cnblogs.com/Leonhard-/p/6866070.html,这是对作者最起码的尊重,谢谢大家。
本文结构如下:
一、Theta*算法、LazyTheta*算法背景介绍
二、Lazy Theta*算法介绍与实现简述
三、深入思考优化需求
1.网格中的阻挡判定
2.效果受A*算法影响
3.lazy theta* cost的限制
四、总结
一、Theta*算法、LazyTheta*算法背景介绍
在上一篇文章中,考虑的是用A*得到一条“最优”的算法,且尽可能的去防止玩家选择上的“抖动”。这里“最优”是基于一个前提,那就是必须沿着地图网格里的格子,一个格子一个格子的跳,像跳棋一样,也就是说,角色移动的角度只能是45的倍数。一条可能的移动路径如下:

这又出现了新问题,假设我们在现实生活中,走路会这么走吗?这让我们的寻路显得非常的僵硬。那最直接的方法就是直接从起点直接走向终点。那此时允许角色往任意角度移动的Theta*算法就派上了用场,而LazyTheta*在Theta*上做了一个性能优化,只对其中的一部分有必要处理的点进行处理。本文的目的就是讨论在二维网格地图上使用lazy theta*算法。
二、Lazy Theta*算法介绍与实现简述
theta*算法和lazy theta*算法和A*算法大部分是一样的,只是theta*类算法比A*多了一个收缩父节点的操作,具体的theta*算法和lazy theta*算法的介绍可以参看这篇blog,这里就不再对重复的内容进行复制粘贴。这里简单的对实现思路进行一个简要的描述,如上图的路径,我们发现其实不需要记录A*算法结果的每一个点,只需要记录起点(s)和终点(d)还有拐角的点(p)三点即可,中间的值就可以通过插值得出。此时,我们把p把的父节点记录为s,而d的父节点记录为p。这样的话,在我们利用A*计算路径的过程之后,将A*算法得到的路径节点进行一一的检测,如果pcurrent、pcurrent->parent和pcurrent->parent->parent三点共线,那么我们直接把pcurrent->parent = pcurrent->parent->parent(A* with post-smoothed paths)。而theta算法,则在此基础上进一步优化,当我们把节点加入到open队列时,我们对该节点进行测试,如果pcurrent和pcurrent->parent->parent之间是否存在一条路径,则把pcurrent->parent = pcurrent->parent->parent并重新设置pcurrent的cost值,如果不存在就什么都不做。而Lazy theta*则是,把节点测试放到了节点从heap里弹出之后,减少了不必要的节点计算。下图为计算的过程。黑色斜线为中间计算结果,黄色线段为最后的结果,也就是说,在这幅图里,Lazy theta*的最终结果就是两个点,起点和终点。

三、深入思考优化需求
1.网格中的阻挡判定
在之前的A*算法寻路中,要判定一个格子是否被占用,只需要对MapManager进行一次查询操作即可,但是现在的移动是任意角度的移动,这需要进一步考虑如何判定任意两个点之间是否存在一条路径。以dx>dy >0的情况为例子。

此时,当我们要判定当X=2时,在地图上是否能够通过时,此时我们需要判定(2,1)和(2,2)两个点的可达性,如果两点都可达,那么直线上的点在X=2时才可达。(也可以只判定一个点,但是这我们项目里,也可能会出现奇怪的现象,具体情况具体分析。而计算方法则可以通过给出直线方程的隐式方程来快速计算)
2.效果受A*算法影响
theta*算法可以优化A*的路径,但是如果A*算法部分做的不够好的话,theta*效果会大打折扣。下面以例子说明。

如果A*的寻路结果如棕色线条时,我们期待的theta*优化结果如红色线条所示,但是,实际上拐角左边的线上的每一个点的parent都为s点,当进行拐角右边路线规划时,会计算该条线上每一点与source点的可达性,但是如图所示,此时的每一条线段是不可达的,所以,这种情况红色线条的优化不会发生。如果要让红色线条被优化的话,需要参照上一篇文章,修改A*的估值函数来实现。
3.lazy theta* cost的限制
如果优化线条成立,那么就得给予被优化的节点一个新的cost值。那么这个cost值有什么要求呢?这起码得符合三角形法则(斜边不能大于两边之和,也不能小于两边之差)。否则,在特殊的情况下会出现意想不到的问题,例如下图,按理说,走的10->20->30是最短的路径,但是因为优化路径的奇怪权值,会导致结果按100->200走。

四、总结
theta*算法可以让路径规划先得平滑自然,而且可以实现任意角度朝向的移动,还可以很方便的实现非网格地图的寻路计算。但是这相比A*算法也会增加额外的计算量,具体使用时,需要在效果和性能中间做一个权衡。
寻路优化(二)——二维地图上theta*算法的设计探索的更多相关文章
- 寻路优化(一)——二维地图上A*启发函数的设计探索
工作中需要优化A*算法,研究了一天,最后取得了不错的效果.看网上的朋友还没有相关的研究,特此记录一下.有错误欢迎大家批评指正.如需转载请注明出处,http://www.cnblogs.com/Leon ...
- 【opengl】OpenGL中三维物体显示在二维屏幕上显示的变换过程
转自:http://blog.sina.com.cn/s/blog_957b9fdb0100zesv.html 为了说明在三维物体到二维图象之间,需要经过什么样的变换,我们引入了相机(Camera)模 ...
- WPF技术触屏上的应用系列(二): 嵌入百度地图、API调用及结合本地数据库在地图上进行自定义标点的实现
原文:WPF技术触屏上的应用系列(二): 嵌入百度地图.API调用及结合本地数据库在地图上进行自定义标点的实现 去年某客户单位要做个大屏触屏应用,要对档案资源进行展示之用.客户端是Window7操作系 ...
- 通过百度地图API显示当前位置在地图上(图标显示)--第三方开源--百度地图(二)
1.下载百度地图的demo,下载地址:http://lbsyun.baidu.com/sdk/download?selected=mapsdk_basicmap,mapsdk_searchfuncti ...
- 在A*寻路中使用二叉堆
接上篇:A*寻路初探 GameDev.net 在A*寻路中使用二叉堆 作者:Patrick Lester(2003年4月11日更新) 译者:Panic 2005年3月28日 译者序 这一篇文章,是&q ...
- Java Web 前端高性能优化(二)
一.上文回顾 上回我们主要从图片的合并.压缩等方面介绍前端性能优化问题(详见Java Web 前端高性能优化(一)) 本次我们主要从图像BASE64 编码.GZIP压缩.懒加载与预加载以及 OneAP ...
- MySql学习(六) —— 数据库优化理论(二) —— 查询优化技术
逻辑查询优化包括的技术 1)子查询优化 2)视图重写 3)等价谓词重写 4)条件简化 5)外连接消除 6)嵌套连接消除 7)连接消除 8)语义优化 9)非SPJ优化 一.子查询优化 1. ...
- 转 cocos2dx内存优化 (之二)
一.cocos2dx之如何优化内存使用(高级篇) 本文由qinning199原创,转载请注明:http://www.cocos2dx.net/?p=93 一.内存优化原则 为了优化应用内存,你应该知道 ...
- SSE图像算法优化系列二十五:二值图像的Euclidean distance map(EDM)特征图计算及其优化。
Euclidean distance map(EDM)这个概念可能听过的人也很少,其主要是用在二值图像中,作为一个很有效的中间处理手段存在.一般的处理都是将灰度图处理成二值图或者一个二值图处理成另外一 ...
随机推荐
- 《ERP系统原理与实施》
第一 采购 第二 生产(生产任务->生产准备->加工单->派工单->生产调度->生产监控->数据采集->统计分析) 第三 仓储 第四 质量 第五 财务 第六 ...
- js對象構造
創建對象的3種方式: 1. var a=new Object() a.attributes=“1”: 2. var a={attributes:"1",aa:"2&quo ...
- Async和Await 异步方法
Async和Await关键字是C#异步编程的核心.通过使用这两个关键字,你可以使用.NET Framework或Windows Runtime的资源创建一个异步方法如同你创建一个同步的方法一样容易.通 ...
- 洛谷P3085 [USACO13OPEN]阴和阳Yin and Yang(点分治,树上差分)
洛谷题目传送门 闲话 偶然翻到一道没有题解的淀粉质,想证明一下自己是真的弱 然而ZSYC(字符串组合)早就切了 然后证明成功了,WA到怀疑人生,只好借着ZSY的代码拍,拍了几万组就出来了... 思路 ...
- LOJ #6432. 「PKUSC2018」真实排名(组合数)
题面 LOJ #6432. 「PKUSC2018」真实排名 注意排名的定义 , 分数不小于他的选手数量 !!! 题解 有点坑的细节题 ... 思路很简单 , 把每个数分两种情况讨论一下了 . 假设它为 ...
- 洛谷 P1381 单词背诵 解题报告
P1381 单词背诵 题目描述 灵梦有\(n\)个单词想要背,但她想通过一篇文章中的一段来记住这些单词. 文章由\(m\)个单词构成,她想在文章中找出连续的一段,其中包含最多的她想要背的单词(重复的只 ...
- luogu2865 路障 (dijkstra)
求次短路,dijkstra时同时记下到某点的最短距离和次短距离即可. #include<cstdio> #include<cstring> #include<algori ...
- python 线程,进程28原则
基于函数实现 from threading import Thread def fun(data, *args, **kwargs): """ :param data: ...
- Ubuntu无法进入Windows的NTFS分区
在Ubuntu进入NTFS分区出现问题,无法访问. 不能访问 新加卷 Error mounting /dev/sda8 at /media/zhuxiaoxi/新加卷: Command-line `m ...
- 2018 省选 D1T2 IIIDX
题目大意: 给出k.n个数选择一种字典序最大的排列,使得对于任意的i,di>=d[i/k](下取整 下同) 分析: 很容易想到的是建树,将i的父亲设为[i/k],之后建有向边. 60分贪心: 将 ...