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

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)的量:http://v.youku.com/v_show/id_XODQyNTA1NjY0.html

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

所有代码如下供参考:

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
});
}

HT for Web可视化QuadTree四叉树碰撞检测的更多相关文章

  1. HTML5实现3D和2D可视化QuadTree四叉树碰撞检测

    QuadTree四叉树顾名思义就是树状的数据结构,其每个节点有四个孩子节点,可将二维平面递归分割子区域.QuadTree常用于空间数据库索引,3D的椎体可见区域裁剪,甚至图片分析处理,我们今天介绍的是 ...

  2. 透过HT for Web 3D看动画Easing函数本质

    http://www.hightopo.com/guide/guide/plugin/form/examples/example_easing.html 50年前的这个月诞生了BASIC这门计算机语言 ...

  3. HT for Web列表和3D拓扑组件的拖拽应用

    很多可视化编辑器都或多或少有一些拖拽功能,比如从一个List列表中拖拽一个节点到拓扑组件上进行建模,并且在拖拽的过程中鼠标位置下会附带一个被拖拽节点的缩略图,那么今天我们就来实现这样的拖拽效果. 首先 ...

  4. 基于HT for Web的3D呈现A* Search Algorithm

    最近搞个游戏遇到最短路径的常规游戏问题,正巧看到老同事写的3D机房最短路径巡线文章,一时起兴基于HT for Web写了个A*算法的WebGL 3D呈现,算法基于开源 https://github.c ...

  5. HT for Web框架使用心得

    一.简单介绍 在HT for Web的官网首页写着,构建先进2D和3D可视化所需要的一切. 是的,只要你看过官网,你就会知道,这是一个企业的.并非开源的且需要收费的框架. 因为公司的业务需要,且公司使 ...

  6. 初识HT for web

    目前国内经济转型在潜移默化中已经发生了巨大的变化,保险,零售业,汽车等我能想到的. 只要互联网能插足的行业,都难逃一‘劫’. 刚看了一篇博客--基于 HTML5 的工业组态高炉炼铁 3D 大屏可视化 ...

  7. 百度地图、ECharts整合HT for Web网络拓扑图应用

    前一篇谈及到了ECharts整合HT for Web的网络拓扑图应用,后来在ECharts的Demo中看到了有关空气质量的相关报表应用,就想将百度地图.ECharts和HT for Web三者结合起来 ...

  8. ECharts+BaiduMap+HT for Web网络拓扑图应用

    前一篇谈及到了ECharts整合HT for Web的网络拓扑图应用,后来在ECharts的Demo中看到了有关空气质量的相关报表应用,就想将百度地图.ECharts和HT for Web三者结合起来 ...

  9. 基于HT for Web 快速搭建3D机房设备面板

    以真实设备为模型,搭建出设备面板,并实时获取设备运行参数,显示在设备面板上,这相比于纯数值的设备监控系统显得更加生动直观.今天我们就在HT for Web的3D技术上完成设备面板的搭建. 我们今天模拟 ...

随机推荐

  1. ENode 2.0 - 介绍一下关于ENode中对Command的调度设计

    CQRS架构,C端的职责是处理从上层发送过来的command.对于单台机器来说,我们如何尽快的处理command呢?本文想通过不断提问和回答的方式,把我的思考写出来. 首先,我们最容易想到的是使用多线 ...

  2. objective-c(继承)

    objective-c的继承给出基础例子及注意点: 定义并实现基类ClassA #import <Foundation/Foundation.h> @interface ClassA : ...

  3. DeviceOne 竟然做出来如此复杂的App

    分享来自DeviceOne论坛 此文章分享自DeviceOne的论坛,论坛上的用户分享,下面有二维码扫描,可以进行安装和试用.支持android和ios两个 操作系统. 这个还没做完,目前已经完成了初 ...

  4. VS开发中的代码编写小技巧——避免重复代码编写的几种方法

    上一篇文章中程序员的幸福生活--有你的日子,每天都是情人节,收到了大家的很多好评.鼓励和祝福,非常感动,真诚的谢谢大家.也希望每个朋友都能保持一个积极向上的心态,去迎接丰富多彩的人生. 在开发过程中, ...

  5. Java提高篇(二七)-----TreeMap

    TreeMap的实现是红黑树算法的实现,所以要了解TreeMap就必须对红黑树有一定的了解,其实这篇博文的名字叫做:根据红黑树的算法来分析TreeMap的实现,但是为了与Java提高篇系列博文保持一致 ...

  6. 一天一小段js代码(no.1)

    10000个数字中缺少三个数,编程找出缺少的三个数字. 算法实现: /*生成10000个数中随机抽掉三个数后的数组*/ function supplyRandomArray(){ /*生成含有1000 ...

  7. 赴美工作常识(Part 5 - 绿卡优先级)

    这个系列的第一篇<赴美工作常识(Part 1 - 签证)>是三年前写的,过了这么久这个系列终于要继续下去了.接下来当然时讨论绿卡的事情了.跟讨论签证一样,这里必须要有免责声名.因为我不是移 ...

  8. java内功 ---- jvm虚拟机原理总结,侧重于虚拟机类加载执行系统

    参考书籍:<深入理解java虚拟机>,三天时间用了八个小时看完,像读一本武侠小说,挺爽. 另外需声明:图片都是从我自己的csdn博客转载,所以虽然有csdn标识,但都是我自己画的图片. j ...

  9. 每天一个linux命令(22):find 命令的参数详解

    find一些常用参数的一些常用实例和一些具体用法和注意事项. 1.使用name选项: 文件名选项是find命令最常用的选项,要么单独使用该选项,要么和其他选项一起使用.  可以使用某种文件名模式来匹配 ...

  10. python+selenium运行报错UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)

    使用python+selenium运行自动化脚本时,打印某一段文字出现UnicodeEncodeError: 'ascii' codec can't encode characters in posi ...