• html5游戏-包围盒检测算法


    矩形包围盒算法:检测2个矩形是否重叠,在这样情况下要判断2个矩形是否碰撞只需要比较两个矩形顶点的坐标即可。假设矩形A用(x1,y1)表示左上角,(x2,y2)表示右下角,矩形B用(x3,y3)表示左上角,(x4,y4)表示右下角,则满足下列条件则表示没有碰撞,反之则碰撞。
    没碰撞:x1>x4或者x2<x3。
    没碰撞:y1>y4或者y2<y3

    var ABBox = function(tBox1,tBox2){
        var x1 = tBox1.x,
              y1 = tBox1.y,
              x2 = tBox1.x + tBox1.w,
              y2 = tBox1.y + tBox1.h,
              x3 = tBox2.x,
              y3 = tBox2.y,
              x4 = tBox2.x + tBox2.w,
              y4 = tBox2.y + tBox2.h;
         if(x1>x4||x2<x3)return false;
         if(y1>y4||y2<y3)return false;
         return true;
    };

    圆形包围盒算法:检测圆形的碰撞比较容易,假设圆A的坐标(x1,y1),半径是r1,圆B的坐标(x2,y2),半径是r2,则如果满足不等式(y2-y1)2+(x2-x1)2<=(r1+r2)2则表示两个圆发生了碰撞,其实就是圆心之间的距离小于两个圆的半径之和即可,由于计算距离需要用到开方运算,效率较低,所以直接比较距离的平方。

    var RBBox = function(tBox){
            var dx = x-tBox.x,
                  dy = y-tBox.y,
                  dr = r+tBox.r;
            return dx*dx+dy*dy<dr*dr;
     };

    凸多边形包围盒算法:对于2个多边形来说,检测它们是否相交,我们所要做的是计算两个多边形的每条边在分离轴上的投影的距离。找出每条边形成的向量在轴上投影的最大值和最小值,这样在分离轴上的每个多边形就分别以这两个值形成线段,最后比较这两个线段是否重叠就可以判断这两个多边形是否相交了。

    所以在做检测的时候只需要按照以下步骤进行即可。
    (1) 产生所有的分离轴,选取一条测试。
    (2) 计算图形在该分离轴上的投影。
    (3) 检测投影是否相交,如果相交则选取下一条,重复步骤2和步骤3,如果不相交则返回不相交。
    (4) 所有分离轴检测完毕,返回相交。

    //x,y是多边形中心坐标,pArr是一个顶点数组,点的坐标采用相对中心点坐标,按顺时针存放各顶点
           init:function(x,y,pArr)
           {
               this.pArr = pArr;
               this._super(x,y);
           },     
           //转换所有顶点坐标到绝对坐标系中
           mapToWorld:function()
           {
              var p = [];
              for(var i=0,len = this.pArr.length;i<len-1;i+=2)
              {
                  p.push(this.pArr[i]+this.x,this.pArr[i+1]+this.y);
              }
              return p;
           },
           collided:function(tBox)
           {           
               var p1 = this.mapToWorld(),
                   p2 = tBox.mapToWorld();
               return MathUtil.isCollide(p1,p2);
           },
    //判断两个多边形是否相交碰撞,p1,p2用于保存多边形点的数组
                isCollide:function(p1,p2){
                    //定义法向量
                    var e = {"x":0,"y":0};
                    var p = p1,
                        idx=0,
                        len1=p1.length,
                        len2=p2.length;
                    for(var i=0,len = len1+len2;i<len-1;i+=2){
                        idx = i;
                        //计算两个多边形每条边
                        if(i>len1){
                            p=p2;
                            idx=(i-len1);
                        }
                        if(i==p.length-2){
                            px=p[0]-p[idx];
                            py=p[1]-p[idx+1];
                        }
                        else{
                            px = p[idx+2]-p[idx],
                            py = p[idx+3]-p[idx+1];
                        }
                        //得到边的法向量
                        e.x = -py;
                        e.y = px;
                        //计算两个多边形在法向量上的投影
                        var pp1 = this.calcProj(e,p1);
                        var pp2 = this.calcProj(e,p2);
                        //计算两个线段在法向量上距离,如果大于0则可以退出,表示无相交
                        if(this.segDist(pp1[0],pp1[1],pp2[0],pp2[1])>0){
                            return false;
                        }
                    }
                    return true;
                }
    //计算同一个轴上线段的距离s1(min1,max1),s2(min2,max2),如果距离小于0则表示两线段有相交;
                segDist:function(min1,max1,min2,max2){
                    if(min1<min2){
                        return min2-max1;
                    }
                    else{
                        return min1-max2;
                    }
                },
  • 相关阅读:
    uva 11080(二分图染色)
    poj 3255(次短路)
    uva 707(记忆化搜索)
    uva 436(floyd变形)
    uva 11748(求可达矩阵)
    uva 11573(bfs)
    Codeforces Round #226 (Div. 2) 解题报告
    uva 11354(最小瓶颈路--多组询问 MST+LCA倍增)
    uva 534(最小瓶颈路)
    uva 538(简单图论 入度出度)
  • 原文地址:https://www.cnblogs.com/gongshunkai/p/5818771.html
Copyright © 2020-2023  润新知