Вводя:
Я разрабатываю небольшую игру Tower Defense в OpenGL, в настоящее время я просто отчаиваюсь из-за небольшой проблемы ….
Я хочу, чтобы снаряды из башни прицеливались головой в сторону отряда. Так что моя проблема скорее математическая, но она принадлежит opengl 🙂
У меня была следующая идея; Я мог бы использовать точечное произведение, чтобы получить угол, вращающийся вокруг оси x, чтобы получить головку в зависимости от расстояния, проходящего прямо вниз или ровно до земли, и после этого дополнительного угла для поворота вокруг оси y, в котором находится головка стрелки. каждый раз подстраивается под устройство, на которое он нацелен.
Мой код для угла поворота вокруг оси X (я назвал его m_fYNeigung, потому что высота (Y) головы изменяется при вращении вокруг оси X) выглядит так:
plocalTowerArray[(sizeMapIndexY * 12) + sizeMapIndexX].Projektils[byteProjectilIndex].m_fYNeigung =
RADIANS_TO_DEGREES (acos ((float)
(
(faTowerPosition[0]) * (plocalTowerArray[(sizeMapIndexY * 12) + sizeMapIndexX].Projektils[byteProjectilIndex].m_faProDirectionVector[0]) +
(faTowerPosition[1] - 1) * (plocalTowerArray[(sizeMapIndexY * 12) + sizeMapIndexX].Projektils[byteProjectilIndex].m_faProDirectionVector[1]) +
(faTowerPosition[2]) * (plocalTowerArray[(sizeMapIndexY * 12) + sizeMapIndexX].Projektils[byteProjectilIndex].m_faProDirectionVector[2])
)
/
(
fabs (faTowerPosition[0]) * fabs (plocalTowerArray[(sizeMapIndexY * 12) + sizeMapIndexX].Projektils[byteProjectilIndex].m_faProDirectionVector[0]) +
fabs (faTowerPosition[1] - 1) * fabs (plocalTowerArray[(sizeMapIndexY * 12) + sizeMapIndexX].Projektils[byteProjectilIndex].m_faProDirectionVector[1]) +
fabs (faTowerPosition[2]) * fabs (plocalTowerArray[(sizeMapIndexY * 12) + sizeMapIndexX].Projektils[byteProjectilIndex].m_faProDirectionVector[2])
)
));
где faTowerPosition — это первый вектор, который направлен вниз от вершины башни (стрелка также начинается с faTowerPosition [X / Y / Z]), вторым вектором для точечного произведения является m_faProDirectionVector, который является нормализованным вектором направления, описывающим маршрут стрелы от башни к блоку.
Часть Opengl Drawing выглядит так же просто, как это:
for (sizeJ = 0; sizeJ < localTowerArray[sizeI].m_byteProjectilAmount; sizeJ++)
{
if (localTowerArray[sizeI].Projektils[sizeJ].m_bOnFlight == true)
{
glPushMatrix();
glTranslatef (localTowerArray[sizeI].Projektils[sizeJ].m_faProPosition[0], localTowerArray[sizeI].Projektils[sizeJ].m_faProPosition[1], localTowerArray[sizeI].Projektils[sizeJ].m_faProPosition[2]);
//glRotatef (360.0f - localTowerArray[sizeI].Projektils[sizeJ].m_fXNeigung, 0, 1, 0);
glRotatef (localTowerArray[sizeI].Projektils[sizeJ].m_fYNeigung, 1, 0, 0);
DrawWaveFrontObject (m_pArrowProjektilObject);
glPopMatrix();
}
}
Просто проигнорируйте вычисления, которые я делаю для угла, я просто сделал это, чтобы поэкспериментировать с действием стрелок, я просто заметил, что это выглядит так, как если бы стрелка действовала по-разному в зависимости от (я должен сказать: сборная карта масштабируется по x: от -3,4 до 3,4 и z от 4 до -4) шнуров башня была построена на -x / z, -z / x, z / x, -z / -x все эти случаи, я думаю, разные и, по крайней мере, в зависимости от того, работает ли блок с левой или правой стороны башни, действие также отличается …. так что я забыл напомнить, используя точечный продукт таким образом?
Во-первых, ваш код очень сложен для понимания, поэтому я очень много пытаюсь ответить вам. Если я предполагаю, что что-то не так, мои извинения за это.
Я предполагаю, что вы хотите использовать угол поворота Эйлера, чтобы правильно выровнять ваши снаряды. Итак, сначала вы сделаете вращение X, а затем вращение Y.
Чтобы выполнить вращение X, ваши векторы для точечного произведения должны находиться в плоскости YZ, и при условии, что ваш снаряд начинается в направлении Z, ваш первый вектор равен (0, 0, 1). Второй вектор, как вы сказали, является вектором, указывающим на единицу, и может быть выражен как (px, py, pz). Вы должны спроецировать этот вектор на плоскость YZ, чтобы получить второй вектор для вашего точечного произведения, поэтому этот вектор будет (0, py, pz)
Теперь для вычисления точечного произведения вы применяете следующую формулу
x1.x2 + y1.y2 + z1.z2 = | p1 |. | p2 | .cos a, где | p1 | и | p2 | модуль вектора (его длина)
В этом примере первый вектор является унитарным, а второй нет. Так что | p2 | = sqrt (py ^ 2 + pz ^ 2). После этого:
acos (a) = pz / sqrt (py ^ 2 + pz ^ 2)
Это даст вам угол вокруг оси X. Сделайте то же самое вычисление для достижения угла поворота Y
PS. После того, как я написал этот ответ, я заметил, что вы используете функцию «fabs». Я думаю, вы хотите найти модуль вашего второго вектора, но FABS дают вам абсолютное значение эскалара. Для вычисления модуля вектора (его длины) необходимо использовать приведенные выше формулы, как указано.
Других решений пока нет …