我正在用Python开发一个物理引擎(我知道,它主要是为了“学习”),并且运行得很好。我一直在关注很多关于这个问题的在线文档,这一系列的文章特别有用:How to Create a Custom Physics Engine
我有一些材料在工作,它们作为一个类来保存一个物体的restitution
和density
。接下来发生的事情是,具有低密度和高恢复性的物体(例如分别为0.3和0.8),它们以如此高的速度相互反弹,以至于它们不需要很长时间就射入“空洞”
我有一个测试场景,设置了4堵墙来包围身体(球)。当它们以如此高的速度前进时,碰撞永远不会被记录,因为下一次物理模拟发生在它们已经通过“墙”之后
我真正感兴趣的是为什么它们在相互弹跳时速度如此之快,而我认为它们不应该这样。在我的示例录音中,我有一个小球(红色),它是由玩家(我)控制的。它的密度为0.3,恢复率为0.8,体积为100(r*r或10*10),质量为30千克(100*0.3)。另一个较大的球(绿色)不是由玩家控制的,但可以通过用红色球击打来反弹。它具有相同的材料,因此具有相同的密度和恢复性。但是,其质量更高,因为半径更大(30)。绿球的实际质量为270(900*0.8)
在录音中很明显,球以一种不自然的方式相互反弹。小球不应该受到比大球更高的冲动吗?我试图通过交换计算冲量时使用的质量值来解决这个问题。所以小球的冲量是用大球的质量来计算的,反之亦然。你会认为这是因为更大的球有更高的质量,但对我来说,它们彼此反弹得相当快
这是我在这两个球上的密度和恢复的正常行为吗?如果需要,我将共享代码,但由于本文已经有点长,如果不需要,我不会浪费空间。我的代码几乎完全遵循文章中介绍的内容,只是“转换”为Python代码
脉冲计算程序
# Relative velocity
rv = b.velocity - a.velocity
# Velocity along the normal direction
vel_along_normal = rv.dot(contact_normal)
# EPSILON (use lowest restitution value)
e = min(a.restitution, b.restitution)
# Calculate j, which will be used to get the impulse
j = -(1 + e) * vel_along_normal
j /= a_inv_mass + b_inv_mass
impulse = contact_normal * j
# Using ratio to have lighter bodies bounce with a higher impulse than heavier bodies
mass_sum = a_mass + b_mass
ratio = (b_mass / mass_sum)
a.rigid_body.velocity -= (impulse * ratio) * dt
ratio = (a_mass / mass_sum)
b.rigid_body.velocity += (impulse * ratio) * dt
碰撞后的速度差似乎存在符号问题。它并没有减慢红球的速度,而是加快了速度
整个功能在我看来并不正确,而且由于它不能按预期工作,因此出现了一些问题。下面的代码片段将为您解决冲突问题,而不是尝试找出错误(代码中有太多未知项,
dt
,a_inv_mass
,b_inv_mass
,contact_normal
)注意忽略
dt
(假设dt
为增量时间)注意两个对象都必须具有一定的质量。如果一个或两个质量都为0,则此操作将不起作用
相关问题 更多 >
编程相关推荐