四分木

前文

四分木又は第四ツリーツリーは、それはまた、Q(Q-木)として知られています。四分木広くまばらなデータを格納する、2D画像処理、空間データの索引付け、高速衝突検出に使用される、及びオクツリーは(オクツリー)は、主に、3Dグラフィックスに使用されます。ゲームのプログラミングは、それが有用であろう。この記事では、あなたが心の中で四分木や八分木の基本的な考え方を構築し、四分木や八分木ヘルプの原理と構造を導入に焦点を当てています。オクトツリーの確立は四分木プッシュを確立することができますので、この記事では、同時にこれら2つのデータ構造を説明していませんが、唯一の説明クワッド。不足した場合、希望は改善に指摘することを躊躇しないだろう。^ _ ^ようこそメールアドレス:[email protected]

構造と4分木や八分木の原則

四分木(Q-木)は、ツリーデータ構造です。四分木が定義されている各ノードの下の子ノードの最大4つのが存在してもよい、二次元空間の一部は、通常、4つの象限又は領域情報を四分木ノードに格納されている領域に細分されます。この領域は、正方形、長方形または任意の形状であってもよいです。以下は、二次元空間の四分木構造(左)とストレージ構造(右)の概略図である(ただし、グリッド・ノードの枠線の色の色)。

 

 

各四分木ノードは、矩形領域の各々は、4つの矩形領域として4つの小さい4つのより小さな矩形領域に分割することができ、(ルートノードは、最周辺黒黒境界矩形領域を表す以上)の矩形領域を表します。矩形領域の子ノードが示さ。

四分木を比較すると、オクトツリーシーンは、3次元空間に2次元から延びています。定義されたオクツリー(オクツリー)は:ツリーが空の場合、任意のノードの子ノードツリーは、ちょうど8、またはゼロ、つまり、子ノードの数が0~8以外ではありませんがあります。だから、あなたは何をすべきでしょうか?キューブを想像してみて、私たちは、少なくとも一定分量の同じ数が小さな立方体にカットすることができますか?答えは8です。図に示すオクツリー構造:

 

 

 

Cクワッド言語記述記憶構造:

矩形領域の/ *クアドラント分割::

UL(1)| UR(0)
---------- | -----------
LL(2)|(3)LR
列挙型の次の四分円
* /
typedefを列挙
{
UR = 0、
UL = 1、
LL = 2、
LR 3 =。
QuadrantEnum};

/ *長方形構造* /
typedefは構造体quadrect_t
{
ダブル左、
トップ、
右、
底。
quadrect_t};

/ *構造の四分木ノードタイプ* /
typedefは構造体quadnode_t
{
quadrect_tのRECT; //ノード矩形領域表さ
list_tを* lst_object; //データノード、ノードタイプは、一般的にリストにリンクされたオブジェクトを複数記憶することができる
構造体quadnode_tを*サブ[4]、四人の子供のノードへ//ポイント
} quadnode_t;

/ *四分木構造タイプ* /
typedefは構造体quadtree_t
{
*ルートquadnode_t;
int型の深さ; //深さ四分木
} quadtree_t。


四分木を確立

図1に示すように、メッシュパターンが残っている完全な四分木を確立するための右に示すように、最初の<4つの完全な四分木構造の概略>本明細書において、図をサブグリッド四分木を使用。

擬似コード:

目的球QuadTreeBuild(深さ、RECT)

   {

QuadTree->深さ=深さ;

 

/ * *枝、ツリーのルートのルート、RECTルートノードによって表される矩形領域の深度の深さを作成/

QuadCreateBranch(根、深さ、RECT)。

   }

 

目的球のQuadCreateBranch(N、深さ、RECT)

   {

(深さ!= 0)の場合

   {

N =新しいノード; //開いて新しいノード

N - > RECT = RECT; //ノードによって表される矩形領域はノードに格納されます。

4つの部分に分類RECTは、[UR]をRECT、[UL]をRECT、[LL]をRECT、[LR] RECT。

 

/ *子を作成し、各支店* /

QuadCreateBranch(N>サブ[UR]、深さ1、RECT [UR])。

QuadCreateBranch(N>サブ[UL]、深さ1、RECT [UL])。

QuadCreateBranch(N>サブ[LL]、深さ1、RECT [LL])。

QuadCreateBranch(N>サブ[LR]、深さ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

 


---------------------
作者:zhanxinhang
来源:CSDN
原文:https://blog.csdn.net/zhanxinhang/article/details/6706217
版权声明:本文为博主原创文章,转载请附上博文链接!

おすすめ

転載: www.cnblogs.com/vana/p/10948784.html