在二维中加速一个点

Accelerating a point in two dimensions

我有以下 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

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

在您的情况下,xy 应更新为 vx 初始和最终的平均值 velocity 和 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)

您要实现的是找到速度随时间的精确积分,其中速度本身隐含地作为加速度的积分给出。然后您尝试使用最简单的可用方法:Euler method。错误累积在所难免。

除了 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                                                                                                                                                                                                         

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

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

如果您对更好的数值积分方法感兴趣,请关注维基百科 Runge-Kutta or Adams-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()