引子

在 Collision Detection 中对碰撞检测作了简略的介绍。在查问材料时,在 Github 上发现了 CollisionDetection 这个我的项目。查看之后,发现对于碰撞检测的探讨,由浅入深,很适宜学习。在其根底上,做了 JavaScript 版本的实现。

以下示例未做兼容性查看,倡议在最新的 Chrome 浏览器中查看。

  • Origin
  • My GitHub

Point/Point

这是示例页面。

最早的碰撞检测是检测两个点的碰撞。为了检测它们是否接触,咱们只须要查看它们的 X 和 Y 坐标是否一样。

/* * (x1,x2) 点的坐标 * (y1,y2) 点的坐标 */function checkPointPoint(x1,x2,y1,y2) {  if (x1 == x2 && y1 == y2) {    return true; // 产生碰撞  } else {    return false; // 没有碰撞  }}

Point/Circle

这是示例页面。

点与圆的碰撞检测,只须要比拟点和圆心之间的间隔 distance 是否小于或等于圆的半径 r

function checkPointCircle() {  if (distance <= r) {    return true; // 产生碰撞  } else {    return false; // 没有碰撞  }}

如下图所示,计算两个点之间的间隔,在几何上进行转换,应用勾股定理(Pythagorean Theorem)能够得出:

a*a + b*b = c*c; // 勾股定理a = px - cx; // 点 x 坐标与 圆心 x 坐标b = py - cy; // 点 y 坐标与 圆心 y 坐标c = Math.sqrt(a*a + b*b);

带入到下面检测碰撞的逻辑中:

/* * (px,py) 点的坐标 * (cx,cy) 圆心的坐标 * radius 圆的半径 */function checkPointCircle({px,py,cx,cy,radius}) {  const minusX = px - cx;  const minusY = py - cy;  const distance = Math.sqrt(minusX*minusX + minusY*minusY);  if (distance <= radius) {    return true; // 产生碰撞  } else {    return false; // 没有碰撞  }}

Circle/Circle

这是示例页面。

圆与圆的碰撞检测,只须要比拟两个圆心之间的间隔 distance 是否小于或等于两个圆的半径之和 r1+r2

同样的应用到了勾股定理。

/* * (c1x,c1y) 圆心的坐标 * (c2x,c2y) 圆心的坐标 * r1,r2 圆的半径 */function checkCircleCircle({c1x,c1y,c2x,c2y,r1,r2}) {  const minusX = c1x - c2x;  const minusY = c1y - c2y;  const distance = Math.sqrt(minusX*minusX + minusY*minusY);  if (distance <= r1+r2) {    return true; // 产生碰撞  } else {    return false; // 没有碰撞  }}

参考资料

  • POINT/POINT
  • POINT/CIRCLE
  • CIRCLE/CIRCLE