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 ... 
随机推荐
- vue后台_实战篇
			一.一些常用组件效果的实现 1)面包屑导航 主要是使用$route.mathed:一个数组,包含当前路由的所有嵌套路径片段的路由记录 .路由记录就是 routes 配置数组中的对象副本 (还有在 ch ... 
- Oracle中shrink space命令
			shrink_clause: http://docs.oracle.com/cd/B19306_01/server.102/b14200/statements_3001.htm#i2192484 ... 
- Ubuntu 18.04安装Samba服务器及配置
			Ubuntu 18.04安装Samba服务器及配置 局域网下使用samba服务在Linux系统与Windows系统直接共享文件是一项很方便的操作.以Ubuntu为例配置samba服务,Linux服务器 ... 
- 模糊C均值聚类的公式推导
			j=1...n,N个样本 i=1...c,C聚类 一.优化函数 FCM算法的数学模型其实是一个条件极值问题: 把上面的条件极值问题转化为无条件的极值问题,这个在数学分析上经常用到的一种方法就是拉格朗日 ... 
- ViewPager翻页控件简单使用方法
			例子布局文件: 主activity布局文件:activity_view_pager.xml <?xml version="1.0" encoding="utf-8& ... 
- java引用如果是成员变量则引用本身不保存在栈上的汇编级调试证明
			很久很久没有更新博客了,因为发生太多太多猝不及防的事情,再加上自己本身也特别忙,这里补上一直想发的自己觉得很有意义的一次探索过程. 就是很多java开发人员都曾被误导的一个点——“如果一个变量是引用, ... 
- 用python画函数图像
			import matplotlib.pyplot as plt import numpy as np x = np.linspace(0, 1, 50) # 从0到1,等分50分 y = 210*(x ... 
- Clonezilla克隆还原系统
			简介 Clonezilla是一个专门用来克隆磁盘驱动器的Linux发行版.它可以操作任何你所能想象到的文件系统类型.Clonezilla有两种版本:Live和SE.Live版本与Ubuntu的Live ... 
- HashMap和ConcurrentHashMap 源码关键点解析
			第一部分:关键源码讲解 1.HashMap 是如何存储的? a.底层是一个数组 tab b. hash=hash(key) ,然后根据数组长度n和hash值,决定当前需要put的元素对应的数组下标, ... 
- 微信小程序 左右分类列表
			分类界面,左边是一级目录,右边是一级目录对应的二级目录,根据这个需求,我们数据设计的结构一定是数组嵌套数组,第一个数组包含一级目录数据,嵌套的数组包含的是二级目录的数据. wxml代码: <vi ... 
