Открыть мобильное меню

Алгоритм расчёта траектории брошенного предмета с учётом гравитации, массы, ветра и сопротивления.

траектория полёта предмета

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

Исходные данные объекта:

objX, objY - координаты объекта от которых начинается расчёт траектории полёта.
m - масса объекта.
Fs - сила сопротивления объекта.
a - ускорение во время броска. Не путать с силой броска!
angle - угол от 0 до 90 под которым брошен предмет относительно оси X.

Исходные величины мира:
Fg - сила гравитации.
Fw - сила ветра.

Предварительный расчёт

Выполняется 1 раз, после того как сработал скрипт броска объекта:
F - общая сила предмета = m * a. Не стоит забывать, что а это ускорение, поэтому чем больше масса, тем больше сила объекта, соответственно он пролетит большее расстояние, чем объект с меньшей массой, при одинаковом ускорении и силах противодействия.

alfa = angle
beta = 90 - alfa

Важно понять, что объект с силой F во время движения в двух плоскостях делит общую силу на две, одна из которых направлена вверх vF, а другая в сторону по направлению движения hF.

Далее нужно отнять от направленной вверх силы vF силу гравитации Fg и вертикальную силу сопротивления viFs, а от силы hF отнять силу ветра Fw и горизонтальную силу сопротивления hiFs.

Как я уже упоминал выше, с данными расчётами в космос не улетишь, так как внимание на то, что объект может иметь разную силу сопротивления в зависимости от того какая площадь взаимодействует в данный момент, здесь не учитываю (хотя это можно добавить по необходимости).
Данный вариант подразумевает, что в любом направлении движения и при любом повороте объекта, сопротивление одинаковое, т.е. некая точка.

Чтобы распределить силы, я использовал отношение углов к направлению каждой силы:
hiFs (горизонтальная сила сопротивления) = Fs / 90 * beta
viFs (вертикальная сила сопротивления) = Fs / 90 * alfa
hF = beta * F / 90 - ( hiFs + Fw )
vF = alfa * F / 90 - ( viFs + Fg )

Перерасчёт координат каждый кадр

Узнаём горизонтальную силу сопротивления при новом угле beta:
hiFs = Fs / 90 * beta
Отнимаем hiFs и силу ветра от горизонтальной силы объекта hF которая сохранилась с прошлого кадра
hF -= hiFs + Fw

Нужна временная переменная nextObjX с новой координатой объекта по оси X, для дальнейшего расчёта нового угла
nextObjX = objX + hF / m, где hF / m = a, ускорение, текущая скорость по оси X. В моём случае это и расстояние пройденное по оси X, т.к. время = 1 кадр

Аналогично рассчитывается vF и nextObjY с новой координатой объекта по оси Y
viFs = Fs / 90 * alfa
vF -= viFs + Fg
nextObjY = objY + vF / m

Далее находим новые углы alfa и beta
Переменная dist это расстояние от текущей координаты объекта до новой
dist = Math.sqrt( (nextObjX - objX) * (nextObjX - objX) + (nextObjY - objY) * (nextObjY - objY) )
alfa = Math.round( Math.acos((nextObjX - objX) / dist) / Math.PI * 180 )
beta = 90 - alfa

objX = nextObjX
objY = nextObjY

Тех кто программирует на AS3, могут скачать класс FlightPath as или zip.