Сопротивление воздуха: когда аналитика бессильна
Добавь сопротивление воздуха — и красивая парабола превращается в задачу, которую решает только компьютер.
Сила сопротивления воздуха при больших скоростях квадратична: она направлена против скорости и пропорциональна её квадрату.
Модель силы сопротивления
На умеренных и высоких скоростях сила трения о воздух хорошо описывается квадратичным законом. В векторном виде она направлена против вектора скорости $\vec v$:
$$\vec F_{\text{c}} = -b\,|\vec v|\,\vec v,$$
где $b$ объединяет плотность воздуха, площадь сечения и коэффициент формы тела. Покомпонентно для 2D, поделив на массу, ускорение от сопротивления равно $-b\,|\vec v|\,v_x$ по горизонтали и $-b\,|\vec v|\,v_y$ по вертикали (плюс гравитация $-g$ по $y$). Множитель $|\vec v| = \sqrt{v_x^2 + v_y^2}$ связывает оси: теперь горизонталь «знает» про вертикаль через общую скорость. Именно поэтому простой формулы дальности больше нет.
Симуляция с сопротивлением
Бросим тело при $v_0 = 30$ м/с и сравним дальность без трения ($b = 0$) и с трением ($b = 0.01$) для разных углов. Точку приземления найдём линейной интерполяцией между последними двумя шагами.
import math
def land_x(v0, ang_deg, b, dt=0.005):
ang = math.radians(ang_deg)
x = y = 0.0
vx = v0*math.cos(ang); vy = v0*math.sin(ang)
g = 9.8
while True:
s = math.hypot(vx, vy)
ax = -b*s*vx; ay = -g - b*s*vy
vx += ax*dt; vy += ay*dt
xn = x + vx*dt; yn = y + vy*dt
if yn < 0:
frac = y/(y - yn) # доля шага до земли
return x + frac*(xn - x)
x, y = xn, yn
print("Без сопротивления (b=0):")
for ang in (30, 40, 45, 50, 60):
print(f" угол {ang}° дальность {land_x(30, ang, 0.0):6.2f} м")
print("С сопротивлением (b=0.01):")
best_a, best_r = 0, 0.0
for ang in (30, 40, 45, 50, 60):
r = land_x(30, ang, 0.01)
print(f" угол {ang}° дальность {r:6.2f} м")
if r > best_r:
best_r, best_a = r, ang
print(f"Лучший угол с сопротивлением: {best_a}°")
Вывод:
Без сопротивления (b=0): угол 30° дальность 79.40 м угол 40° дальность 90.33 м угол 45° дальность 91.73 м угол 50° дальность 90.35 м угол 60° дальность 79.46 м С сопротивлением (b=0.01): угол 30° дальность 52.49 м угол 40° дальность 56.03 м угол 45° дальность 55.68 м угол 50° дальность 54.01 м угол 60° дальность 46.83 м Лучший угол с сопротивлением: 40°
Без трения максимум честно стоит на $45°$. А с сопротивлением картина меняется: оптимум смещается к $40°$, и вся дальность заметно падает ($56$ против $92$ метров). Физический смысл: крутая траектория дольше держит тело в воздухе, где трение успевает съесть больше скорости, поэтому выгоднее бросать чуть положе. Этот эффект — реальный, его учитывают в баллистике и спорте (например, оптимальный угол метания ядра меньше $45°$).
Как работает под капотом
Мы использовали интерполяцию приземления: тело почти никогда не оказывается ровно на $y = 0$ в конце шага, поэтому мы берём долю $\frac{y}{y - y_{\text{нов}}}$ последнего шага, на которой пересекли землю, и линейно оцениваем точку касания. Это типичный приём обнаружения события (event detection) в симуляциях: грубый шаг плюс точная интерполяция момента. Без него дальность «прыгала» бы на размер шага. Шаг $\Delta t = 0.005$ выбран маленьким, чтобы квадратичное сопротивление считалось точно: при больших шагах быстрый старт полёта моделируется грубо.
Частые ошибки
- Раскладывать сопротивление по осям без общей скорости. Сила зависит от $|\vec v|$; нельзя считать оси по отдельности, как при свободном полёте.
- Брать точку приземления как координату последнего шага. Без интерполяции дальность завышается на случайную долю шага.
- Ожидать оптимум на $45°$. С сопротивлением он смещается ниже; $45°$ — миф «идеального вакуума».
Итог
- Квадратичное сопротивление $\vec F_c = -b|\vec v|\vec v$ связывает оси через $|\vec v|$.
- Аналитической дальности нет — только численная симуляция.
- С трением дальность падает, а оптимальный угол смещается ниже $45°$.
- Точку приземления находят интерполяцией последнего шага (event detection).