一、坐标轴投影
依据理论:
对于两个多边形,如果存在一个轴,使得两个多边形的在该轴上的投影不重叠,则多边形之间没有碰撞发生。所有可能的轴为垂直于多边形每个边的轴。
对于矩形的参考轴比较简单,只要是两邻的两条边就可以了。
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
待续……