碰撞检测就是查看物体是否重合。
碰撞检测常用于游戏开发,通过碰撞检测判断前面是否有障碍物以及两个物体是否发生碰撞,根据检测的结果做出不同的处理。
1.矩形m与矩形n
矩形1的参数是:左上角的坐标是(x1,y1),宽度是w1,高度是h1;
矩形2的参数是:左上角的坐标是(x2,y2),宽度是w2,高度是h2。
都是降维的思路
第一种:
m.left<n.right and n.left<m.right and m.bottom<n.bottom and n.bottom<m.top
( 其中,left、right、bottom、top为矩形的左、右、上、下坐标值)
第二种:
两个矩形中心点在x方向的距离的绝对值小于等于矩形宽度和的二分之一,同时y方向的距离的绝对值小于等于矩形高度和的二分之一。
x方向:| (x1 w1 / 2) – (x2 w2/2) |< |(w1 w2) / 2|
y方向:| (y1 h1 / 2 ) – (y2 h2/2) |< |(h1 h2) / 2 |
2.圆形与圆形
计算两个圆心之间的距离是否小于两个圆的半径和。
假设:
圆形1的左上角坐标是(x1,y1),半径是r1,
圆形2的左上角的坐标是(x2,y2),半径是r2。
下面是数学表达式:
(x1 – x2)2 (y1 – y2)2 <(r1 r2)
3.矩形与圆碰撞
通过找到矩形上与圆形最近的点,判断其与圆心的距离,如果小于半径就碰撞
定义:
- 矩形上离圆心最近的点为变量:closestPoint = {x, y};
- 矩形 rect = {x, y, w, h}; // 左上角与宽高
- 圆形 circle = {x, y, r}; // 圆心与半径
首先是 x 轴:
如果圆心在矩形的左侧(if(circle.x< rect.x)),那么 closestPoint.x = rect.x。
圆心在矩形的左侧
如果圆心在矩形的右侧(elseif(circle.x > rect.x rect.w)),那么closestPoint.x = rect.x rect.w。
圆心在矩形的右侧
如果圆心在矩形的正上下方(else),那么 closestPoint.x = circle.x。
圆心在矩形的正上下方
同理,对于 y 轴(此处不列举图例):
如果圆心在矩形的上方(if(circle.y< rect.y)),那么 closestPoint.y =rect.y。
如果圆心在矩形的下方(elseif(circle.y > rect.y rect.h)),那么 closestPoint.y= rect.y rect.h。
如果圆心在矩形的正左右两侧(else),那么 closestPoint.y = circle.y。
因此,通过上述方法即可找出矩形上离圆心最近的点了,然后通过『两点之间的距离公式』得出『最近点』与『圆心』的距离,最后将其与圆的半径相比,即可判断是否发生碰撞。
代码语言:javascript复制var distance = Math.sqrt(Math.pow(closestPoint.x - circle.x, 2) Math.pow(closestPoint.y - circle.y, 2))
if(distance < circle.r) return true // 发生碰撞
else return false // 未发生碰撞
4.圆形与旋转矩形
将矩形的旋转看成是画布的旋转,求出旋转前圆心坐标,就可以用圆形与矩形的碰撞检测了
附:
关于两个矩阵碰撞的感悟:
当只有一个矩形的时候,它的左边界一定小于它的右边界,它的下边界一定小于它的上边界。
两个矩形的时候,要想保证相交,必须一个矩形的左边界小于另一个矩形的右边界,一个矩形的下边界小于另一个矩形的上边界。
一对情侣A和B,A挣钱的最大值一定得大于B花钱的最小值,A最大的容忍量一定得大于B最小的吵闹程度,A最好的态度一定得好于B最差的态度,等等。