Odeint для движения снаряда - PullRequest
0 голосов
/ 28 октября 2019

Я составил график движения снаряда с учетом начальных условий.

Я пытаюсь сделать tmax зависимым от начальных условий, так что если вы измените начальные условия, tmax изменится на разумное значение. Во-вторых, как мне найти расстояние до удара, время полета и скорость при ударе. Все это будет зависеть от того, когда у станет ноль, но IDK, как использовать эту информацию. Вот мой кодСпасибо.

import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt

c=0.65   #Constant friction term
m=0.1    #Object's mass
g=9.81   #Gravitational acceleration
theta=50 #Angle
V0=10    #Initial Velocity
Vx0=np.cos(np.deg2rad(theta))*V0  #Calculates initial speed along the x-axis
Vy0=np.sin(np.deg2rad(theta))*V0  #Calculates initial speed along the y-axis

t0 = 0.0  #Initial time
tmax=1    #Final time
steps=20  #Number of time step
tAF = np.linspace(t0, tmax, steps)# Creates a 1-D array of time values

y0AF = [0.0, Vx0, 0.0, Vy0] #Initial condition for x-position, V along x, y-position, V along y 

def derivative(yAF,tF):     #Function which calculates the derivatives 
    Vx = yAF[1]             #Element in array for the velocity along x axis
    Vy = yAF[3]             #Element in array for the velocity along y axis
    return [Vx, -c*Vx/m, Vy, -g-c*Vy/m]  #Function outputs [dx/dt, dVx/dt, dy/dt, dVy/dt]

yM = odeint(derivative, y0AF, tAF)       #Array with the solution for the differential equation

plt.plot(yM[:,0],yM[:,2], '.')  #Plots y over x
plt.xlabel('x-distance'), plt.ylabel('y-distance')
plt.show()
MAXy=np.amax(yM[:,2])
print('Maximum height reached is',MAXy)

1 Ответ

0 голосов
/ 28 октября 2019

Вместо того, чтобы пытаться интегрировать все дифференциальные уравнения за одно использование odeint(), вы можете использовать несколько шагов, изменяя начальные условия для продолжения интеграции, например, заменяя строку:

yM = odeint(derivative, y0AF, tAF)   

... с чем-то вроде:

y = np.array([y0AF])
tLargeStep = 0.3
i = 0

while 1:
    tAF = np.linspace(i*tLargeStep, (i+1)*tLargeStep, steps)
    yM = odeint(derivative, y[-1,:], tAF)
    y = np.concatenate((y,yM[1:,:]))
    if y[-1,2] < 0:
        break
    i += 1

plt.plot(y[:,0],y[:,2], '.')  #Plots y over x
plt.xlabel('x-distance'), plt.ylabel('y-distance')
plt.show()

В этом случае интеграция будет продолжаться большой шаг за шагом, пока y не станет меньше нуля в конце большого шага.

Получив данные в y, вы можете использовать numpy.interpolate() на этих данных, чтобы найти расстояние до удара, время полета и скорость при ударе.

В качестве альтернативы, если вы используете scipy.integrate.solve_ivp()вместо odeint(), solve_ivp() позволяет указать отслеживаемые события и сделать некоторые из этих событий терминальными, т. е. заставить решатель прекратить вычисления, когда происходит указанное событие.

...