2018-09-01
在游戏或者CAD程序中,我们经常面对的一个需求:已知空间(多数是二维、三维,也有少数高维空间)内的一个物体,求解距离它最近的k个物体是哪些。当然,这个问题可能很简单,假设空间内只有几百几千、甚至几万个个物体,我们只需要遍历一下即可。也花费不了几毫秒时间。但是,当空间内的物体有几百万、几千万个的时候呢,或者几亿几十亿呢?你个简单的查找就耗费几十分钟、几个小时,这绝不能忍受。所以,我们需要加速的优化手段。
一个朴素的方法就是,先求解所有物体所占的空间的BoundingBox,名为bb,以后所有的操作只考虑这个bb空间,不会超过这个范围。把空间平均分割一下,如一维空间分成两份,二维空间就平均分成四份,三维空间就平均分成八份,n维空间就平均分成n^2份,切割完成后,把整体当作父节点,把小的一份当作子节点,那这就是二进制空间分割树,以上分别对应着二叉树、四叉树、八叉树。当把空间平分了之后,我们就可以向周围的子空间询问:是否有包含物体;包含了几个物体?假设物体在空间内均匀分布,那么就意味着只需要向邻居子空间询问即可完成搜索工作。
但是,假如物体在空间中的分布不均匀呢?假想操场上只有一棵树,对这棵树建立包围盒bb,我们包围盒空间进行八叉树划分,递归的多进行m次,且假设m比较大,比如10。若地面上一无所有,一片叶子掉下来落在地面上,问:距离这片叶子最近的其他一片叶子在哪里?那得问多少次才能问到目标。八叉树的构建非常简单。但是,如果我们只偏重于查询,这样子就很浪费了。一个简单的优化