关于基础的a*算法请参考:Unity A星寻路算法实现
首先要理解什么是四叉树?为什么它可以达到优化的效果。它对a*算法的哪一步进行了优化?
四叉树,就是每个父节点有四个子结点的树。当在计算8邻域的寻路消耗时,若地图越大,点数越多,计算就会越多,效率越慢,原因在于计算冗余(均分的网格,无论有无必要均会逐个检查计算),计算复杂度高O(n²)(二维数组遍历)
四叉树通过空间自适应分辨率和用空间复杂度换取时间复杂度获取更高的搜索效率,这两处加粗会在后文讲解。
先看一下在计算前需要做的准备工作。
1. 绘制四叉树
如果有看过图形学Games101的小伙伴,可以参考一下L14的Spatial Partitions空间划分

(感觉这个图错了,图是四叉树,但OctTree是八叉树的意思,四叉树是Quad Tree)
在A*中,也是类似的划分A*将点分为两大种,不可通过(障碍,已走过,越界);可通过。
上述图是什么意思呢?四叉树构建步骤详解
-
初始划分:将整个空间(如地图)划分为 4个大小相等的矩形区域(象限)。
-
递归评估与标记:对每个子区域检查其内部状态:
-
混合状态(部分可通过/不可通过)→ 继续细分为4个子象限,递归处理。
-
完全不可通过(如全为不可通过)→ 标记为“不可通过”节点,停止细分。
-
完全可通过(如全为可通过)→ 标记为“可通过”节点,停止细分。
-
-
终止条件:满足以下任一条件时停止细分:
-
达到最大递归深度(防止无限细分)。
-
达到预设的 最小细分精度(如单像素/网格单元级别)。
-
节点已为“完全可通过”或“完全不可通过”。
-
-
生成树结构:
-
最终形成一棵树,其中:
-
叶节点:标记为可通过或不可通过。
-
非叶节点:表示仍需进一步细分的混合区域。
-
-
2.计算邻接关系
此时虽然降低了时间复杂度,但不难发现找到8邻域似乎并不方便了,我们可以根据树结构的性质以及叶子结点的边界重叠实现邻接节点的获取
- 以叶子节点的边界范围为判断依据,从根节点开始递归遍历四叉树
- 遇到和邻接范围完全无交集的节点就直接剪枝
- 直到查到叶子节点时,再通过边界关系筛选出相关叶子节点
- 最后判断该点可不可取(可行/不可行)进而找到邻接点
3. A*寻路
1. 确定起始点和终点所在的四叉树叶节点
-
起始点:从四叉树的根节点开始,递归检查其所在的象限,直到找到包含该点的 最小叶节点(即不再细分的节点)。
-
终点:同理,递归查找终点所在的叶节点。
2.寻路
-
起始点加入关闭列表,修改标签,开启列表加入八邻域并计算消耗
-
选取消耗最小的点修改标签,加入关闭列表,并再次选取八邻域,递归
-
直至开启列表为空(死路)或到达目标点结束寻路计算
3. 美化一切
发挥各位创造者的智慧制作出完美的敌人寻路吧!!!
(纯文本无代码)&spm=1001.2101.3001.5002&articleId=149339675&d=1&t=3&u=1ba9ecca9ace444cb729155974e6c392)
760

被折叠的 条评论
为什么被折叠?



