关闭

四叉树与八叉树

1188人阅读 评论(0) 收藏 举报
分类:

转自:http://blog.csdn.net/zhanxinhang/article/details/6706217

http://www.mikechambers.com/blog/2011/03/21/javascript-quadtree-implementation/

前序

四叉树或四元树也被称为Q树(Q-Tree)。四叉树广泛应用于图像处理、空间数据索引、2D中的快速碰撞检测、存储稀疏数据等,而八叉树(Octree)主要应用于3D图形处理。对游戏编程,这会很有用。本文着重于对四叉树与八叉树的原理与结构的介绍,帮助您在脑海中建立四叉树与八叉树的基本思想。本文并不对这两种数据结构同时进行详解,而只对四叉树进行详解,因为八叉树的建立可由四叉树的建立推得。若有不足之处,望能不吝指出,以改进之。^_^  欢迎Email:zhanxinhang@gmail.com

四叉树与八叉树的结构与原理

四叉树(Q-Tree)是一种树形数据结构。四叉树的定义是:它的每个节点下至多可以有四个子节点,通常把一部分二维空间细分为四个象限或区域并把该区域里的相关信息存入到四叉树节点中。这个区域可以是正方形、矩形或是任意形状。以下为四叉树的二维空间结构(左)和存储结构(右)示意图(注意节点颜色与网格边框颜色):

 

四叉树的每一个节点代表一个矩形区域(如上图黑色的根节点代表最外围黑色边框的矩形区域),每一个矩形区域又可划分为四个小矩形区域,这四个小矩形区域作为四个子节点所代表的矩形区域。

较之四叉树,八叉树将场景从二维空间延伸到了三维空间。八叉树(Octree)的定义是:若不为空树的话,树中任一节点的子节点恰好只会有八个,或零个,也就是子节点不会有0与8以外的数目。那么,这要用来做什么?想象一个立方体,我们最少可以切成多少个相同等分的小立方体?答案就是8个如下八叉树的结构示意图所示:

 

 

四叉树存储结构的c语言描述:

[cpp] view plain copy
  1. /* 一个矩形区域的象限划分:: 
  2.            
  3.        UL(1)   |    UR(0) 
  4.      ----------|----------- 
  5.        LL(2)   |    LR(3) 
  6. 以下对该象限类型的枚举 
  7. */  
  8. typedef enum  
  9. {  
  10.     UR = 0,  
  11.     UL = 1,  
  12.     LL = 2,  
  13.     LR = 3  
  14. }QuadrantEnum;  
  15.   
  16. /* 矩形结构 */  
  17. typedef struct quadrect_t  
  18. {      
  19.     double  left,   
  20.             top,   
  21.             right,   
  22.             bottom;  
  23. }quadrect_t;  
  24.   
  25. /* 四叉树节点类型结构 */  
  26. typedef struct quadnode_t  
  27. {  
  28.     quadrect_t    rect;          //节点所代表的矩形区域  
  29.     list_t        *lst_object;   //节点数据, 节点类型一般为链表,可存储多个对象  
  30.     struct  quadnode_t  *sub[4]; //指向节点的四个孩子   
  31. }quadnode_t;  
  32.   
  33. /* 四叉树类型结构 */  
  34. typedef struct quadtree_t  
  35. {  
  36.     quadnode_t  *root;  
  37.     int         depth;           // 四叉树的深度                      
  38. }quadtree_t;  


四叉树的建立

1、利用四叉树分网格,如本文的第一张图<四层完全四叉树结构示意图>,根据左图的网格图形建立如右图所示的完全四叉树。

伪码:

Funtion QuadTreeBuild ( depth, rect )

   {

QuadTree->depth = depth;


/*创建分支,root树的根,depth深度,rect根节点代表的矩形区域*/

QuadCreateBranch (  root, depth, rect );

   }


