Ускорение точки в двух измерениях - PullRequest
0 голосов
/ 09 февраля 2020

У меня есть следующий 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

Что я делаю не так? Я хотел бы решить проблему, не используя время; притворись, что его не существует.

Ответы [ 2 ]

2 голосов
/ 12 февраля 2020

То, что вы пытаетесь достичь, - это найти точный интеграл скорости во времени, где сама скорость дается неявно как интеграл ускорения. И вы пытаетесь сделать это самым простым из доступных методов: метод Эйлера . Накапливающиеся неточности неизбежны.

Помимо ошибок (неточностей), присущих методу Эйлера, ваша реализация имеет ошибку обновления переменных последовательным образом. То есть: вы комбинируете смещение в прошлом с текущей скоростью, а не с соответствующей прошлой скоростью. Вы должны вычислить новые значения каждой переменной и обновлять их одновременно. Например, как это (исключая константы из вашего кода):

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                                                                                                                                                                                                         

В вашей текущей настройке (с исправлением) симуляция работает так:

Simulation of the OP's implementation

Вы можете получить лучший результат, увеличив разрешение по времени, например, сделав шаги 0,1 вместо 1, вы получите:

enter image description here

Если вы заинтересованы в улучшении методов численного интегрирования, следуйте википедии по Рунге-Кутта или Адамс-Башфорт .

Вот код для воспроизведения участки:

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()                                                                                                                                                                                                         
0 голосов
/ 09 февраля 2020

В вашем случае x и y должны быть обновлены со средним значением 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)

...