Похоже, вы пытаетесь использовать алгоритм Эйлера и немного запутываетесь в цикле. Вот как я думаю, это должно выглядеть (и я предполагаю, что это для игры, а не для домашнего задания ... если это для домашнего задания, вы должны четко заявить об этом, чтобы мы не дали полный ответ, как я делаю здесь .)
Этот пример для мяча на пружине, к которому, я думаю, вы стремитесь. Я являюсь примером, мои начальные условия - бросать по диагонали вдоль оси xz, и я также включил гравитацию (если вы не намеревались использовать векторы, вы можете просто заменить все векторные величины скалярами, например, t, x , v = 0, 0, 2; и т. д.)
from numpy import *
# set the start conditions, etc.
n_timesteps = 100
dt, m, k = .1, 1., 2. # timestep, mass, spring-const (I'll write the equations correctly so the units make sense)
t, x, v = 0., array([0.,0.,0.]), array([2., 0., 2.]) # initial values
gravity = array([0., 0., -9.8]) # to make the problem a little more interesting
result = zeros((4, n_timesteps))
# run the simulation, looping through the timesteps
for n in range(n_timesteps):
# do the calculation
f = -k*x + gravity
a = f/m
v += a*dt
x += v*dt
# store the results
t += dt # just for easy record keeping
result[0,n] = t
result[1:4, n] = x
Обратите внимание, что цикл for выполняет циклы по временным шагам (а все циклы по векторам обрабатываются с помощью широковещательной трансляции, например, f = -k * x + gravity, что может быть проще?) Также обратите внимание, что сначала устанавливается сила, а затем мы проходим по цепочке интегрирования производных, затем возвращаемся к вершине и снова начинаем с силы. (Вы правы, что это немного асимметрично, и на самом деле мы должны обновлять их все одновременно или что-то в этом роде, и это недостаток метода Эйлера, но он работает достаточно хорошо для небольших временных шагов.)
Вот как выглядят графики ... шар колеблется, как и ожидалось
Редактировать : Чтобы прояснить ваш вопрос: по сути, проблема вашего кода не в том, что вы подразумеваете «запуск функций»; вместо этого ваш код подходит к проблеме неправильно, поэтому вам нужно исправить этот подход. Похоже, вы пытаетесь перебрать свои временные шаги внутри каждой функции. Это неверно! Вместо этого вам нужно выполнить итерацию обтекания через временные шаги, и для каждого временного шага обновлять состояние current каждой переменной, используемой в расчете на этом шаге . Вы можете написать это обновление как отдельную функцию или, например, вы можете сделать это встроенным, как я. Но нет смысла повторять временные шаги в каждой функции вычисления переменной. Вместо этого, чтобы ваш пример имел смысл, force
, velocity
и другие функции должны иметь в качестве входных данных вещи на текущем временном шаге и возвращать обновление состояния этой переменной, которое будет использоваться на следующем временном шаге. Посмотрите, как мой пример делает это: он просто циклически перебирает временные шаги и в пределах каждого цикла временного шага, он последовательно обновляет все переменные, основывая каждую обновленную переменную на переменных, которые были обновлены непосредственно перед ней в этом текущем * 1030 временный шаг *.