OBB碰撞
OBB碰撞检测,坐标点逆时针
class OBBTest extends egret.DisplayObjectContainer {
private obb1:OBB;
private obb2:OBB;
private points1:Array<egret.Point>;
private points2:Array<egret.Point>;
private sprite1:egret.Sprite;
private sprite2:egret.Sprite;
private resPoint:egret.Point = new egret.Point();
constructor() {
super();
this.touchEnabled = true;
var stage = egret.MainContext.instance.stage;
stage.addEventListener(egret.TouchEvent.TOUCH_BEGIN, this.onTouchBegin, this);
stage.addEventListener(egret.TouchEvent.TOUCH_MOVE, this.onTouchMove, this);
stage.addEventListener(egret.TouchEvent.TOUCH_END, this.onTouchEnd, this);
this.points1 = [new egret.Point(0,0),new egret.Point(100,200),new egret.Point(300,300),new egret.Point(300,100),new egret.Point(0,0)];
this.sprite1 = this.drawSprite(this.points1);
this.addChild(this.sprite1);
this.sprite1.x = 100;
this.sprite1.y = 100;
this.points2 = [new egret.Point(0,0),new egret.Point(100,200),new egret.Point(300,300),new egret.Point(300,100),new egret.Point(0,0)];
this.sprite2 = this.drawSprite(this.points2);
this.addChild(this.sprite2);
this.sprite2.x = 100;
this.sprite2.y = 400;
//创建两obb盒子
this.obb1 = new OBB();
this.obb2 = new OBB();
egret.startTick(this.onEnterFrame, this);
}
private pt:egret.Point = new egret.Point(0,0);
private onEnterFrame():boolean {
for (var i = 0; i < this.points1.length; i++) {
var point1:egret.Point = this.points1[i];
this.sprite1.localToGlobal(point1.x, point1.y, this.pt);
this.obb1.setVertex(i, this.pt.x, this.pt.y);
}
for (var j = 0; j < this.points2.length; j++) {
var point2:egret.Point = this.points2[j];
this.sprite2.localToGlobal(point2.x, point2.y, this.pt);
this.obb2.setVertex(j, this.pt.x, this.pt.y);
}
this.sprite1.visible = !this.obb1.isCollidWithOBB(this.obb2);
return false;
}
private drawSprite(points:Array<egret.Point>):egret.Sprite {
var startPoint:egret.Point = points[0];
var sprite = new egret.Sprite();
sprite.graphics.clear();
sprite.graphics.beginFill( 0xffffff, 0.5 );
sprite.graphics.moveTo( startPoint.x, startPoint.y );
for (var i = 1; i < points.length ; i++) {
var point = points[i];
sprite.graphics.lineTo( point.x, point.y );
}
sprite.graphics.endFill();
return sprite;
}
private onTouchBegin(evt:egret.TouchEvent):void {
var posX = evt.stageX;
var posY = evt.stageY;
this.sprite2.x = posX;
this.sprite2.y = posY;
}
private onTouchMove(evt:egret.TouchEvent):void {
var posX = evt.stageX;
var posY = evt.stageY;
this.sprite2.x = posX;
this.sprite2.y = posY;
}
private onTouchEnd(evt:egret.TouchEvent):void {
var posX = evt.stageX;
var posY = evt.stageY;
this.sprite2.x = posX;
this.sprite2.y = posY;
}
}
/**
* 投影判断
*/
class Projection {
private min:number = 0;
private max:number = 0;
constructor(min, max) {
this.min = min;
this.max = max;
} public getMin(){
return this.min;
} public getMax(){
return this.max;
} /**
* 判断是否叠加
*/
public overlap(proj:Projection):boolean {
if(this.min > proj.getMax()) return false;
if(this.max < proj.getMin()) return false; return true;
}
};
class OBB {
private pList:Array<any> = [] //保存盒子顶点数
constructor() {
this.pList = [];
}
public getVertex(idx):egret.Point {
if (idx >= this.pList.length) {
return null;
}
return this.pList[idx];
};
public setVertex(idx:number, x:number, y:number):void {
if (!this.pList[idx]) {
this.pList[idx] = new egret.Point(0, 0);
}
this.pList[idx].x = x;
this.pList[idx].y = y;
}
/**
* 计算分离轴
* 如果边向量为(x,y),那么法向量为(-y,x),你也可以设置为(y,-x)。结果没有什么变化。
*/
public getAxies():Array<egret.Point> {
var axies = [];
var len = this.pList.length;
var pOut = new egret.Point(0,0);
for(var i = 0; i < len; i++) {
var startPoint:egret.Point = this.pList[i];
var endPoint:egret.Point = this.pList[(i + 1) % len];
var point = startPoint.subtract(endPoint);
var length = Math.sqrt(point.x * point.x + point.y * point.y);
pOut.x = point.x / length;
pOut.y = point.y / length;
axies[i] = new egret.Point();
axies[i].x = -pOut.y ;
axies[i].y = pOut.x ;
}
return axies;
}
/**
* 计算投影
* 计算出一个投影线条
* 只是保存了两个float形的数据,分别表示OBB盒在分离轴上投影的最小值和最大值
*/
public getProjection(axies:egret.Point):Projection {
var min = this.pList[0].x * axies.x + this.pList[0].y * axies.y;
var max = min ;
var len = this.pList.length;
for (var i = 1; i < len; i++) {
var temp = this.pList[i].x * axies.x + this.pList[i].y * axies.y;
if (temp > max) {
max = temp;
} else if (temp < min) {
min = temp;
}
}// end for
return new Projection(min, max);
}
//对传递进来的OBB判断是否与调用这个方法的OBB发生了交叉
public isCollidWithOBB(obb:OBB):boolean {
//获取分离轴
var axies1 = this.getAxies();
var axies2 = obb.getAxies();
var p1:Projection = null;
var p2:Projection = null;
//Check for overlap for all of the axies
for(var i = 0; i < axies1.length; i++)
{
p1 = this.getProjection(axies1[i]);
p2 = obb.getProjection(axies1[i]);
if(!p1.overlap(p2))
{
return false ;
}
}
for(var j = 0; j < axies2.length; j ++)
{
p1 = this.getProjection(axies2[j]);
p2 = obb.getProjection(axies2[j]);
if(!p1.overlap(p2))
{
return false ;
}
}
return true ;
}
}
测试,在Main中添加
var obb = new OBBTest();
this.addChild(obb);
OBB碰撞的更多相关文章
- Cocos2d-x教程(34)-三维物体OBB碰撞检測算法
欢迎增加Cocos2d-x 交流群:193411763 个中心点.1个旋转矩阵和3个1/2边长(注:一个旋转矩阵包括了三个旋转轴,若是二维的OBB包围盒则是一个中心点,两个旋转轴,两个1/2边长). ...
- 游戏中的2D OBB碰撞模型的碰撞算法介绍和实践
前言 上一篇博文说道,射线与场景中模型上的所有三角形求交时,会大幅度影响效率且花费比较多的时间,因此会采取使用包围盒的形式,进行一个加速求交.在此文中介绍OBB碰撞模型的碰撞算法 OBB的碰撞模型 有 ...
- 2D空间的OBB碰撞实现
OBB全称Oriented bounding box,方向包围盒算法.其表现效果和Unity的BoxCollider并无二致.由于3D空间的OBB需要多考虑一些情况 这里仅关注2D空间下的OBB. 实 ...
- 游戏碰撞OBB算法(java代码)
业务需求 游戏2D型号有圆形和矩形,推断说白了就是碰撞检测 : 1.圆形跟圆形是否有相交 2.圆形跟矩形是否相交 3.矩形和矩形是否相交 ...
- AABB包围盒、OBB包围盒、包围球的比較
1) AABB 包围盒: AABB 包围盒是与坐标轴对齐的包围盒, 简单性好, 紧密性较差(尤其对斜对角方向放置的瘦长形对象, 採用AABB, 将留下非常大的边角空隙, 导致大量不是必需的包围盒相交測 ...
- AABB边框、OBB边框、通过比较球包围
1) AABB 包围盒: AABB 包围盒是与坐标轴对齐的包围盒, 简单性好, 紧密性较差(尤其对斜对角方向放置的瘦长形对象, 採用AABB, 将留下非常大的边角空隙, 导致大量不是必需的包围盒相交測 ...
- 矩形旋转碰撞,OBB方向包围盒算法实现
怎样进行2D旋转矩形的碰撞检測.能够使用一种叫OBB的检測算法(Oriented bounding box)方向包围盒.这个算法是基于SAT(Separating Axis Theorem)分离轴定律 ...
- [算法][包围盒]球,AABB,OBB
参考地址请看图片水印:http://www.cnblogs.com/iamzhanglei/archive/2012/06/07/2539751.html http://blog.sina.com.c ...
- 3D有向包围盒与球体碰撞的算法
之前发的小游戏滚蛋躲方块中,用它来判断球体与立方体是否发生了碰撞. http://www.cnblogs.com/WhyEngine/p/3350012.html 现在发布下该算法: 有向包围盒OBB ...
随机推荐
- UVALive 4254 Processor ——(二分+优先队列处理)
题目是求最小化最大值,很显然是二分,但是二分以后怎么判断mid是否可行并不容易. 代码参考了网上一个博客的代码.巧妙之处在于一秒一秒的考虑,这样可以把处理速度mid直接转化成1秒内实际的量来解决(避免 ...
- CentOS7.4中配置jdk环境
参考:https://www.linuxidc.com/Linux/2016-09/135556.htm 1.下载jdk 首先创建安装包放置位置 mkdir -p /usr/local/java 然后 ...
- Express框架开发知识点总结
express --view=pug myapp 以上语句在当前工作目录中创建名为 myapp 的 Express 应用程序,采用的模板是jade. 以前还在纠结使用hbs模板引擎或者ejs模板,实际 ...
- MyEclipse环境的项目改为在Eclipse中运行爬坑记【我】
新检出一个web项目,同事都是运行在MyEclipse中的,我用Eclipse启动, 1.首先是许多jar包报错: 处理方法为 remove掉,然后 选 WEB-INF 下的所有 jar 重新添加 ...
- Java csv
CsvWriter csvWriter = new CsvWriter("data2019052803.csv", ',', Charset.forName("UTF-8 ...
- 2019最新 Java商城秒杀系统的设计与实战视频教程(SpringBoot版)_2-2微服务项目的搭建-SpringBoot搭建多模块项目二
一些重要的配置文件直接复制过来了 jdbc和shiro的配置 application.properties里面的相关配置项的含义 日志界别的配置 数据返回到前端的json的配置 数据源的配置 需要新建 ...
- 一百三十:CMS系统之七牛js和python的SDK使用示例
1.安装: pip install qiniu 2.编写获取uptoken的接口 @app.route('/uptoken/')def uptoken(): access_key = '' secre ...
- 【工具】sqlmap 中文手册 使用教程
日期:2019-07-28 09:27:27 更新: 作者:Bay0net 介绍:自己翻译了一下,做个备忘. 0x01. 基本信息 官网 sqlmap: automatic SQL injection ...
- Mysql——索引相关
索引失效的情况: 随着表的增长,where条件出来的数据太多,大于20%左右,使得索引失效(会导致CBO计算走索引花费大于走全表)
- React Native Expected a component class,got [object Object]解决
报错原因: 组件大小写错误. 解决方式: 修改组件名称即可. 这篇博客介绍了大部分RN的错误原因和解决方法: http://blog.csdn.net/chichengjunma/article/de ...