最近想要研究研究webgl地形的渲染,而後就想起了四叉樹,在網上看了一篇相關的文章,準備拿javascript實現一下備用。
四叉樹原理
(這部分就直接抄了,見參考)四叉樹(Q-Tree)是一種樹形數據結構。四叉樹的定義是:它的每一個節點下至多能夠有四個子節點,一般把一部分二維空間細分爲四個象限或區域並把該區域裏的相關信息存入到四叉樹節點中。這個區域能夠是正方形、矩形或是任意形狀。如下爲四叉樹的二維空間結構(左)和存儲結構(右)示意圖(注意節點顏色與網格邊框顏色):
四叉樹的每個節點表明一個矩形區域(如上圖黑色的根節點表明最外圍黑色邊框的矩形區域),每個矩形區域又可劃分爲四個小矩形區域,這四個小矩形區域做爲四個子節點所表明的矩形區域。javascript
數據結構java
var QuadRect = function(left,top,right,bottom){ this.left = left; this.top = top; this.right = right; this.bottom = bottom; }; var QuadNode = function(){ this.rect = null; //所表示的矩形區域 this.data = null; //相關數據 this.childs = null; //四個子節點,沒有就是null }; var QuadTree = function(){ this.root = new QuadNode(); //根節點 this.depth = 0; //數的深度 };
樹的構建node
var g_tree = new QuadTree(); /** * [quadTreeBuild 構建四叉樹] * @param {[number]} depth [輸的深度] * @param {[QuadRect]} rect [數表示的矩形區域] */ function quadTreeBuild(depth, rect){ g_tree.depth = depth; quadCreateBranch(g_tree.root, depth, rect); } /** * [quadCreateBranch 遞歸方式建立給定節點的子節點] * @param {[QuadNode]} node [須要建立子節點的節點] * @param {[type]} depth [description] * @param {[type]} rect [description] * @return {[type]} [description] */ function quadCreateBranch(node, depth, rect){ if (depth !== 1) { node.rect = rect; node.childs = [new QuadNode(),new QuadNode(),new QuadNode(),new QuadNode()]; childsRect = rectSubdivide(rect); quadCreateBranch(node.childs[0], depth - 1, childsRect[0]); quadCreateBranch(node.childs[1], depth - 1, childsRect[1]); quadCreateBranch(node.childs[2], depth - 1, childsRect[2]); quadCreateBranch(node.childs[3], depth - 1, childsRect[3]); } } /** * [rectSubdivide 給定一個矩形區域將它分爲四個象限] * @param {[type]} rect [description] * @return {[type]} [description] */ function rectSubdivide(rect){ var firstRect = new QuadRect( (rect.left + rect.right)/2, rect.top, rect.right, (rect.top+rect.bottom)/2 ); var secondRect = new QuadRect( rect.left, rect.top, (rect.left + rect.right)/2, (rect.top+rect.bottom)/2 ); var thirdRect = new QuadRect( rect.left, (rect.top+rect.bottom)/2, (rect.left + rect.right)/2, rect.bottom ); var fourthRect = new QuadRect( (rect.left + rect.right)/2, (rect.top+rect.bottom)/2, rect.right, rect.bottom ); return [firstRect,secondRect,thirdRect,fourthRect]; } var rect = new QuadRect(0,10,10,0); var depth = 5; quadTreeBuild(depth,rect); console.log('ok.');
用四叉樹查找某一對象
未完待續......web
參考
- 四叉樹與八叉樹segmentfault