前面讲了很多具体的搜索方法,如
也有说了最为基础的空间分割算法
今天就来讲一下一种经典的空间分割方法(也随之带来一种数据结构),其实这种方法很简单,我们在1维的逻辑中有一种经典方法叫做二分(遇事不决便二分),那么在2D平面上就是今天要说的四叉树,而在3D空间中就是八叉树,可以理解为 树, 为空间的维度。
二分法顾名思义,就是一种逐渐缩小范围的方法,每次将搜索范围除2,比如一个人让你猜他多大岁数,你大概看出来他在25-35之间,你就先猜一下30,他说大了,你再猜一下28,......, 这样几波下来你很快就知道他多大了。
四叉树就跟这个逻辑非常一致,之前已经讲过一个接触面和另一个接触面相交,可以先确定出来一个大的相交的AABB 的 boundingbox,然后在2D中就一个这样的盒子一划四,这么划分出去,直达某个终止条件,具体可以看如下的示意图
一样的思想可以拓展到八叉树上,如下图所示 ,唯一的区别就是从平面到空间,从叉除四个节点到叉出八个节点
大家在很多论文和书上会听到有人说“树结构”画上面类似的图,初看其实可能不明觉厉,其实nothing fancy。
这个思想非常简单,那么他有啥好处呢,好处就在于可以更快速的定位,回想刚刚猜岁数的例子,猜的人也可以从25一路猜到35,而用二分的好处就是在于整个过程的时间复杂度是 , 而一个个查的复杂度是 , 这两者在数据量越大的时候效率差距会越明显。
现在想象我们在2D中用最为天真的构造方法,将接触面的主面 个单元面放到一个四叉树结构中,然后我们有 个从节点(点对面接触搜索逻辑)需要进行接触索,那么时间复杂度是啥样的呢
这里每一个从节点需要进行一次主面的定位,而定位主面的复杂度是 。当然还有一些优化方法可以进一步提升,但不是今天要讨论的,后续可作为番外篇。
今天就简单说了一下四叉树和八叉树,其实对于空间分割和接触检测的树状结构还有很多,也有自己不同的适用场景,比如k-d tree, BSP (二元空间分割) tree, BVH (bouding volume hierarchy) tree。总的来说今天讲的是最简单的(当然不如直接画格子的空间箱排序简单),但也有诸多细节尤其是在FEM接触检测中,下次我来详细说说,然后再展开到其他树结构。
最后我突然又想到一个好玩的事,如果各位朋友喜欢这一系列,全都看下来说不定会有意外的惊喜,比如爱打游戏的朋友,所谓的光追(Ray Tracing)底层呢也都事用的ray casting和这些空间分割树状结构啥的,然后游戏中对于接触检测不同与有限元一般称为碰撞检测(collision detection)。