Проблема в том, что ваше условие завершения никогда не выполняется, возможно, потому, что вы добавляете ускорение к скорости (при условии, что 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
В первом случае конвергенция гарантирована (шар остановится остановится), во втором - нет (он может колебаться до бесконечности *) 1019 *). Поскольку первое гарантирует конвергенцию, это, как правило, предпочтительнее - но не полностью реализуем c.
Наиболее реалистичное решение c состоит в том, чтобы объединить оба, т. Е.
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
, для которых сходимость не будет происходит - если встречается такой случай, необходимо скорректировать масштаб условия завершения или шаг по времени.