Funtion QuadCreateBranch ( n, depth,rect )

   {

if ( depth!=0 )

   {

n = new node;    //开辟新节点

n ->rect = rect; //将该节点所代表的矩形区域存储到该节点中

将rect划成四份 rect[UR], rect[UL], rect[LL], rect[LR];


/*创建各孩子分支*/

QuadCreateBranch ( n->sub[UR], depth-1, rect [UR] );

QuadCreateBranch ( n->sub[UL], depth-1, rect [UL] );

QuadCreateBranch ( n->sub[LL], depth-1, rect [LL] );

QuadCreateBranch ( n->sub[LR], depth-1, rect [LR] );

   }

   }


2、假设在一个矩形区域里有N个对象,如下左图一个黑点代表一个对象,每个对象的坐标位置都是已知的,用四叉树的一个节点存储一个对象,构建成如下右图所示的四叉树。


方法也是采用递归的方法对该矩形进行划分分区块,分完后再往里分,直到每一个子矩形区域里只包含一个对象为止。

伪码:

Funtion QuadtreeBuild()

  {

     Quadtree = {empty};
     For (i = 1;i<n;i++)      //遍历所有对象

{

   QuadInsert(i, root);//将i对象插入四叉树

}          

         剔除多余的节点;       //执行完上面循环后,四叉树中可能有数据为空的叶子节点需要剔除
  }    


Funtion QuadInsert(i,n)      //该函数插入后四叉树中的每个节点所存储的对象数量不是1就是0

  {  

     if(节点n有孩子)

 {      

    通过划分区域判断i应该放置于n节点的哪一个孩子节点c;       

    QuadInsert(i,c);

 }

     else if(节点n存储了一个对象)

 {

    为n节点创建四个孩子;

    将n节点中的对象移到它应该放置的孩子节点中;

    通过划分区域判断i应该放置于n节点的哪一个孩子节点c;

    QuadInsert(i,c);

 }

     else if(n节点数据为空)    

 {

    将i存储到节点n中;

 }

  } 


(以上两种建立方法作为举一反三之用)


用四叉树查找某一对象

1、采用盲目搜索,与二叉树的递归遍历类似,可采用后序遍历或前序遍历或中序遍历对其进行搜索某一对象,时间复杂度为O(n)。

 

2、根据对象在区域里的位置来搜索,采用分而治之思想,时间复杂度只与四叉树的深度有关。比起盲目搜索,这种搜索在区域里的对象越多时效果越明显


伪码:

Funtion find ( n, pos, )

  {

      If (n节点所存的对象位置为 pos所指的位置 )

          Return n;

      If ( pos位于第一象限 )

          temp = find ( n->sub[UR], pos );

      else if ( pos位于第二象限)

          temp = find ( n->sub[UL], pos );

      else if ( pos位于第三象限 )

          temp = find ( n->sub[LL], pos );

      else  //pos 位于第四象限

          temp = find ( n->sub[LR], pos );

      return temp;   

  } 

结语:

熟话说:结构之法,算法之道。多一种数据结构就多一种解决问题的方法,多一种方法就多一种思维模式。祝君学习愉快!^_^

 ==============================================

声明:版权所有,转载请注明出处: http://blog.csdn.net/zhanxinhang/article/details/6706217

参考:维基百科、百度百科

参考:CS267: Lecture 24, Apr 11 1996 Fast Hierarchical Methods for the N-body Problem, Part 1


0
0
查看评论

八叉树 C++ 基础 源码

http://blog.csdn.net/pizi0475/article/details/6269060四叉树或四元树也被称为Q树(Q-Tree)。四叉树广泛应用于图像处理、空间数据索引、2D中的快速碰撞检测、存储稀疏数据等,而八叉树(Octree)主要应用于3D图形处理。实际的数据结构,就是一个...
  • yulinxx
  • yulinxx
  • 2017-06-20 23:28
  • 1194

八叉树Octree

八叉树 维基释义:八叉树(Octree)是一种用于描述三维空间的树状数据结构。八叉树的每个节点表示一个正方体的体积元素,每个节点有八个子节点,这八个子节点所表示的体积元素加在一起就等于父节点的体积。一般中心点作为节点的分叉中心。 百度百科释义:八叉树(Octree)的定义...
  • huapenguag
  • huapenguag
  • 2016-03-09 19:28
  • 1414

