2013-08-23 86 views
2

我正在编写扩展Circle-Rectangle collision detection (intersection)以包含对碰撞的响应的软件。圆形边和圆形矩形相当直接。但是圈子让我难倒了。解决圆圈碰撞问题

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

Two Circles Colliding

它们相撞后,我们立即可以有:

Enlarged Circles Collision

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

Circle-Circle Computation

相撞当圆中心间的距离小于或等于该圈子半径之和时,也就是,前面的图中,d < =(RR + GR)。在发生碰撞时,我们需要在调整圆的速度分量之前将DP定位回CP。在d ==(Rr + Gr)的情况下,由于DP位于CP,因此不需要重新定位。

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

Penetration

对我来说,这是完全错误的。它假定两个圆的速度矢量相等,在这个例子中,情况并非如此。我认为渗透与计算有关,但是如何避开我。我知道这个问题可以改写为我们想要为Gcdy和GCdx解决的类似三角形的问题。

Right Similar Triangles

碰撞本身将被模拟成弹性,以及惯性交换数学已经到位。唯一的问题是将圆圈置于碰撞的位置。

+1

你在找什么样的碰撞?弹性(不会损失能量)?无弹性(能量损失)?这两个圈子粘在一起,并继续移动一对? – John

+4

这个问题似乎是题外话题,因为它是关于物理而不是编程。 – tom10

+0

@john碰撞将被建模为弹性。惯性交换的数学已经到位。问题是在哪里定位圈子。 – Gus

回答

1

如果您正在寻找关于圆形物体的非弹性碰撞的基本参考,Joe van den Heuvel和Miles Jackson的Pool Hall Lessons: Fast, Accurate Collision Detection Between Circles or Spheres很容易遵循。

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

你将不得不接受一些近似 - 贝克曼的视频,即使是很简单的情况下,是不可能的分析预测会发生什么证明,这是更糟糕,因为你是模拟具有分立步骤的连续系统。

2

“这就是问题所在:我该如何做出这个举动。”

您很可能想知道如何“在调整圆的速度分量之前将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之前,另一个在后,但可能是放牧接触给出“双根”)。你想要的解决方案(根)是较早的解决方案,其中t(在“即时”RIP,GIP位置处为零)较小。

1

给定初始位置和速度矢量,实际上可以得到达到碰撞所需时间的表达式。

打电话给你的对象A和B,并说他们有位置向量一个b和速度矢量ü分别v。比方说,以每时间步ü单元的速率A移动(因此,在时间= t时,A是在一个;在时间= t + 1的,A是在一个 + Ú)。

我不确定是否要查看派生;它看起来不那么好......我对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描述的二次方程。道歉的冗余职位。

0

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

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

enter image description here

我们必须找到在该圆穿过原点,换句话说发现t为其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是碰撞时间。

+0

还有一件事。根据你的代码,如果两个重叠的对象重新定位并且它们的速度按照惯例改变 - 但是它们没有被重新定位得足够远 - 那么它们可能会立即再次碰撞并且由于它们已经改变了速度而在地图上翘曲。为了防止出现这种情况,最好使用浮点数,使它们在正确的方向上四舍五入,但我不知道该怎么做,所以我只是用'1 + epsilon'乘以't' 。 – jcarpenter2