寻路优化(二)——二维地图上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)这个概念可能听过的人也很少,其主要是用在二值图像中,作为一个很有效的中间处理手段存在.一般的处理都是将灰度图处理成二值图或者一个二值图处理成另外一 ...
随机推荐
- jquery遍歷
遍歷是什麼? jquery的遍歷指的是移動,就是從選中的元素根據元素之間的關係移動,直到找到目標元素.從DOM樹中,可以進行向上移動(祖先),向下移動(子孫)和水平移動(同胞). 祖先就是父,祖父,曾 ...
- Educational Codeforces Round 26 B,C
B. Flag of Berland 链接:http://codeforces.com/contest/837/problem/B 思路:题目要求判断三个字母是否是条纹型的,而且宽和高相同,那么先求出 ...
- Maven项目读取resources下文件的路径问题(getClassLoader的作用)
读取resources下文件的方法 网上有问答如下:问: new FileInputStream("src/main/resources/all.properties") new ...
- day28 classmethod 装饰器
类方法装饰类方法 把一个方法变成类中的方法 之后调用此方法不需要对类实例化后在调用 直接通过类.方法即可调用 class Goods: __discount = 0.5 def __init__(se ...
- 19+ JavaScript 常用的简写技巧
博主说:对于任何基于 JavaScript 的开发人员来说,这绝对是一篇必读的文章,乃提升开发效率之神器也. 正文 js 1. 三元运算符 当你想用一行代码来写if...else语句的时候,使用三元操 ...
- # BZOJ5300 [CQOI2018]九连环 题解 | 高精度 FFT
今天做了传说中的CQOI六道板子题--有了一种自己很巨的错觉(雾 题面 求n连环的最少步数,n <= 1e5. 题解 首先--我不会玩九连环-- 通过找规律(其实是百度搜索)可知,\(n\)连环 ...
- 打开SharePoint 2013 web application显示iis 欢迎页面
当我打开SP web application时,页面显示如下: 查看event log,发现有一些8315-8317之类的error,发现把request management service停掉后, ...
- 洛谷 P4151 [WC2011]最大XOR和路径 解题报告
P4151 [WC2011]最大XOR和路径 题意 求无向带权图的最大异或路径 范围 思路还是很厉害的,上午想了好一会儿都不知道怎么做 先随便求出一颗生成树,然后每条返祖边都可以出现一个环,从的路径上 ...
- 继承的方式完成包装__attr__
__getattr__ 当实例要调用的属性不存在的时候会触发 __setattr__ 当实例要设置属性的时候会触发 __delattr__ 当实例要删除属性的时候会触发 这三个方法是 ...
- ElasticSearch 索引整体迁移方案
以下都是经过实战验证过的!!! [前提]使用相同的版本 ElasticSearch-5.5.1,只不过是在不同的服务器之间且重跑数据相对来说代价比较高,这种情况下就可以使用一下这种方式对索引整体迁移 ...