矩形碰撞检测的一些方法(支持旋转)

一、坐标轴投影

依据理论:

对于两个多边形,如果存在一个轴,使得两个多边形的在该轴上的投影不重叠,则多边形之间没有碰撞发生。所有可能的轴为垂直于多边形每个边的轴

对于矩形的参考轴比较简单,只要是两邻的两条边就可以了。

1、获取矩形的顶点坐标

首先得出矩形的四个点的坐标(可参考本博文章《根据矩形的位置和大小获取顶点位置》)。

2、计算一个矩的顶点在另一个矩边上的投影

计算两个矩形中的另一个矩形各顶点在当前矩形参考边上的投影坐标,只要有一个顶点投影坐标在参考边线内则进行下一条参考边的比较,如果四个顶点投影都不在参考边内则不相交。

重复以上操作分别完成两个矩形的任相邻的两条边。

下面给出js代码

function(rect1, rect2) {
    if (rect1.r == undefined || rect2.r == undefined) {
      return 2;
    }
    //获取顶点

    let r = [this.getRectAllPoint(rect1), this.getRectAllPoint(rect2)];
    
    let rtn = 0;
    let dowdis = -1;
    let dis = 0;
    let rl = r.length;
    for (let j = 0; j < rl; j++) {
      if (rtn == 1) {
        rtn = 0;
      }
       //两点间的距离
      dis = this.getTwoPointDis(this.getPoint(r[j].x[0], r[j].y[0]), this.getPoint(r[j].x[1], r[j].y[1]));
      //遍历另一个矩形的顶点
      for (let i = 0; i < r[rl - 1 - j].x.length; i++) {
        dowdis = this.getPointToLineShadowDis(this.getPoint(r[j].x[0], r[j].y[0]), this.getPoint(r[j].x[1], r[j].y[1]), this.getPoint(r[rl - 1 - j].x[i], r[rl - 1 - j].y[i]));
        //console.log("utils.dis1:" + dis + ",dowdis:" + dowdis );
        if (dowdis > 0 && dowdis <= dis) {
          rtn = 1;
          break; //相交
        }
      }
      if (rtn == 0) {
        return rtn;
      }
      rtn = 0;
      dowdis = -1;
      dis = this.getTwoPointDis(this.getPoint(r[j].x[0], r[j].y[0]), this.getPoint(r[j].x[3], r[j].y[3]));
      //遍历另一个矩形的顶点
      for (let i = 0; i < r[rl - 1 - j].x.length; i++) {
        dowdis = this.getPointToLineShadowDis(this.getPoint(r[j].x[0], r[j].y[0]), this.getPoint(r[j].x[3], r[j].y[3]), this.getPoint(r[rl - 1 - j].x[i], r[rl - 1 - j].y[i]));
        //console.log("utils.dis2:" + dis + ",dowdis:" + dowdis);
        if (dowdis > 0 && dowdis <= dis) {
          rtn = 1;
          break; //相交
        }

      }

      if (rtn == 0) {
        return rtn;
      }
    }

    return rtn;
  }

总结:使用此方法只能判断两个矩形是否是交,不能判断出相交的顶点。

 

二、向量叉乘计算

依据理论:

向量a*向量b ,小于0,b在a的顺时针方向;大于0,b在a的逆时针方向;等于0,a与b平行。

向量叉乘计算公式:

设向量a(xa,ya),向量b(xb,yb)

a^b=xa*yb-xb*ya

待续……

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值