博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HT for Web可视化QuadTree四叉树碰撞检测
阅读量:6120 次
发布时间:2019-06-21

本文共 3940 字,大约阅读时间需要 13 分钟。

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

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

我构建了的和两个组件,通过左右分割,由于两个视图都共享同一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)的量:​

除了碰撞检测外QuadTree算法还有很多有趣的应用领域,有兴趣可以玩玩这个 

所有代码如下供参考:

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

 

转载于:https://www.cnblogs.com/xhload3d/p/4147749.html

你可能感兴趣的文章
Python异步IO --- 轻松管理10k+并发连接
查看>>
mysql-python模块编译问题解决
查看>>
Oracle中drop user和drop user cascade的区别
查看>>
【Linux】linux经常使用基本命令
查看>>
Java 内存区域和GC机制
查看>>
更新代码和工具,组织起来,提供所有博文(C++,2014.09)
查看>>
HTML模块化:使用HTML5 Boilerplate模板
查看>>
登记申请汇总
查看>>
Google最新截屏案例详解
查看>>
2015第31周一
查看>>
2015第31周日
查看>>
在使用EF开发时候,遇到 using 语句中使用的类型必须可隐式转换为“System.IDisposable“ 这个问题。...
查看>>
Oracle 如何提交手册Cluster Table事务
查看>>
BeagleBone Black第八课板:建立Eclipse编程环境
查看>>
在服务器上用Fiddler抓取HTTPS流量
查看>>
文件类似的推理 -- 超级本征值(super feature)
查看>>
【XCode7+iOS9】http网路连接请求、MKPinAnnotationView自定义图片和BitCode相关错误--备用...
查看>>
各大公司容器云的技术栈对比
查看>>
记一次eclipse无法启动的排查过程
查看>>
【转】jmeter 进行java request测试
查看>>