При отсутствии дополнительной информации мы можем предположить, что на космический корабль действуют 3 силы, которые в конечном итоге диктуют его траекторию:
- " импульсов ": [пользователь / управляемая программой] сила.
Пользователь (или программа), кажется, имеет полный контроль над этим, то есть он контролирует направление импульса и его тягу (вероятно, в диапазоне от 0 до максимума)
- какая-то внешняя сила : называйте это гравитацией, как угодно ...
Такая сила может быть вызвана несколькими источниками, но мы просто заинтересованы в результирующей объединенной силе: в данное время и пространство эта внешняя сила действует на корабль с заданной силой и направлением. Пользователь / программа не контролирует их.
- инерция : это связано с текущей скоростью и направлением корабля. Эта сила обычно заставляет корабль продолжать движение в текущем направлении со своей текущей скоростью. Могут быть и другие параметры [космического возраста], управляющие инерцией, но, как правило, они пропорциональны скорости и массе корабля (Интуитивно легче остановить корабль, если его текущая скорость меньше и / или если его масса меньше)
Очевидно, что пользователь / программа контролирует (в определенных пределах) первую силу.
Непонятно, из вопроса, является ли проблема под рукой:
- [Задача A] написать программу, которая обнаруживает динамику системы (и / или адаптируется к изменениям этой динамики).
или ..
- [Проблема B], чтобы предложить модель-формулу, которая может быть использована для вычисления объединенной силы, в конечном итоге прикладываемой к кораблю: «взвешенная» сумма импульса, управляемого пользователем, и двух других, управляемых системой / физикой силы.
Последний вопрос, проблема B, объясняется более легко и лаконично, поэтому давайте предложим следующую модель:
Constant Parameters:
ExternalForceX = strength of the external force in the X direction
ExternalForceY = id. Y direction
MassOfShip = coeficient controlling
Variable Parameters:
ImpulseAngle = direction of impulse
ImpulseThrust = force of thrust
Formula:
Vx[new] = (cos(ImpulseAngle) * ImpulseThrust) + ExternalForceX + (MassOfShip * Vx[current])
Vy[new] = (sin(ImpulseAngle) * ImpulseThrust) + ExternalForceY + (MassOfShip * Vy[current])
Обратите внимание, что приведенная выше модель предполагает постоянную внешнюю силу (постоянную как по силе, так и по направлению); то есть: сродни гравитационному полю, относительно удаленному от отображаемой области (точно так же как, скажем, гравитация Земли, рассматриваемая в пределах футбольного поля). Если масштаб отображаемой области велик относительно источника (источников) внешних сил, средний член приведенных выше формул должен быть изменен таким образом, чтобы он включал: тригонометрический коэффициент, основанный на угле между центром источника и током. положение и / или [обратно] пропорциональный коэффициент, основанный на расстоянии между центром источника и текущей позицией.
Точно так же предполагается, что масса Корабля остается постоянной, она вполне может быть переменной, основанной, скажем, на массе Корабля в пустом состоянии, к которой масса топлива удаляется / добавляется по ходу игры.
Теперь ... Все вышеизложенное предполагает, что динамика системы контролируется разработчиком игры: по сути, выбирая набор значений для упомянутого параметра и, возможно, добавляя немного сложности в математику формулы (а также обеспечение правильного масштабирования, чтобы вообще «удерживать» корабль в зоне отображения).
Что, если вместо этого динамика системы была легко запрограммирована в игру (и предполагается, что она скрыта / случайна), и задача сейчас состоит в том, чтобы написать программу, которая будет постепенно определять направление и значение тяги импульсов для движения. корабль к месту назначения, таким образом, чтобы его скорость на цели была как можно ближе к getTargetVelocity ()? Это «проблема А».
Этот тип проблемы может быть решен с помощью ПИД-регулятора . В двух словах, такой контроллер «решает», какое количество действий (в случае этой игры = какой импульсный угол и количество тяги применить), на основе трех взвешенных факторов, которые в общих чертах определены ниже:
- как далеко мы находимся от текущих значений от «уставки»: это P = пропорциональная часть PID
- как быстро мы приближаемся к «заданному значению»: это D = производная часть PID
- как долго и на сколько мы отошли от «заданного значения»: это I = Интегральная часть PID
Менее сложный контроллер может, например, использовать только пропорциональный коэффициент. Это может привести к колебаниям, иногда с большой амплитудой по обе стороны от заданного значения («Я на X единиц от того места, где я должен быть: позвольте мне дернуть руль и нажать на газ»). Такое превышение заданного значения сдерживается производным фактором («Да, я все еще не там, где должен быть, но прогресс, достигнутый с момента последней проверки, очень велик: лучше немного замедлиться») , Наконец, Интегральная часть принимает во внимание тот факт, что при прочих равных условиях в отношении комбинированной Пропорциональной и Производной части, было бы целесообразно использовать действие меньшего или большего размера в зависимости от того, были ли мы «в стороне» в течение длительного времени или нет и, конечно, мы все это время были не в курсе (например, «в последнее время мы довольно близко следили за тем, где мы должны быть, нет смысла делать необдуманные шаги»)
Мы можем обсудить детали реализации ПИД-контроллеров для конкретных потребностей игры космического корабля, если это действительно то, что требуется. Идея заключалась в том, чтобы дать представление о том, что можно сделать.