Я пытаюсь нарисовать цилиндр в определенном направлении с gluCylinder
, Чтобы указать направление, которое я использую gluLookAt
однако, как и многие до меня, я не уверен насчет вектора «вверх» и поэтому не могу заставить цилиндр указывать правильное направление.
Я прочитал из другого ответа так
Интуиция за вектором «вверх» в gluLookAt проста: посмотрите на что угодно. Теперь наклоните голову на 90 градусов. То, где вы находитесь, не изменилось, направление, на которое вы смотрите, не изменилось, но изображение на вашей сетчатке явно изменилось. Какая разница? Куда указывает верхняя часть вашей головы. Это восходящий вектор.
Это простое объяснение, но в случае моего цилиндра я чувствую, что вектор подъема совершенно не важен. Поскольку цилиндр может вращаться вокруг своей оси и при этом выглядеть одинаково, другой вектор подъема ничего не изменит. Поэтому в моей задаче должно быть бесконечно много действительных векторов вверх: все ортогонали к вектору от начальной точки до конечной точки.
Вот что я делаю:
У меня есть мировые координаты того, где должны быть начальная и конечная точки цилиндра, A_world
а также B_world
,
Я проецирую их на координаты области просмотра A_vp
а также B_vp
с gluProject
:
GLdouble A_vp[3], B_vp[3], up[3], model[16], projection[16];
GLint gl_viewport[4];
glGetDoublev(GL_MODELVIEW_MATRIX, &model[0]);
glGetDoublev(GL_PROJECTION_MATRIX, &projection[0]);
glGetIntegerv(GL_VIEWPORT, gl_viewport);
gluProject(A_world[0], A_world[1], A_world[2], &model[0], &projection[0], &gl_viewport[0], &A_vp[0], &A_vp[1], &A_vp[2]);
gluProject(B_world[0], B_world[1], B_world[2], &model[0], &projection[0], &gl_viewport[0], &B_vp[0], &B_vp[1], &B_vp[2]);
Я звоню glOrtho
сбросить камеру в положение по умолчанию: Отрицательный z на изображение, x вправо, y вверх:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, vp_edgelen, vp_edgelen, 0, 25, -25);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
Я перевожу в координату A_vp
, рассчитать вектор вверх как нормаль к вектору A_vp — B_vp
и укажите вид с помощью gluLookAt
:
glTranslatef(A_vp[0], gl_viewport[2] - A_vp[1], A_vp[2]);
glMatrixMode(GL_MODELVIEW);
GLdouble[] up = {A_vp[1] * B_vp[2] - A_vp[2] * B_vp[1],
A_vp[2] * B_vp[0] - A_vp[0] * B_vp[2],
A_vp[0] * B_vp[1] - A_vp[1] * B_vp[0]};
gluLookAt(0, 0, 0,
B_vp[0], gl_viewport[2] - B_vp[1], B_vp[2],
up[0], up[1], up[2]);
Я рисую цилиндр с gluCylinder
:
GLUquadricObj *gluCylObj = gluNewQuadric();
gluQuadricNormals(gluCylObj, GLU_SMOOTH);
gluQuadricOrientation(gluCylObj, GLU_OUTSIDE);
gluCylinder(gluCylObj, 10, 10, 50, 10, 10);
Вот неожиданный результат:
Так как цилиндр начинается в правильном положении, и так как я смог нарисовать круг в положении B_vp, единственное, что должно быть неправильным, это вектор «вверх» в gluLookAt
, право?
gluLookAt()
не обязательно для достижения правильной перспективы. Достаточно повернуть текущий z-вектор, чтобы указать направление, в котором должен указывать цилиндр.