1 基本介绍
在PR四叉树中,每个节点代表一个矩形区域,并且每个节点要么没有子节点,要么有四个子节点,分别代表该矩形区域的四个象限
2 数据结构
PR四叉树的每个节点通常包含以下几个元素:
- 区域(矩形):节点所代表的二维空间范围。
- 点:存储在该区域内的点(通常只允许存储一个点,但也有变种)。
- 四个子节点:分别代表左上、右上、左下、右下四个象限。
3 插入
- 从根节点开始。
- 判断要插入的点是否在当前节点的区域内。
- 如果在,查看当前节点是否已经存储了点。
- 如果没有,存储这个点。
- 如果有,把当前区域分割成四个象限,然后把当前点和新点分别放入相应的象限。
- 递归进行这个过程。
3.1.1 举例
假设我们有以下几个点:(1, 1), (2, 2), (3, 3),我们想要在一个 4x4 的区域内用 PR 四叉树来存储它们
- 初始状态:
- 插入(1,1)
- 直接存储在根节点
- 插入 (2, 2)
- 将根节点分割成四个 2x2 的区域。将 (1, 1) 放入左下区域,(2, 2) 放入右上区域
- 插入(3,3)
- 同样放在右上,但由于右上已经有点(2,2),所以再次分割
4 优点
- 四叉树的结构在空间数据对象分布比较均匀时,具有比较高的空间数据插入和查询效率(复杂度O(logN))
5 松散四叉树
- 四叉树的一个问题是,物体有可能在边界处来回,从而导致物体总是在切换节点,从而不得不更新四叉树
- 而松散四叉树正是解决这种边界问题的一种方式:首先它定义一个节点有入口边界(inner boundary),出口边界(outerboundary)
- 若物体还没添加进四叉树/八叉树,则检测现在位于哪个节点的入口边界内
- 若物体先前已经存在于某个节点,则先检测现在是否越出该节点的出口边界,若越出再检测位于哪个节点的入口边界内
- 在非松散的四叉树/八叉树中,入口边界和出口边界是一样的。
- 而松散四叉树/八叉树的松散,是指出口边界比入口边界要稍微宽些
- (各节点的出口边界也会发生部分重叠)
- ——>使节点不容易越过出口边界,减少了物体切换节点的次数
- 节点即使越过了入口边界,但由于他没有出出口边界,所以也不发生切换
- 另一个问题是,如何定义出口边界的长度
- 太短会退化成正常四叉树/八叉树,太长又可能会导致节点存储冗余的物体
- 实验表明出口边界长度为入口边界2倍时可以表现得很好
6 应用
6.1 场景管理
- 以游戏为例,如果游戏场景是基于地形的(甚至没有高度)(如城市、平原、2D场景),那么适合用四叉树来管理
- 如果游戏场景在高度轴上也有大量物体需要管理(如太空、高山),那么适合用八叉树来管理
假设我们想得到绿色点附近(假设小于最小格的长度)有那些红色目标,那么通过四叉树可以快速索引到绿点所在的K区域节点,只对该子节点包含的所有红色目标逐个进行距离检测,这样就可以避免给区域外的大量其它红色目标进行距离检测
参考内容:GIS空间数据库(21)PR四叉树索引 | 麻辣GIS (malagis.com)
空间数据结构(四叉树/八叉树/BVH树/BSP树/k-d树) - KillerAery - 博客园 (cnblogs.com)