Космические корабли в моей игре должны быть построены игроком с произвольным количеством движителей, прикрепленных где угодно с любым вращением. В настоящее время у меня есть грязный код для поворота корабля на заданный угол (ускорение и замедление).
Вот пример симметричного корабля, обращенного туда, куда указывает красная линия, которому говорят повернуть налево.
Однако, как вы можете себе представить, в зависимости от того, куда игрок поставил двигатели, иногда нежелательные линейные силы влияют на корабль. В этом случае корабль начинает двигаться вперед.
Я уточняю, можно ли найти максимальную тягу, которую может применить двигатель, чтобы не вызывать линейную скорость. (В приведенном выше случае этого не будет, поскольку нет ничего, что могло бы противодействовать силам задних движителей, а передние убивали друг друга).
До сих пор я придумал формулу для определения «эффективности поворота», например, сколько вращения вызывается относительно линейного движения.
a - вектор положения для двигателя a b - вектор положения для двигателя b v1 - сила от двигателя a v2 - сила от двигателя b
performanceDelta = a.cross (v1) / | v1 | - (a.cross (v1) + b.cross (v2)) / | v1 + v2 |
, в основном "a.cross (v1 * t) / | v1 |" Предполагается, что эффективность поворота. И затем мы вычитаем это из-за эффективности поворота движителей вместе взятых, чтобы посмотреть, стоит ли запуск нового движителя.
Проблема возникает, когда я понимаю, что двигатели не должны быть включены / выключены, но могут изменять их тягу от 0 до 1. И как это сделать, когда игрок хочет, чтобы корабль шел вперед. Конечно, должен быть баланс того, сколько вращаться / двигаться.
Я не специалист в области ракетостроения, поэтому я надеюсь, что найдется кто-нибудь, кто скажет мне, можно ли рассчитать таким образом дроссель каждого двигателя и дать мне толчок в правильном направлении.
Спасибо, что нашли время! / Ким
Ответы:
Я предполагаю, что у вас есть физически правильное движение для вашего корабля, иначе этот анализ не будет проведен. Вам нужно что-то сильнее, чем эффективность, чтобы правильно решить эту проблему.
Каждый движитель будет оказывать два влияния на движение корабля: линейное и угловое. Это можно рассмотреть независимо. Если подруливающее устройство создает силу
f
в направленииdir
и смещено от центра масс на векторr
(не геометрический центр или центр спрайта!), То влияние на линейную составляющую будет:Влияние на угловую скорость определяется моментом:
t
вектор силы (т. е. линейная тяга).tau
это скаляр со знаком, который при делении на момент инерции массы даст угловое ускорение. Важно, чтоdir
иr
оба находятся в одном координатном пространстве, т.е. оба в локальных координатах или оба в мировых координатах.Общее линейное ускорение корабля дается суммой
t
's' для каждого двигателя, деленной на массу корабля. Аналогично, угловое ускорение - это просто сумма моментов, деленная на момент инерции массы (который является другим скаляром). Корабль не повернет, если общий крутящий момент равен нулю. Точно так же он не будет двигаться, если общая тяга равна нулю. Напомним, крутящий момент является скалярным, но тяга (суммаt
's) является 2D вектором.Смысл этой экспозиции в том, что теперь мы можем написать нашу задачу в виде линейной программы . Скажем сначала, мы хотим, чтобы наш корабль вращался без движения . У нас есть переменная для каждого двигателя, $ x_1, x_2, ... $, которая представляет собой величину тяги, которую обеспечивает двигатель. Один набор ограничений:
где
fmax
максимальная сила для этого двигателя (это позволяет нам иметь более сильные или более слабые силы). Далее скажем, что оба равенства:Это кодирует ограничение, что мы не будем применять линейное ускорение, говоря, что общая тяга равна нулю (тяга является вектором, поэтому мы просто говорим, что каждая часть равна нулю).
Теперь мы хотим, чтобы наш корабль развернулся. Предположительно мы хотим сделать это как можно быстрее, поэтому мы хотим:
Решение этой
x_i
задачи при соблюдении указанных выше неравенств и равенств при максимальном суммировании, приведенном выше, даст нам желаемую тягу. Большинство языков программирования имеют для них доступную библиотеку LP. Просто поместите вышеупомянутую проблему в нее, и она даст ваш ответ.Подобная проблема позволит нам двигаться без поворота. Скажем, мы переписываем нашу задачу в систему координат, в которой мы хотим двигаться в положительном направлении х. Тогда ограничения:
С учетом того, что двигатели могут создавать тягу только в одном направлении, будут ограничения по типу вращений и линейным скоростям, которых вы сможете достичь. Это проявится как решение проблемы
0 = x_1 = x_2 = ... = x_n
, а это значит, что вы никогда не получите ничего. Чтобы смягчить это, я предлагаю добавить пару небольших, слабых (скажем, 5% или 10%) движителей для каждого игрока, расположенного под углом 45 градусов с обеих сторон. Это даст решению большую гибкость, поскольку их можно использовать для противодействия слабым вторичным воздействиям основных двигателей.Наконец, для более чем 100 движителей, решение для LP достаточно быстро, чтобы быть выполненным за кадр. Однако, поскольку решение не зависит от местоположения или текущего состояния, вы можете предварительно вычислить решение для каждой разумной входной комбинации контроллера всякий раз, когда изменяется форма (это включает в себя добавление не движителей, которые изменяют момент инерции или массу корабля, потому что тогда двигатели находятся в другом месте относительно центра масс!). Это 24 возможности (т.е. 8 направлений времени {вращение влево, вращение не влево, вращение вправо}).
источник
Sum_i
значит в этом контексте?Моей первой мыслью было чисто эмпирическое решение, которое заключается в том, чтобы смоделировать буровую установку в среде песочницы для различной степени тяги, чтобы определить, как она себя ведет. Вместо того, чтобы балансировать сложную математику в поиске детерминированного решения, вы можете достичь ее численно, например, с помощью метода Ньютона. Пример:
Диапазон для тяги составляет от 0 до 1000, где 1000 ALOT.
Шаг 1
Имитация с доверием (0 + 1000) / 2 = 500. Результат: слишком большое доверие
Шаг 2
Диапазон теперь от 0 до 500 Имитация с доверием (0 + 500) / 2 = 250. Результат: слишком большое доверие
Шаг 3
Диапазон теперь от 0 до 250 Имитация с доверием (0 + 250) / 2 = 125 Результат: слишком мало доверия
Шаг № 4
Теперь диапазон от 125 до 250. Имитация с доверием (125 + 250) /2=187.5. Результат - слишком большое доверие.
Шаг # 5 Диапазон теперь от 125 до 187,5. Имитация с доверием (125 + 187,5) /2=156.25 Результат - слишком мало доверия
Шаг № 6 Диапазон теперь 156,25–187,5 Диапазон ниже порогового значения 35, что означает, что это достаточно хорошая оценка
Окончательный результат = (187,5 + 156,25) / 2 = 171,875
источник