用四叉树管理散布在平面上的对象

周末一直在考虑怎样在游戏服务器中保存和管理那些有平面坐标的对象。希望能方便的查到每个对象附近的东西。以往用过的方法是给(平面)场景打上格子,然后再把每个对象放入相应的格子中。

这次又遇到这个问题,却不想用网格的方法来解决问题了。

原因主要是这么几点:一,用网格对于大场景特别消耗内存,而且不太适合做无限延展的场景。二,查询每个对象周围的东西时,不太方便。格子的粒度越小,速度越慢。

虽然这两个问题,都可以通过改进算法来回避。不过这次,我想尝试一下用四叉树解决这个问题。

用四叉树的话,内存占用量应该 O(n) 。如果定死了四叉树的扩展深度,可以推算出节点的最大可能消耗量。我想,如果只是为了解决 AOI 的计算,5 级深度已经足够。这样,大约预分配出 20 * n 个节点,几乎肯定够用了。

我希望场景是从坐标原点向四周无限延展开,没有什么具体的尺寸限制。所以,这次实现的时候对四叉树做了改造。第一级的划分是一个特例,它将平面分成四块,每一块都可以向某个方向无限延伸。

接下来,把各种可供切割的平面分为 9 类:

 2 6 17 5 93 8 4

我给这些类别编了号,5 号类型的平面有固定大小,可以被明确切割成四块,这四块依然是类型 5 。而类型 1 的块,被切割成四块后,四块的类型(按四个象限分布)分别是 1,6,5,9 。同理,类型 2,3,4 的平面,也会被切割成不同类型的四块。

类型 6,7,8,9 的平面由于他们只向一个方向延伸,所以只能被切割成 2 块,一块固定大小的正方型(类型 5),一块保留它原来的类型。

这样,我的数据结构不是一个完整的四叉树,有个支干上就只有两个分支了。如果一个对象被放到了离坐标原点过远的地方,树的深度可能很大(超过 5),但是宽度会减半。如果大多数对象都在原点附近的话,查找是很快的。

今天化了一通宵的时间来实现这个东西,写了四百多行 C 程序。因为要实际用到项目中去,效率上的考虑比较多,顾而时间用了近 8 个小时;而且篇幅也比我想象的长的多。

一般,我们会在四叉树的每个节点上保存父节点的指针。这样,遍历这棵树就不需要用递归实现。好久没有写纯算法的程序了,平时递归写惯了,今天为了实现个用回溯法遍历树的算法还颇费了点工夫。为了提高查找一个节点附近节点的效率,最后也做了特别的实现。

另外,因为树节点总数可以估算出来,我用了个预分配的大节点池,并内部实现了 gc 算法。这样,从四叉树上拿掉节点非常简单,分配新节点也很容易。事后想了一下,不用 gc 的话,用一个 freelist 来管理也慢不到哪去。

在四叉树的叶子上,存放一个对象链表即可。可以用一个备用链表,分配,释放,移动位置都不需要重新构造。估算了一下,对象在四叉树描述的场景中移动,处理过程应该是常数时间了。查询 AOI 区域的对象也是一个常数时间。总的来说,对今天的工作成果还是挺满意的 :)


隔日补充:

其实,通过动态增加层次来向边界延展的算法实现起来更简单,也没有增加太多储存和查询的负担。昨天晚上把问题想复杂了。睡一觉起来后,把程序改了。

