`
xhload3d
  • 浏览: 205750 次
社区版块
存档分类
最新评论

HT for Web可视化QuadTree四叉树碰撞检测

阅读更多

QuadTree四叉树顾名思义就是树状的数据结构,其每个节点有四个孩子节点,可将二维平面递归分割子区域。QuadTree常用于空间数据库索引,3D的椎体可见区域裁剪,甚至图片分析处理,我们今天介绍的是QuadTree最常被游戏领域使用到的碰撞检测。采用QuadTree算法将大大减少需要测试碰撞的次数,从而提高游戏刷新性能,本文例子基于HT for Web的图形引擎,通过GraphViewGraph3dView共享同一数据模型DataModel,同时呈现QuadTree算法下的2D和3D碰撞视图效果:http://v.youku.com/v_show/id_XODQyNTA1NjY0.html

Screen Shot 2014-12-06 at 12.41.24 AM

QuadTree的实现有很多成熟的版本,我选择的是 https://github.com/timohausmann/quadtree-js/ 四叉树的算法很简单,因此这个开源库也就两百来行代码。使用也非常简单,构建一个Quadtree对象,第一个参数传入rect信息制定游戏空间范围,在每次requestAnimationFrame刷新帧时,先通过quadtree.clear()清除老数据,通过quadtree.insert(rect)插入新的节点矩形区域,这样quadtree就初始化好了,剩下就是根据需要调用quadtree.retrieve(rect)获取指定矩形区域下,与其可能相交需要检测的矩形对象数组。

我构建了HTGraphViewGraph3dView两个组件,通过ht.widget.SplitView左右分割,由于两个视图都共享同一DataModel,因此我们剩下的关注点仅是对DataModel的数据操作,构建了200个ht.Node对象,每个对象的attr属性上保存了随机的运动方向vx和vy,同时保存了将要反复插入quadtree的矩形对象,这样避免每帧更新时反复创建对象,同时矩形对象也引用了ht.Node对象,用来当通过quadtree.retrieve(rect)获取需要检测的矩形对象时,我们能指定其所关联的ht.Node对象,因为我们需要对最终检测为碰撞的图元设置上红颜色的效果,也就是ht.Node平时显示默认的蓝色,当互相碰撞时将改变为红色。

需要注意从quadtree.retrieve(rect)获取需要检测的矩形对象数组中会包含自身图元,同时这些仅仅是可能会碰撞的图元,并不意味着已经碰撞了,由于我们例子是矩形,因此采用ht.Default.intersectsRect(r1, r2)最终判断是否相交,如果你的例子是圆形则可以采用计算两个圆心距离是否小于两个半径来决定是否相交,因此最终判断的标准根据游戏类型会有差异。

采用了QuadTree还是极大了提高了运算性能,否则100个图元就需要100*100次的监测,我这个例子场景下一般也就100*(10~30)的量:

Screen Shot 2014-12-06 at 12.42.35 AM

除了碰撞检测外QuadTree算法还有很多有趣的应用领域,有兴趣可以玩玩这个 https://github.com/fogleman/Quads

Screen Shot 2014-12-06 at 12.52.17 AM

所有代码如下供参考:

function init(){  
	d = 200;
	speed = 8;
	dataModel = new ht.DataModel();                                
	g3d = new ht.graph3d.Graph3dView(dataModel);                                                  
	g2d = new ht.graph.GraphView(dataModel);                   
	mainSplit = new ht.widget.SplitView(g3d, g2d);                   
	mainSplit.addToDOM();                                        
	g2d.translate(300, 220);      
	g2d.setZoom(0.8, true);
	  
	for(var i=0; i<100; i++) {
		var node = new ht.Node();
		node.s3(randMinMax(5, 30), 10, randMinMax(5, 30));
		node.p3(randMinMax(-d/2, d/2), 0, randMinMax(-d/2, d/2));
		node.s({
			'batch': 'group',
			'shape': 'rect',
			'shape.border.width': 1,
			'shape.border.color': 'white',
			'wf.visible': true,
			'wf.color': 'white'
		});
		node.a({
			vx: randMinMax(-speed, speed),
			vy: randMinMax(-speed, speed),
			obj: {
				width: node.getWidth(),
				height: node.getHeight(),
				data: node
			}
		});                    
		dataModel.add(node);
	}                
	createShape([
		{x: -d, y: d},
		{x: d, y: d},
		{x: d, y: -d},
		{x: -d, y: -d},
		{x: -d, y: d}
	]);                   
	quadtree = new Quadtree({ x: -d, y: -d, width: d, height: d });                                
	requestAnimationFrame(update);
}               
function update() {   
	quadtree.clear();                
	dataModel.each(function(data){
		if(!(data instanceof ht.Shape)){
			var position = data.getPosition();
			var vx = data.a('vx');
			var vy = data.a('vy');
			var w = data.getWidth()/2;
			var h = data.getHeight()/2;
			var x = position.x + vx;
			var y = position.y + vy;
			if(x - w < -d){
				data.a('vx', -vx);
				x = -d + w;
			}
			if(x + w > d){
				data.a('vx', -vx);
				x = d - w;
			}
			if(y - h < -d){
				data.a('vy', -vy);
				y = -d + h;
			}
			if(y + h > d){
				data.a('vy', -vy);
				y = d - h;
			}
			data.setPosition(x, y);                        
			var obj = data.a('obj');
			obj.x = x - w;
			obj.y = y - h;
			
			quadtree.insert(obj);
			setColor(data, undefined);
		}
	});                
	dataModel.each(function(data){
		if(!(data instanceof ht.Shape)){ 
			var obj = data.a('obj');
			var objs = quadtree.retrieve(obj);
			if(objs.length > 1){                            
				for(var i=0; i<objs.length; i++ ) {
					var data2 = objs[i].data;
					if(data === data2){
						continue;
					}
					if(ht.Default.intersectsRect(obj, data2.a('obj'))){
						setColor(data, 'red');
						setColor(data2, 'red');
					}                                
				}                             
			}
		}
	});
	requestAnimationFrame(update);                    
}                        
function randMinMax(min, max) {
	return min + (Math.random() * (max - min));
}                      
function createShape(points){
	shape = new ht.Shape();
	shape.setPoints(points);
	shape.setThickness(4);
	shape.setTall(10);                                
	shape.s({
		'all.color': 'red',
		'shape.background': null,
		'shape.border.width': 2,
		'shape.border.color': 'red'                    
	});                
	dataModel.add(shape); 
	return shape;
}
function setColor(data, color){
	data.s({
		'all.color': color,
		'shape.background': color
	});
}

 

2
0
分享到:
评论

相关推荐

    QuadTree四叉树实现代码 C#

    总之,这个C#实现的四叉树代码提供了创建、维护和使用四叉树结构的功能,特别适合处理2D空间中的碰撞检测问题。通过理解和应用这些文件,开发者可以掌握四叉树的基本原理,并将其应用于实际的项目中,优化性能,提升...

    creator 四叉树 Quadtree.ts 用于优化碰撞检测

    creator 四叉树 Quadtree.ts 用于优化碰撞检测

    四叉树quadtree的c++实现

    四叉树(Quadtree)是一种数据结构,特别适用于在二维空间中组织和处理点对象。在计算机图形学、地理信息系统和图像处理等领域中,四叉树被广泛应用。它类似于二叉树,但每个节点有四个子节点,分别代表上、下、左、...

    4叉树做的碰撞检测demo

    4. 可能还包含了可视化四叉树结构和碰撞结果的辅助代码,以便于调试和理解。 总的来说,这个四叉树碰撞检测的demo提供了一种在AS3中优化大规模物体碰撞检测的解决方案。通过四叉树的划分和查询,可以显著减少计算量...

    quadtree:使用四叉树进行粒子碰撞检测

    使用四叉树进行粒子碰撞检测。 四叉树是一种树数据结构,其中每个内部节点恰好具有四个子节点。 四叉树是八叉树的二维模拟,最常用于通过将二维空间递归细分为四个象限或区域来划分二维空间。 演示版 在GitHub页面...

    qur_tree.rar_quadtree image_四叉树 点_四叉树分割_四叉树图像_图像 四叉树

    在标题“qur_tree.rar_quadtree image_四叉树 点_四叉树分割_四叉树图像_图像 四叉树”中,关键词“四叉树 点”和“四叉树分割”暗示了这个压缩包可能包含一个用于四叉树分割图像中特定点的工具或算法。四叉树分割...

    matlab-prog.rar_canny _matlab四叉树_quadtree_四叉树_四叉树分解

    其次,四叉树(Quadtree)是一种数据结构,常用于图像分割和压缩。在图像处理中,四叉树将图像空间划分为大小相等的四边形区域,并根据区域内的像素相似性进行分解。当一个区域内像素颜色相近时,该区域可以被进一步...

    基于限制四叉树的大规模地形可视化及其实现.pdf

    《基于限制四叉树的大规模地形可视化及其实现》这篇文献深入探讨了在处理大规模地形数据时,如何利用限制四叉树实现高效、流畅的可视化技术。本文将详细阐述限制四叉树的基本概念,以及其在地形可视化中的应用,同时...

    四叉树unity 用于碰撞检测

    四叉树(Quadtree)是一种数据结构,常用于在二维空间中组织和管理对象,尤其在游戏开发中,它在碰撞检测、图形渲染优化等方面有着广泛的应用。Unity是一款流行的3D游戏引擎,它允许开发者利用各种算法来提高游戏...

    四叉树Demo

    6. **图形化表示**:在Unity中,可以通过可视化方式展示四叉树的结构,这有助于理解和调试。可能使用Unity的`OnDrawGizmos()`函数来绘制四叉树的边界和子区域。 7. **性能分析**:通过四叉树,开发者可以更好地理解...

    四叉树实现碰撞检测、坐标点查找与比对,如果是坐标组,那么需要另外定义插入的规则,该Demo代码示例针对的是单个坐标点。

    四叉树(Quadtree)是一种数据结构,特别适用于在二维空间中组织和管理对象,尤其在处理图形和图像处理领域,如碰撞检测、坐标查找和比对等方面具有显著优势。四叉树是二叉树的扩展,每个节点都有四个子节点,分别...

    一个四叉树的实现代码

    四叉树可以用于实现快速碰撞检测、范围查询、最近邻搜索等功能。 四叉树的优点 四叉树的实现代码具有以下优点: * 高效的存储和检索能力 * 高效的碰撞检测和范围查询能力 * 良好的可扩展性和灵活性 四叉树的缺点...

    QuadTree(VC#2005)

    5. **遍历与绘图**:四叉树的可视化是通过GDl+实现的。GDl+是.NET Framework的一部分,提供了丰富的图形绘制功能。遍历四叉树并根据节点的边界框绘制矩形,可以清晰地展示四叉树的结构。 在实际应用中,四叉树常...

    四叉树 C# 源码

    在实际应用中,四叉树可以用来优化碰撞检测,比如在游戏场景中,快速找出与某一物体可能发生碰撞的对象。还可以用于地图渲染,通过分层存储地理信息,只加载可视范围内的数据,提高渲染效率。在图像处理中,四叉树...

    四叉树代码

    四叉树(Quadtree)是一种数据结构,它与二叉树类似,但每个节点有四个子节点,分别代表上、下、左、右四个方向。这种数据结构在计算机科学中常用于图像处理、地理信息系统、游戏编程等领域,因为它能够有效地对二维...

    四叉树分割的示意图(matlab)

    四叉树分割是一种在图像处理...总的来说,四叉树分割在MATLAB中的实现涉及图像读取、四叉树结构的构建、节点分割策略以及结果的可视化。通过理解这些概念和步骤,你可以自行编写或修改代码,以适应不同的图像处理需求。

    四叉树实现

    此外,四叉树还常用于碰撞检测、图像压缩、地理信息系统等,能够快速定位和组织空间内的元素。 总结来说,四叉树是一种分治策略的数据结构,适用于二维空间的索引和查找任务。它通过不断地将空间划分为四个部分,...

    quadtree-python:Python3中的四叉树实现

    6. **可视化(Visualization)**:为了更好地理解和调试四叉树,可以提供可视化工具来显示树的结构。 在`quadtree-python-main`这个项目中,可能包含了实现这些功能的代码。项目可能还提供了测试用例来验证四叉树的...

    四叉树算法的C#实现

    - 初始化:创建一个空的四叉树,设置根节点的位置和大小。 - 插入:将一个点或矩形对象插入到四叉树中。这通常涉及判断对象所在区域,并递归地在相应子节点中插入。 - 查询:根据给定的点或矩形,查找与之相交的...

    Quadtree:Java中的四叉树实现

    四叉树这是Quadtree的Java实现,Quadtree是一种树数据结构,可用于存储2D位置数据。用法创建新的四叉树从点(0,0)开始以400 x 400尺寸初始化世界// init.Dimension dimension = new Dimension ( 400 , 400 ); ...

Global site tag (gtag.js) - Google Analytics