Следване и завъртане около път в OpenGL

Опитвам се да направя упражнение, при което превозно средство следва Лемниската на Бернули (или по-просто, песен с фигура 8). Искам да използвам 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