Python 中的非弹性碰撞

Inelastic collision in Python

这是我第一次 post 来这里。我正在尝试学习 python 代码。我使用 turtle 模块制作了一个程序,该程序模拟一个弹跳球遭受非弹性碰撞,以减少每次弹跳的最大高度。它一直有效,直到球在非常短的高度弹跳并且它停止弹跳以使球以恒定(小)速度向下移动 - 这显然不是预期的。

"floor" 是 y = -100 坐标处的一条线。

我的迭代代码是这样的:

while t < 5000:
    vy += g
    h += vy
    corpo.goto(0, h)

    if h <= -100 and g == 0:
        vy = 0
        h = -100
        g = 0
    if abs(vy) <= 0.000000000000000000001 and h <= -100:
        vy = 0
        g = 0
        h = -100
    elif h <= -100 and vy < 0:
        vy = -vy * 0.75

    print(vy)

    t += dt 

问题是你的完成条件永远不会满足,可能是因为你在速度上增加了加速度(假设 g 指的是重力,如果不是,你真的应该考虑给它一个不同的名字).另一个问题是,即使进行了该更正,只有在 g * dt 小于 0.000000000000000000001 / 0.75 时才会满足 abs(vy) <= 0.000000000000000000001 的完成条件,否则 vy 永远不会小足够。

有两种方法可以解决后一个问题,您可以将完成条件扩展到 g * dt,即

if abs(vy) <= abs(g * dt) and h <= -100:
    # ...

或者您可以在 h <= -100 时关闭重力并稍微提高阈值,即

t = 0
dt = 0.0001
vy = 0
h = 0
g = -5
while t < 500:
    if h <= -100 and g == 0:
        vy = 0
        h = -100
        g = 0
        break
    if abs(vy) <= 0.0001 and h <= -100:
        vy = 0
        g = 0
        h = -100
    elif h <= -100 and vy < 0:
        vy = -vy * 0.75
    elif h > -100:
        vy += g * dt

    h += vy
    print(h, vy)

    t += dt 

前者保证收敛(球停止),后者则不然(可能会无限震荡).由于前者保证收敛,因此通常更可取 - 但不完全现实。

不过,最现实的解决方案是将两者结合起来,即

t = 0
dt = 0.001
vy = 0
h = 0
g = -9.81
while t < 500:
    if h <= -100 and g == 0:
        vy = 0
        h = -100
        g = 0
        break
    if abs(vy) <= abs(g * dt)*2 and h <= -100:
        vy = 0
        g = 0
        h = -100
    elif h <= -100 and vy < 0:
        vy = -vy * 0.75
    elif h > -100:
        vy += g * dt

    h += vy
    print(h, vy)

    t += dt 

请注意,时间步长的某些值 dt 不会发生收敛 - 如果遇到这种情况,完成条件或时间步长的比例应该是已调整。