Как рассчитать вектор перехвата?

11

Имеется двумерное пространство и 1 дружественный космический корабль, стоящий на месте, один враг НЕ движется прямо к дружественному кораблю с известными фактическим положением, скоростью и направлением.

Дружелюбный корабль хочет попасть на полигон, чтобы сразиться с противником.

На самом деле я устанавливаю только прямой вектор фактической позиции движущегося корабля и пересчитываю его каждый кадр, в результате чего получается некая «круглая» траектория полета.

Что я хочу, так это установить прямой и прямой путь к тому положению, которое будет (предположительно) у противника при достижении дальности стрельбы, при условии, что противник не изменит курс до тех пор.

В качестве первой и «простой» реализации было бы достаточно, если бы мы предположили, что друг может ускориться от 0 до max за мгновение.

Предпочтительной реализацией будет та, которая учитывает возможности ускорения друга и знает, когда перехват невозможен из-за скорости. Он должен работать на любой стартовой скорости, а не только стоять на месте. Плюсом было бы, если бы он даже рассматривал торможение (сражение на скорости света очень неэффективно в данной вселенной)

NobbZ
источник

Ответы:

5

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

Vector totarget =  target.position - tower.position;

float a = Vector.Dot(target.velocity, target.velocity) - (bullet.velocity * bullet.velocity);
float b = 2 * Vector.Dot(target.velocity, totarget);
float c = Vector.Dot(totarget, totarget);

float p = -b / (2 * a);
float q = (float)Math.Sqrt((b * b) - 4 * a * c) / (2 * a);

float t1 = p - q;
float t2 = p + q;
float t;

if (t1 > t2 && t2 > 0)
{
    t = t2;
}
else
{
    t = t1;
}

Vector aimSpot = target.position + target.velocity * t;
Vector bulletPath = aimSpot - tower.position;
float timeToImpact = bulletPath.Length() / bullet.speed;//speed must be in units per second

Я обнаружил, что это работает так хорошо, что мне не нужно было обнаруживать столкновения для выстрела ... Я мог рассчитывать на каждый выстрел, попавший в глаз быка, независимо от расстояния / направления / скорости цели, пока эти факторы оставались неизменными.

Стив Н
источник
Из вашего описания это, кажется, то, что я ищу, по крайней мере, простой способ, предполагающий мгновенное ускорение до максимальной скорости. Я поближе посмотрю на это вечером. Правильно ли я полагаю, что Vector.Dot возвращает точечный продукт векторов?
NobbZ
Хммм ... Я сделал это в ruby ​​сейчас, но, похоже, что-то не так. Каждый раз, когда я пытаюсь, возникает исключение, потому что выражение в sqrt оценивается как нечто отрицательное и, следовательно, выходит за пределы. Как я могу справиться с этим. Извините за вопрос, но я могу использовать только это, но не понимаю здесь, пока кто-то не даст мне совет.
NobbZ
Пример был из этой книги: amazon.com/…
Стив Х
1
Не знаю, поможет ли это, но вот код Python, который выполняет то же самое. moddb.com/mods/wicmw/tutorials/...
Steve H
Хорошо, я до сих пор не понимаю отверстие математики позади, но ТНХ для кода питона, документация сказала мне, что если есть значение Negativ внутри SQRT, то мой друг замедляться , чтобы догнать. После настройки тестовых значений я получаю некоторые результаты. Спасибо за вашу помощь.
NobbZ
6

Я предлагаю вам взглянуть на рулевое поведение. Особенно погоня . Источник-код можно найти в OpenSteer реализации или посмотреть книгу , как « Программирование игр АИ примером » (ISBN 13: 978-1556220784)

bummzack
источник
Погоня, кажется, нуждается в знании о цели и направляется к ней, но я на самом деле не знаю цель. Я знаю , где противник сейчас, я знаю , что его скорость и направление. Теперь я хочу знать , в каком направлении он должен идти на перехват врага на пути к своей цели как можно быстрее и как можно быстрее. Как упоминалось ранее, ускорение может быть сначала проигнорировано, это даже сэкономило бы большую часть времени обработки по сравнению с реальной версией ... С новой моделью мне приходится пересчитывать только тогда, когда противник запускает событие "размена курса", а не для каждого " hasmoved "- событие, как я это делаю сейчас.
NobbZ
Да, то, что вы описываете, это преследование. Он не знает цель .. он делает прогноз, основываясь на текущем местоположении, скорости и направлении
движения
Тогда я неправильно понял описание, завтра я посмотрю поближе.
NobbZ
Я только что закончил читать документ несколько минут назад, преследование - это НЕ то, что я ищу. Это похоже на мою фактическую реализацию, за исключением того, что она нацелена на позицию следующего кадра, мне все еще приходится пересчитывать новый курс каждый кадр, и курс приводит к некоторой кривой. Но я хочу, чтобы прямая линия предполагала, что противник не меняет скорость или курс, пока оба не встретятся. Если это все еще не ясно, я пытаюсь нарисовать то, что я хочу после работы. Но все равно спасибо за ссылки. Я думаю, что я могу использовать это где-то еще в проекте.
NobbZ
@NobbZ Извините, мой ответ не помог. Возможно, вам следует соответствующим образом отредактировать свой вопрос, потому что такие высказывания, как: «Я знаю, что в случае изменения скорости или хода врага каждый расчет должен повторяться», могут вводить в заблуждение. "преследование" рулевого поведения.
bummzack