Точка столкновения 2 кривых в 3d-комнате - PullRequest
1 голос
/ 30 декабря 2010

Я довольно давно программирую маленькую игру. Мы начали кодировать небольшой FPS-Shooter внутри школьного проекта, чтобы получить немного опыта с DirectX. Я не знаю почему, но я не смог остановить проект и тоже начал программировать дома. На данный момент я пытаюсь создать небольшой ИИ. Конечно, это определенно нелегко, но в любом случае это моя личная цель. Тема могла бы заполнить несколько книг хе-хе. У меня до сих пор ходячая часть моих ботов. Они идут по заданному пути. Я не работаю над "прицеливанием" ботов. Во время программирования я столкнулся с какой-то математической задачей, которую пока не мог решить. Я надеюсь, что ваш вклад поможет мне продвинуться дальше. Концепции, идеи и все остальное высоко ценится.

Проблема: Вычислите позицию (D3DXVECTOR3), где кривая снаряда (зависит от силы тяжести, скорости), попадет в кривую пешеходной дорожки противника (зависит от скорости). Мы предполагаем, что противник идет по постоянной линии.

Известные переменные:

float projectilSpeed = 2000 m/s //speed of the projectile per second
float gravitation = 9.81 m/s^2 //of cause the gravity lol
D3DXVECTOR3 targetPosition //position of the target stored in a vector (x,y,z)
D3DXVECTOR3 projectilePosition //position of the projectile
D3DXVECTOR3 targetSpeed //stores the change of the targets position in the last second

Variabledefinition

ProjectilePosition at time of collision = ProjectilePos_t
TargetPosition at time of collision = TargetPos_t
ProjectilePosition at time 0, now = ProjectilePos_0
TargetPosition at time 0, now = TargetPos_0
Time to impact = t
Aim-angle = theta

Моя попытка: Найдена формула для расчета «капли» (Drop of the снаряд на основе силы тяжести) в Википедии:

float drop = 0.5f * gravity * t * t

Скорость снаряда имеет горизонтальную и вертикальную части. Найдена формула для этого в Википедии, а также:

ProjectilVelocity.x = projectilSpeed * cos(theta)
ProjectilVelocity.y = projectilSpeed * sin(theta)

Так что я бы предположил, что это верно для кривой снаряда:

ProjectilePos_t.x = ProjectilePos_0.x + ProjectileSpeed * t
ProjectilePos_t.y = ProjectilePos_0.y + ProjectileSpeed * t + 0.5f * gravity * t * t
ProjectilePos_t.z = ProjectilePos_0.z + ProjectileSpeed * t

Цель идет с постоянной скоростью, поэтому мы можем определить его кривую следующим образом:

TargetPos_t = TargetPos_0 + TargetSpeed * D3DXVECTOR3(t, t, t)

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

float time = distanz / projectileSpeed

Но это было бы не совсем правильно, поскольку предполагалось бы линейную «Траекторию». Мы просто находим это поведение при использовании ракеты.

Я надеюсь, что смог объяснить проблему как можно больше. Если остались вопросы, не стесняйтесь спрашивать меня!

Привет из Германии, Фрэнк


Edit:

Основная проблема заключается в том, что я не могу рассчитать положение врагов во время столкновения, так как у меня нет времени, прошедшего до столкновения. И с другой стороны, я не могу рассчитать время, не зная местоположение врагов во время удара. Может быть, итерационный метод решает это.

кривой враг:

pos(t).x = pos(0).x + speed.x * time
pos(t).y = pos(0).y + speed.y * time
pos(t).z = pos(0).z + speed.z * time

Кривая снаряда: pos (t) .y = pos (0) .y + sin (тета) * скорость + 0,5 * гравитация * время * время

pos (t) .x и pos (t) .z не уверены, как вычислять в (x и z), определяют направление вперед в основном ... не только x ..

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

Ответы [ 3 ]

0 голосов
/ 30 декабря 2010

Не полное решение, но как бы я подошел к этому с математической точки зрения.

У вас есть два объекта, которые вы хотите встретить.Три неизвестных, которые вам нужно найти, это время, в которое происходит попадание, вертикальный угол выстрела и горизонтальный угол выстрела.

Вы знаете положение цели в любое время t, просто сказав

position = initial position + t*velocity

(в векторах здесь).

Положение снаряда будет:

position = initial position + t*(initial velocity) + 0.5*acceleration*t^2

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

Когда мы получаем удар, очевидно, что эти две позиции будут одинаковыми, поэтому мы можем приравнять эти две позиции.

Мы знаем, что имеем векторное уравнение с тремя неизвестными.Если мы затем разделим его на составляющие его векторы, то каждое из этих уравнений будет справедливо только для компонент x, y и z векторов (обратите внимание, что ускорение имеет только компонент в направлении z).

Затем мы получимтри уравнения с тремя неизвестными, которые будут решаться одновременно.Основная причина, по которой я собираюсь оставить все остальное, состоит в том, что я понятия не имею, как бы я изобразил алгебру в своем ответе хорошим способом.:)

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

0 голосов
/ 30 декабря 2010

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

Но в реальном мире много врагов, и когда вы стреляете, вы должны проверить, пересекает ли ваша пуля в момент времени t форму какого-то врага (враги неточки).Таким образом, вы стреляете из своей пули, моделируете ее траекторию с помощью быстрого решения ODE: я думаю, что Runge Kutta 4-го порядка обычно используется не для его точности (у вас нет простого контроля над ошибкой, и вам не нужна физическая точность: только реалистичность).Не используйте RK4 для решения ODE, кроме как в видеоиграх), но потому что вы можете делать относительно большие временные шаги, не слишком отвлекаясь.

На самом деле, имитируя физику игры (физика игроков и врагов и IA, пули)...) требует от вас следить за временем.Затем вы перебираете маркеры и проверяете их на предмет пересечения с различными объектами игры (в основном врагами).

Каждый раз, типичный способ вычисления пересечений - это использование октодерева для отслеживания того, где находятся объектыявляются.В данное время это устройство позволяет вам легко находить (регистрировать) врагов, которые находятся в той же области пространства, что и пуля.Теперь вы можете использовать:

  • Ограничивающие элементарные фигуры (ящики, сферы) для врага, которые имеют дело со многими случаями, когда пуля поражает или поражает не врага: поместите коробки за пределы фигуры врагаи внутри.
  • Когда ограничивающие прямоугольники ничего вам не говорят (вы проходите через один внешний прямоугольник, но не пересекаете ни одного внутреннего прямоугольника), вы должны выработать пересечение небольшой прямой линии (между t и t+ dt, с dt не такой маленький) с вражеской формой.
0 голосов
/ 30 декабря 2010

Прежде всего, поскольку вы работаете с C ++, действительно стоит использовать перегруженные арифметические операторы и, следовательно, векторные операции .Ваши формулы будут выглядеть намного чище и ближе к математическим определениям.Вам вообще никогда не понадобятся явные .x, .y назначения.

Итак, теперь на ваш вопрос:

Основная проблема в том, что я не могу вычислитьпозиция врагов во время столкновения, так как у меня нет времени, прошедшего до столкновения

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

Поскольку вы немец, вы обязательно должны взглянуть на эту немецкую статью , которая хорошо освещает тему!

...