碰撞解决


23

我非常了解如何检查碰撞,但是我不知道如何以良好的方式处理碰撞。

简化,如果两个对象发生碰撞,我将使用一些计算来更改速度方向。如果我不移动这两个对象,它们将仍然重叠,并且如果速度不够大,它们在下次更新后仍将碰撞。这可能导致对象彼此卡住。

但是,如果我尝试移动两个对象以使其不重叠,该怎么办。这听起来是个好主意,但我已经意识到,如果有两个以上的对象,这将变得非常复杂。如果我移动两个对象并且其中一个与其他对象发生碰撞该怎么办,所以我也必须移动它们,并且它们可能与墙壁发生碰撞等。

我有一个自上而下的2D游戏,但我认为这与它没有太大关系。通常如何处理冲突?

代表Wooh提出这个问题


1
您能说明游戏的类型吗?“自上而下的2D”可能意味着很多事情:塞尔达风格的动作冒险游戏,垂直滚动射击游戏或口袋台球游戏。所有这些将具有处理碰撞的非常不同的标准样式!
伊恩·施雷伯

2
我无法澄清这一点。问题不是关于碰撞会发生什么,而是关于多重重叠的问题。我想知道我正在互相反弹物体就足够了,我希望它们表现得现实一些以回答这个问题。
CiscoIPPhone

Answers:


16

丹尼尔·科迪切克(Daniel Kodicek)在他的《程序员的数学与物理学》一书中非常详细地介绍了该主题。

Kodicek为实现自然的碰撞解决方案做了两件事:

  • 他的碰撞检测功能可计算两个物体碰撞的确切时间。
  • 他在碰撞时会重新计算新的速度,因此物体永远不会重叠。

我上传了一个基于Kodicek的碰撞检测和解决方案演示

更新:这是一种碰撞检测和解决算法,与Kodicek的方法非常相似。附带源代码。我仍然推荐Kodicek的书,因为他的算法实现方式略有不同,并且解释得更加透彻。


1
您的演示链接似乎已断开。
ashes999 2011年

@ ashes999:链接已修复!
Leftium 2011年

这是圈子的算法。盒子呢?
安东·奇金

@AntonChikin:Kodicek的碰撞解决算法仅需要三个输入:碰撞点处的质量,速度和法线。当检测到碰撞时,Kodicek总是在碰撞点计算法线。他解释了许多不同类型的碰撞检测,包括撞到另一个盒子的盒子。只需将冲突检测算法插入冲突解决算法即可。有关完整说明,请参见Kodicek的书的第8-10章。(请注意,旋转物理学需要更多的数学知识,这在本书后面还会介绍...)
Leftium 2015年

1
@ThomasHilbert:演示源代码和Windows可执行文件现在可在leftium.com/asteroid上获得
Leftium

6

如果在对象移动之前而不是之后检查碰撞,该怎么办?或者换句话说,如果对象碰撞,您拒绝新位置,在这种情况下重用旧位置?

伪代码:

  tmpPosition1 = Obj1.position
  tmpPosition2 = Obj2.position
  updatePosition(Obj1)
  updatePosition(Obj2)
  if collided(Obj1,Obj2) then
      updateVelocities( Obj1, Obj2 )
      Obj1.position = tmpPosition1
      Obj2.position = tmpPosition2
  endif

这样,对象将要碰撞时就会相互碰撞,如果您的更新步骤足够小,则播放器应该不会在表示中发现任何奇怪的东西。


1
这很烦人,因为您不能轻松地平行于对象移动,因为如果您触摸其他对象也无法移动。
Ikke

除非您分别解析x和y,否则
Instantaphex

6

每当两个对象重叠时,请检查它们是否朝向彼此或远离彼此。仅当它们彼此靠近时才进行碰撞。

向量数学非常简单,只需计算:

dot_product(B.position-A.position,A.velocity-B.velocity)

如果结果是肯定的,则对象彼此接近。


4

我可能会误会,但似乎您在问两个问题:1.处理冲突解决的一般方法是什么?您要寻找的术语是“基于脉冲的仿真”,并且有很多论文可以比我做得更好。

总而言之,您想在物理量乘以速度上推动物理模拟,动量空间是质量乘以速度(不要做基于力的事情,积分器无论如何都做得不好)。

幸运的是,对于角响应,最大惯性矩和最小惯性矩总是可以减小为两个正交轴(在2D中),这意味着矩阵乘法通常会起作用,如果将它们与X和Y轴对齐,它会变成2D向量。

发生碰撞时,您会根据碰撞点处的线性力矩和角力矩来计算响应,而如果存在互穿现象,则可以通过施加一些惩罚力(如上所述)来使两个物体分开,这是一个很好的软糖因素。

从这一点开始,您最终将添加越来越多的规则来控制异常行为,例如,设置最大角动量上限,以免事物像陀螺那样旋转,但这是一个好的开始。

如果可以,请保持简单。

  1. 您如何解决多体碰撞问题

唯一可行的方法是使用线性方程组和大量求解方法。实用的方法是使用上述系统,并随着时间的推移自然解决物理问题。

大多数做滚动或站立在移动表面上的游戏都具有混合模型,在这种模型中,您的脚附着在表面(或车轮在道路上)以适应物理时间步长(这将导致互穿响应周期和将无法正常工作)。

希望这可以帮助。如果您需要任何数学示例,请告诉我。


3

通常在物理引擎中解决此问题的方法是施加惩罚力。如果刚体以更高的速度运动(在穿透过程中会出现瞬时跳动),则在互穿之后移动刚体将看起来不太好,尽管作为第一步,您应该尝试一下并看看它是否满足您的要求。

A penalty force就像弹簧阻尼器一样应用,其中穿透力越强,则穿透刚性刚体的力就越大,而在后续框架中则减小。把它想象成春天。当两个刚体相互渗透时,它们各自遇到一个不可见的弹簧,该弹簧会抑制它们的前进(即,防止更多的相互渗透),并应用前面提到的方法,penalty force直到这些实体不再渗透为止。

这是一个广泛的话题,但希望以上信息能帮助您入门。


因此,与其阻止相互渗透,不如说该方法允许它但是提供阻力,就像压缩对象一样?
CiscoIPPhone

它提供抵抗力,是的,抵抗力会随着人体试图穿透的程度而增加。实际上,如果您有足够低的增量时间(例如10ms),它将不会产生任何互穿。但是,此方法的真正优势在于,由于某些原因,您的主体确实相互渗透(位置已更改,它们是网络化的刚性主体,并且其位置已得到校正),现在需要分离,因为如果没有这种技术,这些主体会爆炸而不是逐渐分开。
Samaursa,2010年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.