Вы должны рассчитать каждое местоположение на основе суммы сил в данный момент времени. Для этого лучше начать с расчета чистой силы в любое время и использовать ее для расчета ускорения, скорости, а затем положения. Для следующих расчетов предполагается, что плавучесть и сила тяжести являются постоянными (что в действительности не соответствует действительности, но эффект их изменчивости незначителен в этом случае), также предполагается, что начальное положение равно (0,0)
, хотя это может быть тривиально меняется на любую начальную позицию.
F_x = tau_x
F_y = tau_y + bouyancy + gravity
Где tau_x
и tau_y
- силы сопротивления в направлениях x
и y
соответственно. Скорости v_x
и v_y
тогда определяются как
v_x = v_x + (F_x / (2 * m)) * dt
v_y = v_y + (F_y / (2 * m)) * dt
Таким образом, позиции x
и y
, r_x
и r_y
в любое время t
задаются суммой
r_x = r_x + v_x * dt
r_y = r_y + v_y * dt
В обоих случаях это должно быть оценено от 0
до t
для некоторого dt
, где dt * n = t
, если n
- количество шагов суммирования.
r_x = r_x + V_i * np.cos(theta) * dt + (F_x / (2 * m)) * dt**2
r_y = r_y + V_i * np.sin(theta) * dt + (F_y / (2 * m)) * dt**2
Весь расчет может быть выполнен в две строки,
r_x = r_x + V_i * np.cos(theta) * dt + (tau_x / (2 * m)) * dt**2
r_y = r_y + V_i * np.sin(theta) * dt + ((tau_y + bouyancy + gravity) / (2 * m)) * dt**2
За исключением того, что v_x
и v_y
требуют обновления на каждом временном шаге. Чтобы повторить это и вычислить позиции x
и y
в диапазоне времен, вы можете просто следовать приведенному ниже (отредактированному) примеру.
Следующий код включает исправления для предотвращения отрицательных позиций y, поскольку данное значение g
предназначено для поверхности или Марса. Я полагаю, что это уместно - когда вы нажмете ноль y
и попытаетесь продолжить движение, вы можете в конечном итоге с быстрой незапланированной разборкой, как мы, физики, называем это.
Редактировать
В ответ на отредактированный вопрос следующий пример был изменен для отображения всех трех запрошенных случаев: гравитация, гравитация плюс сопротивление и гравитация плюс сопротивление и плавучесть. Код настройки графика также был добавлен
Полный пример (отредактировано)
import numpy as np
import matplotlib.pyplot as plt
def projectile(V_initial, theta, bouyancy=True, drag=True):
g = 9.81
m = 1
C = 0.47
r = 0.5
S = np.pi*pow(r, 2)
ro_mars = 0.0175
time = np.linspace(0, 100, 10000)
tof = 0.0
dt = time[1] - time[0]
bouy = ro_mars*g*(4/3*np.pi*pow(r, 3))
gravity = -g * m
V_ix = V_initial * np.cos(theta)
V_iy = V_initial * np.sin(theta)
v_x = V_ix
v_y = V_iy
r_x = 0.0
r_y = 0.0
r_xs = list()
r_ys = list()
r_xs.append(r_x)
r_ys.append(r_y)
# This gets a bit 'hand-wavy' but as dt -> 0 it approaches the analytical solution.
# Just make sure you use sufficiently small dt (dt is change in time between steps)
for t in time:
F_x = 0.0
F_y = 0.0
if (bouyancy == True):
F_y = F_y + bouy
if (drag == True):
F_y = F_y - 0.5*C*S*ro_mars*pow(v_y, 2)
F_x = F_x - 0.5*C*S*ro_mars*pow(v_x, 2) * np.sign(v_y)
F_y = F_y + gravity
r_x = r_x + v_x * dt + (F_x / (2 * m)) * dt**2
r_y = r_y + v_y * dt + (F_y / (2 * m)) * dt**2
v_x = v_x + (F_x / m) * dt
v_y = v_y + (F_y / m) * dt
if (r_y >= 0.0):
r_xs.append(r_x)
r_ys.append(r_y)
else:
tof = t
r_xs.append(r_x)
r_ys.append(r_y)
break
return r_xs, r_ys, tof
v = 30
theta = np.pi/4
fig = plt.figure(figsize=(8,4), dpi=300)
r_xs, r_ys, tof = projectile(v, theta, True, True)
plt.plot(r_xs, r_ys, 'g:', label="Gravity, Buoyancy, and Drag")
r_xs, r_ys, tof = projectile(v, theta, False, True)
plt.plot(r_xs, r_ys, 'b:', label="Gravity and Drag")
r_xs, r_ys, tof = projectile(v, theta, False, False)
plt.plot(r_xs, r_ys, 'k:', label="Gravity")
plt.title("Trajectory", fontsize=14)
plt.xlabel("Displacement in x-direction (m)")
plt.ylabel("Displacement in y-direction (m)")
plt.ylim(bottom=0.0)
plt.legend()
plt.show()
![image](https://i.stack.imgur.com/Qb8Ap.png)
Обратите внимание, что это сохраняет и возвращает время пролета в переменной tof
.