Для тех из вас, кто помнит Descent Freespace, у него была хорошая функция, позволяющая вам прицелиться в противника при стрельбе из самонаводящихся ракет или лазеров: он показал перекрестие перед преследуемым вами кораблем, указывающее, куда стрелять, чтобы поразить движущееся цель.
Я попытался использовать ответ из /programming/4107403/ai-algorithm-to-shoot-at-a-target-in-a-2d-game?lq=1, но это для 2D, поэтому я попытался адаптируя это.
Сначала я разложил вычисление, чтобы найти точку пересечения для плоскости XoZ, сохранил координаты x и z, а затем решил точку пересечения для плоскости XoY и добавил координату y к окончательному xyz, который я затем преобразовал в пространство клипов, и поместил в них текстуру. координаты. Но, конечно, это не работает так, как должно, иначе я бы не отправил вопрос.
Из того, что я заметил, после нахождения x в плоскости XoZ и в XoY x не совпадает, поэтому что-то должно быть не так.
float a = ENG_Math.sqr(targetVelocity.x) + ENG_Math.sqr(targetVelocity.y) -
ENG_Math.sqr(projectileSpeed);
float b = 2.0f * (targetVelocity.x * targetPos.x +
targetVelocity.y * targetPos.y);
float c = ENG_Math.sqr(targetPos.x) + ENG_Math.sqr(targetPos.y);
ENG_Math.solveQuadraticEquation(a, b, c, collisionTime);
Первый раз targetVelocity.y на самом деле является targetVelocity.z (то же самое для targetPos), а второй раз - targetVelocity.y.
Финальная позиция после XoZ
crossPosition.set(minTime * finalEntityVelocity.x + finalTargetPos4D.x, 0.0f,
minTime * finalEntityVelocity.z + finalTargetPos4D.z);
и после XoY
crossPosition.y = minTime * finalEntityVelocity.y + finalTargetPos4D.y;
Мой подход разделения на 2 плоскости и вычисления какой-либо пользы? Или для 3D есть совершенно другой подход?
- sqr () является квадратом, а не sqrt - избегая путаницы.
источник
Ответы:
Нет необходимости разбивать его на 2 2d функции. Это квадратное уравнение, с которым вы работаете, прекрасно работает и в 3d. Вот псевдокод для 2d или 3d. Это означает, что башня (защита башни) стреляет из снаряда:
'aimSpot' может быть вектором, о котором вы спрашиваете.
источник
timeToImpact
обратном отсчете до нуля.Есть также хороший пост в блоге на ту же тему: http://playtechs.blogspot.kr/2007/04/aiming-at-moving-target.html . Он также содержит более сложные образцы, которые включают гравитацию.
Автор сделал больше упрощений, что приводит к более компактному коду:
Обновление: оригинальный автор учел только больший рут. Но в случае, если меньший корень неотрицателен, это приводит к лучшему решению, так как время воздействия меньше. Я обновил код соответственно.
источник