Следование и вращение по пути в OpenGL

Я пытаюсь выполнить упражнение, в котором транспортное средство следует за лемнискатой Бернулли (или, проще говоря, трек в форме восьмерки). Я хочу использовать glTranslatef и glRotatef для достижения этой цели. До сих пор мне удавалось успешно заставить транспортное средство следовать / перемещаться по этому пути, используя параметрическую форму следующим образом:

X = (ширина * cos (t)) / (1 + sin ^ 2 (t))
Y = (ширина * cos (t) * sin (t)) / (1 + sin ^ 2 (t))
Где t в -pi, pi

В коде это выглядит следующим образом:

carX = (float) ((Math.cos(t) / (1 + Math.sin(t)*Math.sin(t))));
carY = 0.0f;
carZ = (float) ((Math.cos(t) * (Math.sin(t))) / (1 + Math.sin(t)*Math.sin(t)));
gl.glTranslatef(carX,carY,carZ);

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

Вещи, которые я пробовал:

  • Используя производную от форм X и Y, перечисленных выше. Я использовал их независимо друг от друга, потому что я не уверен, как и нужно ли их комбинировать, чтобы использовать для угла. С небольшими изменениями они следуют прямым областям около начала координат, но ломаются вокруг кривых.
  • Непосредственно нахождение тангенса значения t и преобразование в градусы. Результат - беспорядочное вращение.

Если у кого-то есть предложения, которые могут быть лучше, чем метод glRotatef, это тоже будет оценено. Я видел, что gluLookAt может быть полезным, и я могу попытаться найти решение используя это.

(Примечание: я работаю в JOGL, используя Java и FFP, но мне удобны фрагменты кода C / C ++.)


person Anthony Neace    schedule 29.11.2012    source источник
comment
Не могли бы вы сделать что-нибудь попроще, например, вычислить (carX(t+epsilon), carZ(t+epsilon)) и использовать вектор от (carX(t), carZ(t)) к нему для направления. Если у вас есть этот вектор, угол будет Math.atan2(deltaZ, deltaX).   -  person user1118321    schedule 29.11.2012
comment
atan2 (dy / dt, dx / dt) должен дать вам желаемый угол. Не могли бы вы подробнее объяснить, какие проблемы у вас возникают при таком подходе?   -  person msell    schedule 29.11.2012
comment
Спасибо вам обоим за комментарии. Насколько я могу описать это, транспортное средство в настоящее время вращается перпендикулярно синей линии в красной точке в этом примере. Прочитав еще немного, возможно, на самом деле это именно так, как предполагается, для этого примера, хотя это не мое желаемое поведение. Я сейчас далеко от компьютера, поэтому я не могу следить за новыми попытками, но я обновлюсь снова, если узнаю что-нибудь новое.   -  person Anthony Neace    schedule 30.11.2012


Ответы (1)


если предположить, что вид из камеры - это взгляд водителя, gluLookAt это именно то, что вам нужно! на основе ваших carX,carY,carZ вычислений (при условии, что математика верна), вы можете сохранить предыдущие значения и использовать их:

//globals & imports:
import javax.vecmath.*;

Vector3f current = new Vector3f();
Vector3f prev = new Vector3f();

вычисление выглядит следующим образом:

//on drawing:
prev.set(current);
current.x = (float) ((Math.cos(t) / (1 + Math.sin(t)*Math.sin(t))));
current.z = (float) ((Math.cos(t) * (Math.sin(t))) / (1 + Math.sin(t)*Math.sin(t)));

glu.gluLookAt(current.x, 0f, current.z,
              current.x - prev.x, 0f, current.z - prev.z,
              0f, 1f, 0f);

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

person gilad hoch    schedule 02.12.2012