Я создаю 2-мерную космическую игру, и мне нужно, чтобы космический корабль перехватывал планету. У меня есть рабочий код для пересечения прямой линии, но я не могу понять, как рассчитать расположение планет на круговой орбите.
Игра не является научно точной, поэтому меня не волнуют инерция, гравитация, эллиптические орбиты и т. Д.
Я знаю местоположение и скорость космических кораблей, а также орбиту и скорость планет
2d
mathematics
physics
Ausa
источник
источник
Ответы:
Аналитическое решение этого является сложным, но мы можем использовать бинарный поиск, чтобы найти решение с необходимой точностью.
Корабль может достичь ближайшей точки на орбите за время t_min :
Корабль может достичь ЛЮБОЙ точки на орбите за время, меньшее или равное t_max :
(Здесь, для простоты, я предполагаю, что корабль может двигаться сквозь солнце. Если вы хотите избежать этого, то вам, по крайней мере, в некоторых случаях нужно будет переключиться на неровные пути. «Целующие круги» могут выглядеть красиво и орбитально. механика-у, без изменения алгоритма более чем на постоянный коэффициент)
Если у нас короткий орбитальный период, мы могли бы улучшить эту верхнюю границу, выбрав
t_max
первый случай, послеt_min
которого планета приблизится к стартовой позиции корабля. Возьмите, какое из этих двух значенийt_max
меньше. Посмотрите этот ответ позже, чтобы узнать, почему это работает.Теперь мы можем использовать бинарный поиск между этими крайностями, t_min и t_max . Мы будем искать t-значение, которое возвращает ошибку, близкую к нулю:
(Используя эту конструкцию, error @ t_min> = 0 и error @ t_max <= 0, поэтому должен быть хотя бы один перехват с ошибкой = 0 для промежуточного значения t)
где для полноты функция положения что-то вроде ...
Обратите внимание, что если орбитальный период планеты очень короткий по сравнению со скоростью корабля, эта функция ошибок может несколько раз менять знаки на протяжении промежутка от t_min до t_max. Просто следите за самой ранней парой + ve & -ve, с которой вы столкнулись, и продолжайте поиск между ними, пока ошибка не станет достаточно близкой к нулю («достаточно близко», чувствительная к вашим юнитам и контексту игрового процесса. Квадрат половины длительности кадра может работать хорошо - это гарантирует, что перехват с точностью до кадра)
Как только вы добьетесь приятного минимизации ошибок t, вы можете просто указать кораблю на planet.positionAtTime (t) и сделать полный газ, будучи уверенным, что планета достигнет этой точки в то же время, что и вы.
Вы всегда можете найти решение в итерациях Log_2 ((2 * orbitRadius / ship.maxSpeed) / errorThreshold). Так, например, если мой корабль может пересечь орбиту за 60 кадров, и мне нужен точный перехват с точностью до одного кадра, мне потребуется около 6 итераций.
источник
Давайте не будем слишком усложнять это. Это не «идеальное» решение, но оно должно работать для большинства игр, и любые недостатки должны быть незаметны для игрока.
Это работает, потому что чем ближе космический корабль приближается, тем ниже становится ошибка. Таким образом, расчет со временем становится более стабильным.
Ошибка представляет собой разницу между вычисленным необходимым временем для достижения планеты (TimeNeeded) и фактическим временем, необходимым для достижения планеты (после учета новой TargetPoint).
источник
Давайте начнем с рассмотрения математики, стоящей за этой проблемой.
Шаг 1:
Нахождение пересечения между линией и формой - это просто вопрос вставки уравнения линии в уравнение формы, которая в данном случае является кругом.
Возьмите круг с центром c и радиусом r . Точка p находится на окружности, если
Квадратное расстояние можно переписать в виде точечного произведения ( http://en.wikipedia.org/wiki/Dot_product ).
которое является простым квадратным уравнением, и мы приходим к решению
Шаг 2:
Что мы можем сделать с этим? Что ж, теперь мы знаем расстояние, которое должен пройти корабль, и в какой точке он окажется!
Теперь осталось только рассчитать, где должна быть планета, когда корабль начнет приближаться к своей орбите. Это легко рассчитать с помощью так называемых полярных каудинатов ( http://mathworld.wolfram.com/PolarCoordinates.html )
Резюме
Выберите линию для своего корабля и запустите математику, чтобы увидеть, сталкивается ли она с орбитой планет. Если это так, рассчитайте время, которое потребуется, чтобы добраться до этой точки. Используйте это время, чтобы вернуться на орбиту из этой точки с планетой, чтобы вычислить, где должна быть планета, когда корабль начнет двигаться.
источник
Вот два «нестандартных» решения.
Вопрос в том, что с учетом того, что корабль движется по прямой линии с заданной скоростью, а планета движется по кругу с заданным радиусом с заданной угловой скоростью, а исходные позиции планеты и корабля определяют направление вектора движения корабля. должна быть прямая линия, чтобы построить курс перехвата.
Решение первое: опровергнуть предпосылку вопроса. Количество, которое «скользит» в вопросе - это угол. Вместо этого исправьте это. Направьте корабль прямо в центр орбиты.
Решение второе: вообще не делайте этого на автопилоте. Сделайте мини-игру, в которой игрок должен использовать двигатели, чтобы приблизиться к планете, и если они ударили по ней с слишком высокой относительной скоростью, они взорвутся, но у них также будет ограниченное топливо. Заставьте игрока научиться решать проблему перехвата!
источник
Положение планеты в пространстве и времени может быть параметризовано, например,
Это уравнение должно быть решено численно. У этого может быть много решений. Глядя на это, кажется, что всегда есть решение
источник
Вот часть решения. Я не успел закончить вовремя. Я попробую еще раз позже.
Если я правильно понимаю, у вас есть положение и скорость планеты, а также положение и скорость корабля. Вы хотите узнать направление движения корабля. Я предполагаю, что скорости корабля и планеты постоянны. Я также предполагаю, без ограничения общности, что корабль находится в (0,0); чтобы сделать это, вычтите положение корабля из положения планеты и добавьте положение корабля обратно к результату операции, описанной ниже.
К сожалению, без латекса я не могу отформатировать этот ответ очень хорошо, но мы попытаемся обойтись. Позволять:
s_s
= скорость корабля (s_s.x, s_s.y, также)s_a
= направление судна (угол движения, что мы хотим вычислить )p_p
= начальное положение планеты, глобальные координатыp_r
= расстояние планеты (радиус) от центра орбиты, полученное изp_p
p_a
= начальный угол планеты в радианах относительно центра орбитыp_s
= угловая скорость планеты (рад / с)t
= время до столкновения (это тоже нужно вычислить)Вот уравнения для положения двух тел, разбитых на составляющие:
Поскольку мы хотим
ship.x = planet.x
иship.y = planet.y
в какой-то моментt
мы получаем это уравнение (y
случай почти симметричный):Решение главного уравнения для s_a:
Подстановка этого во второе уравнение приводит к довольно ужасающему уравнению, которое Wolfram alpha не решит для меня . Может быть лучший способ сделать это, не используя полярные координаты. Если кто-то захочет попробовать этот метод, добро пожаловать в него; Я сделал это вики. В противном случае, вы можете отнести это в Math StackExchange .
источник
Я бы зафиксировал место, в котором нужно перехватить (выпустить круг на «исходящей» стороне орбиты.)
Теперь вам просто нужно отрегулировать скорость космического корабля, чтобы планета и корабль достигли этой точки одновременно.
Обратите внимание, что рандеву может быть за N орбит больше, в зависимости от того, как далеко находится корабль и как быстро планета вращается вокруг звезды.
Выберите N, которое со временем приближается к продолжительности путешествия корабля с текущей скоростью.
Затем ускорите или замедлите корабль, чтобы точно соответствовать отметке времени для этих N орбит.
Во всем этом фактический курс уже известен! Просто не скорость.
источник