八叉树 ( 1 )
| 1、對Octree的描述 Octree的定義是:若不為空樹的話,樹中任一節(jié)點的子節(jié)點恰好只會有八個,或零個,也就是子節(jié)點不會有0與8以外的數(shù)目。那么,這要用來做什么?想象一個立方體,我們最少可以切成多少個相同等分的小立方體?答案就是8個。再想象我們有一個房間,房間里某個角落藏著一枚金幣,我們想很快的把金幣找出來,聰明的你會怎么做?我們可以把房間當成一個立方體,先切成八個小立方體,然后排除掉沒有放任何東西的小立方體,再把有可能藏金幣的小立方體繼續(xù)切八等份….如此下去,平均在Log8(房間內(nèi)的所有物品數(shù))的時間內(nèi)就可找到金幣。因此,Octree就是用在3D空間中的場景管理,可以很快地知道物體在3D場景中的位置,或偵測與其它物體是否有碰撞以及是否在可視范圍內(nèi)。 2、實現(xiàn)Octree的原理 (1). 設定最大遞歸深度 (2). 找出場景的最大尺寸,并以此尺寸建立第一個立方體 (3). 依序?qū)挝辉貋G入能被包含且沒有子節(jié)點的立方體 (4). 若沒有達到最大遞歸深度,就進行細分八等份,再將該立方體所裝的單位元元素全部分擔給八個子立方體 (5). 若發(fā)現(xiàn)子立方體所分配到的單位元元素數(shù)量不為零且跟父立方體是一樣的,則該子立方體停止細分,因為跟據(jù)空間分割理論,細分的空間所得到的分配必定較少,若是一樣數(shù)目,則再怎么切數(shù)目還是一樣,會造成無窮切割的情形。 (6). 重復3,直到達到最大遞歸深度。 3、Octree的存貯結(jié)構(gòu)本例中Octree的存貯結(jié)構(gòu)用一個有(若干+八)個字段的記錄來表示樹中的每個結(jié)點。其中若干字段用來描述該結(jié)點的特性(本例中的特性為:節(jié)點的值和節(jié)點坐標),其余的八個字段用來作為存放指向其八個子結(jié)點的指針。此外,還有線性存儲和1托8式存儲。 4、BSP Tree和Octree對比 a) BSP Tree將場景分割為1個面,而Octree分割為3個面。 b) BSP Tree每個節(jié)點最多有2個子結(jié)點,而Octree最多有8個子結(jié)點 因此BSP Tree可以用在不論幾唯的場景中,而Octree則常用于三維場景 5、本例實現(xiàn)Octree的若干關(guān)鍵技術(shù)及截圖 A、主界面:
Main函數(shù)中使用while(true)產(chǎn)生類似Trinigy引擎中的渲染循環(huán)效果,等待用戶輸入操作。通過IF判斷用戶的輸入并進行相應的操作。
B、創(chuàng)建八叉樹界面,需要用戶輸入遞歸次數(shù)和外包盒在三維場景中的坐標 本例使用3層深度,外包盒坐標為(1,100,1,100,1,100)
樹的結(jié)構(gòu)圖:
C、創(chuàng)建成功后先序遍歷此八叉樹。
共產(chǎn)生了73個節(jié)點,由于比較多,沒有截出全部結(jié)果。
D、查看此樹的深度
即查找1號節(jié)點的個數(shù)。
E、查找點,需要用戶輸入坐標,本例使用坐標(80,80,80) 如果用戶輸入的點在場景外,則提示沒有找到。如(200,2,200) 根據(jù)用戶定義的最大遞歸深度和場景的坐標,計算一下該場景被分割后的最小6面體各邊的邊長,然后判斷用戶輸入的坐標是在當前節(jié)點的哪一個子結(jié)點中并循環(huán)搜索,直到達到葉子節(jié)點。(代碼較多,詳情請見下面的源代碼) 6、源代碼 八叉樹節(jié)點類的定義:
創(chuàng)建節(jié)點的函數(shù): / | ||||||||||||||||||||
總結(jié)
- 上一篇: 关于项目奖
- 下一篇: 亚马逊云科技官方培训课程介绍