看起来您正在尝试执行欧拉算法并且在循环中有点混淆。这是我认为它应该看起来的样子(我假设这是为了游戏而不是家庭作业......如果是为了家庭作业,你应该清楚地说明这一点,所以我们不会给出完整的答案,就像我在这里做的那样.)
这个例子是一个弹簧上的球,我认为你的目标是。我就是这个例子,我的初始条件是沿 x-z 轴对角抛出,并且我还包括重力(如果您不打算使用向量,则可以将所有向量替换为标量,例如 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 循环在时间步上循环(并且向量上的所有循环都是由 numpy 广播处理的,例如 f = -k*x+gravity,还有什么更容易的?)。另请注意,首先设置力,然后我们沿着导数积分链向下工作,然后回到顶部并再次从力开始。 (你说得对,这有点不对称,实际上我们应该同时更新它们,或者类似的东西,这是欧拉方法的缺陷,但它对于小时间步长来说足够好。)
这就是情节的样子......球按预期摆动
编辑:澄清您的问题:基本上,您的代码问题不是您暗示的“启动功能”的问题;相反,您的代码以错误的方式解决了问题,因此您需要修复该方法。看起来您正在尝试迭代每个函数内的时间步。 这是不正确的!相反,您需要通过时间步进行包络迭代,并且对于每个时间步,更新所使用的每个变量的当前状态在计算中在那个时间步。您可以将此更新编写为单独的函数,或者例如,您可以像我一样内联执行它。但是在每个变量计算函数中迭代时间步是没有意义的。相反,为了让您的示例有意义,force、velocity 和其他函数应该在当前时间步具有输入内容,并返回对该变量状态的更新以在下一个时间步中使用。看看我的例子是如何做到的:它只是循环遍历时间步和 within 每个时间步循环它按顺序更新所有变量,将每个更新的变量基于在它之前更新的变量 当前时间步长。