Math 解决圆碰撞

Math 解决圆碰撞,math,geometry,collision-detection,Math,Geometry,Collision Detection,我正在编写软件,扩展到包括对碰撞的响应。圆边和圆矩形相当直接。但圆圈把我难住了 例如,在离散事件模拟中,让两个圆碰撞,一个红色,一个绿色。我们可能会遇到以下情况: 在它们碰撞后,我们可以立即: 这里RIP和GIP是上一个时钟滴答声中圆圈的位置。在当前时钟滴答声中,在RDP和GDP处检测到碰撞。然而,当两个圆圈处于RCP和GCP时,时钟信号之间发生碰撞。时钟滴答作响时,红色圆圈向下移动RVy,向右移动RVx;绿色圆圈向下移动GVy,向左移动GVx。RVy不等于GVy;RVx也不等于GVx 当

我正在编写软件,扩展到包括对碰撞的响应。圆边和圆矩形相当直接。但圆圈把我难住了

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

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

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


当圆心之间的距离小于或等于圆的半径之和时,就会发生碰撞,也就是说,在上图中,d如果您正在寻找关于圆形物体非弹性碰撞的基本参考,Joe van den Heuvel和Miles Jackson的著作很容易理解

从最不正式到最正式,以下是一些后续参考资料,介绍如何实现支持问题解决方案的编程(碰撞响应)

  • 布莱恩·贝克曼和查尔斯·托瑞
  • Chris Hecker,游戏开发者,1997年
  • David Baraff,在线Siggraph’97课程笔记,与刚体模拟特别相关的幻灯片
你将不得不接受一些近似值-贝克曼在视频中演示,即使是非常简单的情况,也不可能通过分析预测会发生什么,这更糟糕,因为你正在模拟一个具有离散步骤的连续系统。

“这就是问题:我如何采取行动。”

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

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

碰撞将被建模为弹性碰撞。惯性交换的数学 已经到位。问题是如何定位这些圆

考虑到我将只讨论第一个问题,解决碰撞发生的确切位置。假设两个圆都匀速运动,只需知道碰撞发生的确切时间,即圆中心之间的距离何时等于其半径之和即可

匀速运动时,可以将一个圆(红色)的速度减去另一个圆(绿色)的速度,将其视为静止。实际上,我们把第一个圆的中心当作固定的,而只考虑第二个圆是在(匀速)运动中。

现在,通过解一个二次方程,可以得到碰撞的精确时间。设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位置为零)较小。

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

将对象A和B分别称为位置向量AB以及速度向量uv。假设A以每时间步u单位的速率移动(因此,在时间=t时,A在A;在时间=t+1时,A在A+u

我不确定你是否想看推导;看起来就不那么好了。。。我对乳胶的了解非常有限。(如果您确实希望我这样做,我可以稍后在中进行编辑)。但现在,我得到的是,使用通用的C#ish语法,向量2类型声明为Vector2(X,Y),具有向量加法、标量乘法、点积和长度函数

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为一个未定义的值

好吧,希望这是有帮助的!我碰巧和你有同样的问题,决定看看我是否能在纸上解决

编辑:我以前应该更仔细地阅读前面的回答
a = V*V
b = 2 P*V
c = P*P - r^2
t = (-b - sqrt(b^2 - 4ac)) / (2a)