6

我正在编写扩展圆矩形碰撞检测(交叉点)以包括对碰撞的响应的软件。圆边和圆矩形相当直接。但是一圈圈让我难住了。

例如,在离散事件模拟中,让两个圆相撞,一个红色和一个绿色。我们可能有以下情况:

两个圆圈碰撞

在它们发生碰撞后,我们可以立即:

扩大的圆圈碰撞

这里 RIP 和 GIP 是上一个时钟滴答时圆圈的位置。在当前时钟滴答处,在 RDP 和 GDP 上检测到冲突。然而,当两个圆圈位于 RCP 和 GCP 时,时钟滴答之间发生了冲突。在时钟滴答声中,红色圆圈使 RVy 向下移动,RVx 向右移动;绿色圆圈向下移动 GVy,向左移动 GVx。RVy 不等于 GVy;RVx 也不等于 GVx。

圆-圆计算

碰撞发生在圆心之间的距离小于或等于圆半径之和时,即上图中d <= ( Rr + Gr )。在 d < ( Rr + Gr ) 的碰撞中,我们需要在调整圆的速度分量之前将 DP 定位回 CP。在 d == ( Rr + Gr ) 的情况下,不需要重新定位,因为 DP 位于 CP 处。

这就是问题所在:我如何回到 CP。一些作者建议应用下图中由 p 给出的一半穿透。

渗透

对我来说,这完全是错误的。它假设两个圆的速度矢量相等,但在本例中并非如此。我认为渗透与计算有关,但我如何逃避。我确实知道这个问题可以重新定义为直角相似三角形的问题,我们要在其中解决 Gcdy 和 GCdx。

右相似三角形

碰撞本身将被建模为弹性,并且惯性交换的数学已经到位。唯一的问题是碰撞时圆圈的位置。

4

4 回答 4

4

“这就是问题所在:我该如何行动。”

您可能想知道如何“在调整圆的速度分量之前将 DP 定位回 CP”。

因此有两个问题,如何确定 CP(发生碰撞的位置)以及如何调整圆从该点向前的运动。第一部分有一个相当简单的解决方案(允许不同的半径和速度分量),但第二部分取决于是否对弹性或非弹性响应进行建模。在评论中,您写道:

碰撞将被建模为弹性。惯性交换的数学已经到位。问题是在哪里放置圆圈。

鉴于我将只解决第一个问题,解决发生碰撞的确切位置。假设两个圆都匀速运动,知道碰撞发生的确切时间就足够了,即圆心之间的距离何时等于它们的半径之和。

对于匀速运动,可以通过从另一个圆(绿色)的速度减去它的速度来将一个圆(红色)视为静止的。实际上,我们将第一个圆的中心视为固定的,并且只考虑第二个圆处于(匀速)运动中。

现在通过求解一个二次方程来找到确切的碰撞时间。令 V = (GVx-RVx, GVy-RVy) 为圆的相对运动,令 P = (GIPx-RIPx,GIPy-RIPy) 它们在碰撞前的“瞬间”中的相对位置。我们通过定义为相对位置 P“动画”一条线性路径:

P(t) = P + t*V

并询问这条直线何时与半径 Rr+Gr 的原点周围的圆相交,或者何时相交:

(Px + t*Vx)^2 + (Py + t*Vy)^2 = (Rr + Gr)^2

这是一个未知时间 t 的二次方程,所涉及的所有其他量都是已知的。情况是这样的(在位置 CP 处或之前发生碰撞)将存在正实解(通常有两个解,一个在 CP 之前,一个在 CP 之后,但可能是掠过接触,产生“双根”)。您想要的解决方案(根)t 是较早的解决方案,即 t(在“即时”RIP、GIP 位置为零)较小的解决方案。

于 2013-08-24T13:34:05.617 回答
2

如果您正在寻找有关圆形物体非弹性碰撞的基本参考资料,池厅课程: Joe van den Heuvel 和 Miles Jackson 的圆或球体之间的快速、准确的碰撞检测非常容易理解。

