如果你有一个以速度 V 运动的圆 C,你如何计算与矩形 R 碰撞的冲击点?
我问这个问题并立即回答我自己的问题,希望有人有一个更简单的答案。搜索这个问题会找到大量静态案例的答案,检测静止圆是否与静止矩形相交,但我找不到移动案例的答案。
这是我想出的:
首先,我们定义我们的对象。
我们的圆 C 有圆心 cx, cy 和半径 r.
预计的下一个位置是 C 加上它的速度,所以 C2 = cx+vx, cy+vy, r。我们将这个位置标记为 c2x,c2y。
矩形R定义为左、上、右、下。
我们试图找到撞击时刻的圆心Q。
这是通过计算从 C2 到矩形边缘的距离,并检查它是否大于或小于 C2 的半径来完成的。
dx = max(rect.left - c2x, 0, c2x - rect.right)
dy = max(rect.top - c2y, 0, c2y - rect.bottom)
isIntersecting = (dx*dx + dy*dy) <= C2.r*C2.r
最大值是所以我们只关心正距离,导致 dx,dy 点是矩形上最近的点 P,通过将圆的中心夹在矩形边界上找到这里。我们使用毕达哥拉斯公式来计算距离:sqrt(A^2 + B^2) = C,但是两边都平方以避免昂贵的 sqrt 操作,作为检查距离的常见优化。
如果不是相交,我们就完成了。
知道现在会发生碰撞,我们需要确定碰撞点I。
创建一个新的外部矩形 R2,它是原来的 R 按我们的圆的半径扩展。
R2 = R.left-r, R.top-r, R.right+r, R.bottom+r
在撞击点,我们圆的中心点将位于该外部矩形的边缘之一,或者它将撞击以内部矩形 (R) 角之一为中心的半径为 r 的圆。
我们确定这些情况如下:
通过将 c2x、c2y 夹紧到 R2.left、R2.top、R2.right,找到外矩形 R2 最接近圆 C1 的 1-2 条边(水平和垂直)。 R2.底部。结果点要么是一个角,在这种情况下我们有一个垂直和水平的边要检查,要么它会落在一条边上而不是一个角上,在这种情况下我们只需要检查那个边。
求CV与边的交点W。如果检查 2 个边,找到 2 个点,W 是更接近 C 的那个(再次使用毕达哥拉斯距离)。
现在,如果 W 在垂直边上,检查 W.y 是否在 R.top 和 R.bottom 之间。那是内部矩形。如果是这样,我们的影响点是
Q.x = R.left or R.right (whichever side we are checking against)
Q.y = W.y
同样,如果 W 在水平面上,检查 W.x 是否在 R.left 和 R.right 之间。如果是这样,我们的影响点是
Q.x = W.x
Q.y = R.top or R.bottom (whichever side we are checking against)
如果点 W 没有投射到内部矩形的任一侧,我们就处于角落情况,我们的圆在角落处碰到矩形。我们可以通过找到 CV 与圆 CR 的交点来找到这一点,圆 CR 的中心点是我们正在检查的 R 的哪个角(从上面),半径为 r(与 C.r 相同)。
如果找到2个交点,离C近的就是落点。如果只找到 1 个点,我们只是擦过矩形的角,这就是撞击点。
很抱歉没有包括任何图表或现场演示,已经晚了。我可能会稍后编辑它。
有谁知道更简单的方法来确定这个?
注意,一旦找到撞击点,计算碰撞反弹就相对简单了:
我太累了,记不起那里第 4 步的数学,但希望解释是有道理的。