C#几何算法:空间索引——Quadtree四叉树及应用(一)

目录

前言

什么是四叉树?

四叉树的原理

结语


前言

        最近在CAD中开发拓扑检查和空间分析功能时发现,传统的双层递归法会极大的降低程序运行速度,就比如:图上有1000个图形,我们要求图形之间的交点,传统的作法就是遍历两次图形,在两次循环中分别对图形求交处理,对于图形较少的情况,传统的双层递归法也不会太多的影响程序的效率,但是如果图上有10000个图形,或者更多图形呢?按照传统的双层递归法来运算显然是不太可能的,可能会直接导致CAD无响应,大幅度影响计算效率。为了解决这个问题,针对大量图形进行空间运算的时候就必须用到空间索引了。

        我们用过GIS软件的小伙伴就能感受到GIS的空间分析功能远比CAD强大,最直观的就是GIS软件的运算速度,很多小伙伴就很好奇为什么它会这么快,正是因为所有的GIS软件都使用了空间索引,常见的空间索引有很多,比较成熟的有:Rtree、Kdtree、Quadtree等,我们今天要讲的就是Quadtree,中文名称叫:四叉树。

什么是四叉树?

        本文中使用的编程语言为C#,C#为面向对象语言,我们开始写代码之前一定得搞懂对象的定义,我们要写四叉树,首先得明白四叉树是什么,首先我们来看看四叉树的理论模型图(图片源自知乎):

        是不是看不太懂?没关系,笔者最开始也是看不懂这套模型图,相对于网上晦涩难懂的解释,对于大多数新手朋友来说都是不太友好的,笔者在此将会以自己的理解跟大家进行一个解读。

四叉树的原理

        首四叉树的原理就是将图形区域的最大矩形范围(根节点)不断向下四等分,矩形每划分一次就形成四个新的矩形范围(子节点),直到满足设定条件为止就停止划分,最终形成成无数个矩形区域,如下图:

        第一步,首先确定出目标区域的最大矩形范围(根节点):

         第二步,由最大矩形区域不断向下四等分,形成每一层的子节点

        笔者在这里一共划分了三次,每次划分都形成了一层子节点(多个矩形区域),那么这个矩形区域划分出来到底有什么作用呢?

        矩形区域的作用就是将庞大的空间范围进行划分,四叉树检索图形其实就是检索矩形区域对应的图形,什么意思呢?如下图所示:

        从实例出发,如上图所示,图中一共有四个矩形,六个图形,那么矩形和图形是什么关系呢?

        首先我们要判断每个图形的外包矩形(上图中的青色部分)和四个矩形区域的相交关系以确定每个区域所包含的图形,上图的相交与包含关系图下:

相交关系:

  •         图形1的外包矩形与矩形一相交,所以矩形一包含图形1
  •         图形2的外包矩形与矩形一相交,所以矩形一包含图形2
  •         图形3的外包矩形与矩形一相交,所以矩形一包含图形3
  •         图形4的外包矩形与矩形一、矩形二、矩形三、矩形四相交,所以矩形一、矩形二、矩形三、矩形四同时包含图形4
  •         图形5的外包矩形与矩形四相交,所以矩形五包含图形5
  •         图形6的外包矩形与矩形三相交,所以矩形三包含图形6

    包含关系:

    •         矩形一包含:图形1、图形2、图形3、图形4
    •         矩形二包含:图形4
    •         矩形三包含:图形4、图形6
    •         矩形四包含:图形4、图形5

              确定好相交与包含关系之后,我们就可以进行范围搜索了,还是以上图为例,我们以图形1的外包矩形进行搜索:

              首先判断图形1与四个矩形区域的相交关系,得出图形1仅与矩形一相交 ,然后根据上一步的包含关系即可以拿到图形1所在区域所包含的所有图形:图形1、图形2、图形3、图形4,通过这样的方式进行检索,我们的图形运算就可以按照区域进行,无需再全图双层递归对比了。

              四叉树的工作原理就是将指定的图形范围进行划分,每次划分判断图形外包矩形与子节点的关系,从而形成一个位置关系树结构,后期直接通过给定的矩形范围逐节点进行判断指定的矩形范围属于哪个矩形分区,最后拿出对应矩形分区所对应的图形即可。

      结语

              本章内容咱们先理解四叉树的原理,下一章我们再详细的教学如何用C#代码去编写一个四叉树并进行应用。如对本章内容有任何疑问可扫描下方二维码,联系作者微信。