Вместо того, чтобы пытаться интегрировать все дифференциальные уравнения за одно использование 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()
позволяет указать отслеживаемые события и сделать некоторые из этих событий терминальными, т. е. заставить решатель прекратить вычисления, когда происходит указанное событие.