从最不正式到最正式,这里有一些关于实现支持您的问题(冲突响应)解决方案的编程工艺的后续参考。

您将不得不接受一些近似值 - 贝克曼在视频中演示,即使对于非常简单的情况,也无法通过分析预测会发生什么,这甚至更糟,因为您正在模拟具有离散步骤的连续系统。

于 2013-08-24T09:01:36.683 回答
2

要以恒定速度重新定位两个重叠的圆,您需要做的就是找到发生碰撞的时间,并将它们的速度因子添加到它们的位置。

首先,我们将考虑一个具有组合半径和相对位置和速度的圆,而不是两个圆移动。让输入圆有位置P1P2、速度V1V2、半径r1r2。让组合圆有位置P = P2 - P1、速度V = V2 - V1和半径r = r1 + r2

在此处输入图像描述

我们必须找到圆穿过原点的时间,换句话说,找到twhich的值r = |P + tV|。应该有 0、1 或 2 个值,具体取决于圆是不通过原点、与原点相切还是穿过原点。

r^2 = ||P + tV||通过平方两边。

r^2 = (P + tV)*(P + tV) = t^2 V*V + 2tP*V + P*P利用L2范数等价于向量与自身的点积这一事实,然后分布点积。

t^2 V*V + 2tP*V + P*P - r^2 = 0把它变成一个二次方程。

如果没有解,则判别式b^2 - 4ac为负。如果它是零或正数,那么我们对第一个解决方案感兴趣,因此我们将减去判别式。

a = V*V
b = 2 P*V
c = P*P - r^2
t = (-b - sqrt(b^2 - 4ac)) / (2a)

t碰撞的时间也是如此。

于 2016-11-14T21:43:54.380 回答
1

在给定初始位置和速度矢量的情况下,您实际上可以推导出到达碰撞所需时间的表达式。

调用您的对象 A 和 B,并说它们分别具有位置向量ab以及速度向量uv。假设 A 在每个时间步以u个单位的速率移动(因此,在时间 = t 时,A 在a处;在时间 = t + 1 时,A 在a + u处)。

我不确定您是否想查看推导;它看起来不太好...我对 LaTeX 的了解非常有限。(如果您确实希望我这样做,我可以稍后对其进行编辑)。不过,就目前而言,这就是我所拥有的,使用通用的 C#-ish 语法,具有声明为 Vector2(X, Y) 的 Vector2 类型,并具有向量加法、标量乘法、点积和长度的函数。

double timeToCollision(Vector2 a, Vector2 b, Vector2 u, Vector2 v)
{
    // w is the vector connecting their centers;
    // z is normal to w and equal in length.
    Vector2 w = b - a;
    Vector2 z = new Vector2(-1 * w.Y, w.X);
    Vector2 s = u - v;
    // Dot() represents the dot product.
    double m = Dot(z, s) / Dot(w, s);

    double t = w.Length() / Dot(w, s) * 
              (w.Length() - sqrt( ((2 * r) ^ 2) * (1 + m ^ 2) - (m * w.Length()) ^ 2) ) / 
              (1 + m * m)

    return t;
}

至于对碰撞的反应:如果你可以快进到撞击点,你就不必担心处理相交的圆圈。

如果你有兴趣,这个表达式在没有碰撞的情况下会给出一些很酷的结果。如果两个物体彼此远离,但如果它们的速度相反,则会发生碰撞,您将得到 t 的负值。如果对象位于不平行但永远不会相遇(彼此通过)的路径上,您将在平方根内得到一个负值。丢弃平方根项,您将得到它们彼此最接近的时间。如果它们以相同的速度平行移动,则分母将为零,t 的值未定义。

好吧,希望这会有所帮助!我碰巧遇到了和你一样的问题,决定看看能不能在纸上解决。

编辑:我应该在发布之前更仔细地阅读以前的回复......上面的公式的混乱确实是hardmath描述的二次方程的解。为多余的帖子道歉。

于 2014-01-02T06:55:58.013 回答