|
|

楼主 |
发表于 2007-2-13 00:33:00
|
显示全部楼层
Re:游戏中碰到个有点棘手的算法问题
其实我想到一个解决方案了,只是用文字比较难表术:
我用的是计算几何+A*解决这个问题.计算几何里的射线扫描+线段树.
很多人写过A*,我也见过比A*更快速的搜索算法,不过在解决寻路问题上,都没什么创新,我也看过以前的程序写的A*算法,在游戏里,感觉很土,我这里说一种我对这个问题的解决方法,是有点麻烦,不过我一时想不出更好的了.
物体移动,只有两种状态,直线运动,或绕弯.如果起始点能够直线到目标点,那肯定是最短的,这个小学生都知道.
OK,这是非常重要的附加条件(1),我没有载入地图,我只有通过前期的预处理,得到障碍物的信息,每个障碍物,我都将它钩边,最后我得到的是n个多边形,对我来说多边形是没意义的,我只要他的边就够了,于是我保存了所有边的数据,附加条件(2).
接下来是算法的核心,我估计很多人想不到,即使想到也很难做出来,我怎么说没别的意思,从我个人经历看来,确实不大容易.
我将所有这些边用一个2维的线段树表示,如果你不理解线段树,那么将无法看下去了.搜索google:segment tree.
这样有什么好处呢?
我得到一个起点到终点的直线,判断有没障碍物的边和我的直线有交点,时间复杂度为O(2*LogN)N=2048,最多计算22次,每个线段求交做2个cross,就是向量的差基.所以一次判断直线是否直达目标点可以算是常数时间.
接下来,怎么做射线扫描和A*呢?
扫描说起来有点麻烦,不直观,明天去公司再画个图讲解一下.
目的就是找与障碍物的切点.
原理和凸包算法有点像.
就是以起点为根,到目标点,这跟线段,以起点S,为圆心,半径R = |V(S,D)|,S,为起始点,D就是目标点,为半径扫过去,扫一周,找出所有切点,最后的最短路径必然包含这些切线断,是不是,不知道我说的可以理解么?好接下来用A*的思路做下去就可以了.
扫描线的时间复杂度是O(nlogn),n = 线段的个数.因为对线段需要排序,所以最快也只能是这个复杂度了.
最后的时间复杂度是O(n^2+nlogn)
也就是说,和地图的大小一点关系都没有了,只是和障碍物的包围线段数量有关系.
|
|