Чтобы расширить комментарий Килотана, Вы можете использовать 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)