0

我有以下 Python 代码:

import math

x = 0
y = 0

acceleration = 10
angle = 0

vx = 0
vy = 0

time = 10
for _ in range(time):
    vx += acceleration * math.cos(math.radians(angle))
    vy += -acceleration * math.sin(math.radians(angle))

    x += vx
    y += vy

print(x, y)

哪个输出:

550.0 0.0

这不是位移方程产生的结果。

(acceleration * time**2) / 2= 500

我究竟做错了什么?我想不花时间解决问题;假装它不存在。

4

2 回答 2

2

您想要实现的是找到速度随时间的精确积分,其中速度本身隐含地作为加速度的积分给出。您尝试通过可用的最简单方法来做到这一点:欧拉方法。累积误差是不可避免的。

除了 Euler 方法固有的错误(不精确)之外,您的实现还存在按顺序更新变量的错误。即:您将过去的位移与当前速度相结合 - 而不是与相应的过去速度相结合。您应该计算每个变量的新值并同时更新它们。例如像这样(从你的代码中省略常量):

import math                                                                                                                                                                                                        

acceleration = 10                                                                                                                                                                                                  
vx = 0                                                                                                                                                                                                             
x = 0                                                                                                                                                                                                              

for _ in range(10):                                                                                                                                                                                                
    new_x = x + vx                                                                                                                                                                                                 
    new_vx = vx + acceleration                                                                                                                                                                                     

    x = new_x                                                                                                                                                                                                      
    vx = new_vx                                                                                                                                                                                                    

print(x) # 450                                                                                                                                                                                                         

在您当前的设置(带有修复程序)中,模拟运行如下:

模拟 OP 的实现

您可以通过增加时间分辨率来获得更好的结果,例如通过将步长设为 0.1 而不是 1,您将获得:

在此处输入图像描述

如果您对更好的数值积分方法感兴趣,请关注维基百科到Runge-KuttaAdams-Bashfort

这是重现绘图的代码:

import numpy as np                                                                                                                                                                                                 
import matplotlib.pyplot as plt                                                                                                                                                                                    

acceleration = 10                                                                                                                                                                                                  

t0 = 0                                                                                                                                                                                                             
t1 = 10                                                                                                                                                                                                            
nb_steps = 11                                                                                                                                                                                                      

ts = np.linspace(t0, t1, num=nb_steps)                                                                                                                                                                             
vs = np.zeros_like(ts)                                                                                                                                                                                             
xs = np.zeros_like(ts)                                                                                                                                                                                             

vs[0] = 0                                                                                                                                                                                                          
xs[0] = 0                                                                                                                                                                                                          

true_xs = acceleration * ts ** 2 / 2                                                                                                                                                                               


for i, t in enumerate(ts):                                                                                                                                                                                         
    if i == 0:                                                                                                                                                                                                     
        continue # initial conditions are preset                                                                                                                                                                   

    delta_t = t - ts[i-1]                                                                                                                                                                                          
    vs[i] = vs[i-1] + acceleration * delta_t                                                                                                                                                                       
    xs[i] = xs[i-1] + vs[i-1] * delta_t                                                                                                                                                                            

plt.figure()                                                                                                                                                                                                       
plt.plot(ts, vs, label='velocity')                                                                                                                                                                                 
plt.plot(ts, xs, label='displacement-sim')                                                                                                                                                                         
plt.plot(ts, true_xs, label='displacement-true')                                                                                                                                                                   
plt.legend()                                                                                                                                                                                                       
plt.show()                                                                                                                                                                                                         
于 2020-02-12T07:43:47.430 回答
0

在您的情况下,xandy应该分别用vx初始和最终速度的平均值和更新vy

作为

如果您希望每个时间步都使用 x 和 y,您应该这样做,

import math

x = 0
y = 0

acceleration = 10
angle = 0

vx = 0
vy = 0

time = 10

vx = (vx + acceleration * math.cos(math.radians(angle))*time)/2 #average of velocity
vy = (vy  -acceleration * math.sin(math.radians(angle))*time)/2 #average of velocity

for _ in range(time):

  x += vx
  y += vy

  print(x, y)

于 2020-02-09T15:04:02.193 回答