八叉树Octree

维基释义:八叉树(Octree)是一种用于描述三维空间的树状数据结构。八叉树的每个节点表示一个正方体的体积元素,每个节点有八个子节点,这八个子节点所表示的体积元素加在一起就等于父节点的体积。一般中心点作为节点的分叉中心。百度百科释义:八叉树(Octree)的定义是:若不为空树的话,树中任一节点的子节...
  • Augusdi
  • Augusdi
  • 2014-06-30 16:41
  • 12774

场景管理:八叉树算法C++实现

简单实现了场景管理八叉树算法 代码结构: object.h,object.cpp 被管理的对象类octree_node.h,octree_node.cpp 八叉树类main.cpp程序入口 object.h #pragma once /* //被管理的对象类 */ class...
  • u012234115
  • u012234115
  • 2015-07-30 21:06
  • 2939

八叉树三维数据结构

(一)基本原理     用八叉树来表示三维形体,并研究在这种表示下的各种操作及应用是在进入80年代后才比较全面地开展起来的。这种方法,既可以看成是四叉树方法在三维空间的推广,也可以认为是用三维体素阵列表示形体方法的一种改进。    ...
  • Chinamming
  • Chinamming
  • 2013-11-24 13:15
  • 3305

空间八叉树剖分

空间八叉树剖分转载自:http://hi.baidu.com/j_factory/blog/item/8bc1ca182d7f45f6af5133c3.html  空间八叉树算法是一个空间非均匀网格剖分算法,该算法将含有整个场景的空间立方体按三个方向分割成八个子立方体网格,组织成一棵八叉树...
  • Augusdi
  • Augusdi
  • 2014-06-30 16:49
  • 4651

八叉树及K-D树的应用和实现

1. 八叉树、k-d树的原理2. 八叉树、k-d树的应用、优缺点3. 八叉树、k-d树的实现八叉树和k-d树都经常用来处理三维空间数据,k-d树的使用范围更宽泛些,适用于k维空间的数据,在Sift算法中,k-d树被用于在k维的空间内搜索邻近特征点。1. 八叉树、k-d树的原理wiki或百科上面都有详...
  • Augusdi
  • Augusdi
  • 2014-06-30 20:46
  • 2253

基于八叉树的网格生成算法剖析

基于八叉树的网格生成算法剖析前言  对于网格生成这个主题,之前的网格生成系列的三篇博客文章分别介绍了MC算法,SMC算法以及Cuberille算法三种方法。同时还有一篇介绍网格生成与种子点生长算法高效结合的算法。本篇文章继续这一主题,介绍采用八叉树结构来进行网格生成的算法,这个算法并不是独立于之前介...
  • Kaitiren
  • Kaitiren
  • 2016-03-11 11:40
  • 2390

四叉树与八叉树

前序 四叉树或四元树也被称为Q树(Q-Tree)。四叉树广泛应用于图像处理、空间数据索引、2D中的快速碰撞检测、存储稀疏数据等,而八叉树(Octree)主要应用于3D图形处理。对游戏编程,这会很有用。本文着重于对四叉树与八叉树的原理与结构的介绍,帮助您在脑海中建立四叉树与八叉树
  • zhanxinhang
  • zhanxinhang
  • 2011-08-21 15:34
  • 38873

八叉树入门

八叉树入门出 处: 中国游戏开发者[ 2003-06-08 ]作 者:Jaap Suter  目 录  1 引言  2 八叉树的结构  3 创建八叉树  4 八叉树的用途  5 结论  原 文:Introduction ...
  • Augusdi
  • Augusdi
  • 2014-06-30 17:09
  • 2111
    个人资料
    • 访问:552839次
    • 积分:7230
    • 等级:
    • 排名:第3694名
    • 原创:75篇
    • 转载:538篇
    • 译文:1篇
    • 评论:91条
    最新评论