Как заставить стрелу приземлиться на определенную позицию в трехмерном мировом пространстве

8

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

Стрелка имеет положение, ускорение и скорость, используя трехмерные векторы. Я посмотрел « Траекторию» статьи о снаряде в Википедии, но я не знаю, как применить ее в моей ситуации, поскольку она объясняет 2D математику. Мне было интересно, есть ли решение для 3D векторов? Какие-нибудь хорошие ресурсы, возможно, связанные с 3D-ситуацией?

Ник
источник
5
Я не буду писать это как ответ, так как надеюсь, что кто-то может дать более подробный ответ, но вы можете использовать 2D-решение в 3D. 2D-решение применяется к вертикальной плоскости, проходящей через начальную и конечную точки, поэтому вы берете 2D-решение и поворачиваете его, чтобы соответствовать этой плоскости в 3D-пространстве.
Kylotan

Ответы:

12

Чтобы расширить комментарий Килотана, Вы можете использовать 2D формулы в 3D. Предполагая, что Y поднялся:

рассчитать положение цели в пространстве X'Y'Z ', где ось X' параллельна направлению полета стрелки, ось Y 'направлена ​​вверх, а Z' перпендикулярна осям X 'и Y'.

диаграмма

Как только вы вычислили X 'и Y', вы можете преобразовать обратно в реальное пространство XYZ

пример

Лучник в (1,0,1). Хочет стрелять в (4,0,5). Мы принимаем X 'за единичный вектор (0,6, 0, 0,8), так как он указывает прямо из источника в пункт назначения. Затем мы принимаем Z 'равным (-0,8, 0, 0,6), потому что оно перпендикулярно, но, поскольку стрелка не движется по оси Z', мы ее проигнорируем. Теперь ваша задача выяснить, как стрелять из (0,0) в (0,5) в пространстве X'Y '.

.. делать 2D расчеты здесь. Обратите внимание, что вам, вероятно, понадобятся параметрические функции X 'и Y' в терминах переменной времени t .

Один из способов абстрагировать преобразование между двумя координатами - использовать матрицу преобразования.

let archer = Vector3d(1.0,0.0,1.0)
let target = Vector3d(4.0,0.0,5.0)
let travel = target - archer
let transform = Matrix4d.CreateTranslation(-archer) *
                Matrix4d.CreateRotationY(Math.Atan2(travel.Z,travel.X)) 
Vector3d.Transform(archer, transform) // transforms archer to (0,0,0)
Vector3d.Transform(target, transform) // transforms target to (5,0,0)

когда мы конвертируем обратно из X'Y'Z ' в XYZ , это просто обратное линейное преобразование.

let inverse = Matrix4d.Invert(transform)
Vector3d.Transform(Vector3d.Zero, transform) // transforms (0,0,0) to (1,0,1)
Джимми
источник
Спасибо, мне удалось заставить это работать! Все еще выясняю, как заставить его работать с разными высотами сейчас ... :)
Ник
Нееет! Эмм. Это можно решить аналитически в любом измерении, не прибегая к изменению координат или тригонометрии. См. Как учитывать ускорение при наведении снарядов? и playtechs.blogspot.com/2007/04/aiming-at-moving-target.html для примеров.
Electro