看到了一篇as3 实现的四叉树,http://bbs.9ria.com/thread-243675-1-1.html,自己用js实现了一遍。想做aoi的管理游戏里面的物体。
var qtree =(function(){function qtree(level,rectangle) {
var s = this;
s.level = level || 0;
s.objects = [];
s.bounds = rectangle;
s.nodes = [];
}
s.level描述这个节点是四叉树的第几层,s.objects包含这个节点对象,s.bounds描述这个节点的范围,方形,s.nodes包含这个节点的子节点。
var p ={
split:function(){
var s = this;
var subWidth = s.bounds[2] /2;
var subheight = s.bounds[3]/2;
var x = s.bounds[0];
var y = s.bounds[1];
var sublevel = s.level +1;
s.nodes.push(new qtree(sublevel,[x+subWidth,y,subWidth,subheight]));
s.nodes.push(new qtree(sublevel,[x,y,subWidth,subheight]));
s.nodes.push (new qtree(sublevel,[x,y+subheight,subWidth,subheight]));
s.nodes.push(new qtree(sublevel,[x+subWidth,y+subheight,subWidth,subheight]));
},
split这个函数会将这个节点划分成四部分,s.bounds是一个数组[0,0,100,100]这样格式,s.bounds[0]是x坐标,s.bounds[1]是y坐标,s.bounds[2]是宽,s.bounds[3]是高。后面就是把划分的矩形添加到4节点里。
getIndex:function(rect){
var s =this;
var index = -1;
var xMidpoint = s.bounds[0]+ s.bounds[2]/2;
var yMidpoint = s.bounds[1]+ s.bounds[3]/2;
var topquadrant = rect[1]< yMidpoint && rect[1]+rect[3]<yMidpoint;
var bottomquadrant = rect[1] > yMidpoint;
if(rect[0]<xMidpoint && rect[0] +rect[2] <xMidpoint){
if(topquadrant){
index = 1;
}else{
index = 2;
}
}else if (rect[0]>xMidpoint){
if(topquadrant){
index = 0;
}else{
index =3;
}
}
return index;
},
getIndex方法获得传入矩形所在的象限,rect也是s.bounds格式的数组。
insert:function(rect){
var s = this;
if(s.nodes[0]!=null){
var index = s.getIndex(rect);
if(index != -1){
s.nodes[index].insert(rect);
}
return;
}
s.objects.push(rect);
if(s.objects.length>10 && s.level<5){
s.split();
var i = 0;
while(i < s.objects.length){
index = s.getIndex(rect);
if(index != -1){
s.nodes[i].insert(s.objects.pop());
}else{
i++
}
}
}
}
};
插入方法,这是一个递归调用的过程,if(s.objects.length>10 && s.level<5)这是如果这个节点的子节点大于10个层数小于6,我们就在分下去。
for(var k in p){
qtree.prototype[k]=p[k];
}
return qtree;
})();
这个就不说了。
,,,未完待续,然后我们测试性能,优化一下。