这是我在这里的第一篇文章。我正在尝试学习python代码。我使用乌龟模块制作了一个程序,该程序模拟遭受非弹性碰撞的弹跳球,以使每次弹跳的最大高度变小。直到球在很短的高度跳动并且停止跳动以使球以恒定的(小)速度向下移动时,它才可以正常工作-这显然不是所期望的。
“地板”是在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
指的是重力,如果不是,那么您真的应该考虑给它起另一个名字)。另一个问题是,即使进行了更正,仅当abs(vy) <= 0.000000000000000000001
小于g * dt
时,才能满足0.000000000000000000001 / 0.75
的完成条件,否则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
在前一种情况下,可以保证收敛(球will停止),在后一种情况下,则不能保证(它可能摆动ad infinitum)。由于前者保证收敛,因此通常更可取-但并非完全现实。
最现实的解决方案是将两者结合起来,即
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
的某些值不会发生收敛-如果遇到这种情况,应调整完成条件的标度或时间步长。