用四叉树管理散布在平面上的对象相关推荐

  1. ACMNO.47 矩形面积交(有图) 平面上有两个矩形,它们的边平行于直角坐标系的X轴或Y轴。对于每个矩形,我们给出它的一对相对顶点的坐标,请你编程算出两个矩形的交的面积。

    题目描述 平面上有两个矩形,它们的边平行于直角坐标系的X轴或Y轴. 对于每个矩形,我们给出它的一对相对顶点的坐标,请你编程算出两个矩形的交的面积. 输入 输入仅包含两行,每行描述一个矩形. 在每行中, ...

  2. 前端图片上坐标连线_平面上三角形“四心”的解析建模

    写在前面:三角形四心在这里指三角形的重心.垂心.内心.外心.本文讲述如何在几何定义的基础上用向量和坐标给三角形四心建立模型,以方便探究其规律.主要讲xAP+yBP+zCP=0.AP=λAB+μAC和知 ...

  3. s平面上的圆对应的z平面上的图形

    简 介: 对于2021年期末信号与系统复习过程中学生提出の关于拉普拉斯变换定义域s平面与z变换的定义与z平面上的圆形对应关系进行实验讨论.显示了不同半径的s平面的上的圆形对应在z平面上的具有不同交叉点 ...

  4. 平面上给定n条线段,找出一个点,使这个点到这n条线段的距离和最小。

    题目:平面上给定n条线段,找出一个点,使这个点到这n条线段的距离和最小. 源码如下: 1 #include <iostream> 2 #include <string.h> 3 ...

  5. Problem A: 平面上的点——Point类 (I)

    Description 在数学上,平面直角坐标系上的点用X轴和Y轴上的两个坐标值唯一确定.现在我们封装一个"Point类"来实现平面上的点的操作. 根据"append.c ...

  6. 点在平面上的投影坐标例题_光测力学-栅线投影(面结构光)技术

    本文主要介绍了栅线投影方法的基本原理-三角测量与线性对应关系,以及栅线投影系统标定的细节.下一篇文章我们将介绍傅里叶与相移两种相位求解方法. 栅线投影可能在其他领域更多的被成为面结构光,其和DIC或者 ...

  7. 九度 题目1548:平面上的点

    题目描述: 给定平面上的n个点,任意做一条直线,求至多能有几个点恰好落在直线上. 输入: 包含多组测试数据,每组测试数据由一个整数n(0<=n<=100)开始,代表平面上点的个数. 接下去 ...

  8. 什么叫返回路径平面上的间隙_信号完整性:关于走线的参考平面问题探讨

    关于走线的参考平面问题探讨 很多人对于 PCB 走线的参考平面感到迷惑, 经常有人问: 对于内层走线, 如果走线一侧 是 VCC ,另一侧是 GND ,那么哪个是参考平面? 要弄清楚这个问题,必须对了 ...

  9. Java黑皮书课后题第3章:**3.27(几何:点是否在三角形内)假设一个平面上有一个直角三角形。编写程序,提示用户输入一个点的x坐标和y坐标,然后判断这个点是否在该三角形内

    **3.27(几何:点是否在三角形内)假设一个平面上有一个直角三角形.编写程序,提示用户输入一个点的x坐标和y坐标,然后判断这个点是否在该三角形内 题目 题目描述 破题 运行示例 代码 题目 题目描述 ...

  10. 平面上有两个圆相交,求两个圆相交部分的面积

    平面上有两个圆相交,求两个圆相交部分的面积 又学习了一遍算法,感触颇深,也对算法有了更进一步的认识,记录一下这次的学习,希望能帮到有需要的人. 输入:六个参数:第一个圆的圆心坐标,半径,第二个圆的圆心 ...

最新文章

  1. 关于上传文件的跨域问题
  2. linux中更新python_linux下面升级 Python版本并修改yum属性信息
  3. couldn't find libgnustl_shared.so
  4. 科大星云诗社动态20211108
  5. 关于拓扑排序的问题-P3116 [USACO15JAN]会议时间Meeting Time
  6. Centos下安装Gcc和Qt
  7. mysql 排名_MySQL和Hive中的排名问题
  8. Kbengine游戏引擎-【4】demo-kbengine_unity3d_demo 在容器docker上安装测试
  9. 解决eclipse环境下maven项目tomcat启动,未加载到项目的问题
  10. stat---文件状态信息结构体
  11. bzoj1135:[POI2009]Lyz
  12. 流量分类方法设计(一)——参考论文整理
  13. android 语音和输入法按钮切换,android 切换系统语言,输入法也随之切换
  14. 异常检测之孤立森林算法详细解释且配上代码运行实例
  15. 蓝桥杯 算法训练 关联矩阵Python实现
  16. caxa电子图板2022软件
  17. 征集难于处理的机械臂奇异点位
  18. 大学Java基础课程设计——网络聊天室
  19. Oracle 安装包合集!
  20. Android 屏幕方向以及UI界面状态的保存

热门文章

  1. 应用html的DIV+CSS制作牛顿摆
  2. python论坛签到_python简单实现网站打卡签到
  3. 计算机教程求和,excel筛选求和的方法步骤图
  4. python获取现在的日期和时间
  5. 局域网服务器ie浏览器文件传输慢,Win8.1系统下局域网打开IE网页很慢如何解决...
  6. 域名Whois信息查询接口
  7. 简易网页版进程管理器(支持手机管理电脑进程)
  8. mysql入门 博客园_FreeSql (一)入门 – FreeSql – 博客园
  9. GIF 字节格式介绍
  10. 数独解法 C++实现