gluCylinder 的正确 gluLookAt

Proper gluLookAt for gluCylinder

我正在尝试使用 gluCylinder 在特定方向上绘制圆柱体。为了指定方向,我使用 gluLookAt,但是,正如我之前的许多人一样,我不确定 "up" 矢量,因此无法让圆柱体指向正确的方向。

我从另一个 SO 答案中读到

The intuition behind the "up" vector in gluLookAt is simple: Look at anything. Now tilt your head 90 degrees. Where you are hasn't changed, the direction you're looking at hasn't changed, but the image in your retina clearly has. What's the difference? Where the top of your head is pointing to. That's the up vector.

这是一个简单的解释,但就我的圆柱体而言,我觉得向上矢量完全不重要。由于圆柱体可以绕其轴旋转并且看起来仍然相同,因此不同的向上矢量不会改变任何东西。所以对于我的问题应该有无限多的有效向上向量:从起点到终点的向量的所有正交。

所以这就是我所做的:

  1. 我有圆柱体起点和终点的世界坐标,A_worldB_world

  2. 我用 gluProject:

    将它们投影到视口坐标 A_vpB_vp
    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]);
    
  3. 我调用 glOrtho 将相机重置为默认位置:负 z 进入图片,x 向右,y 向上:

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0, vp_edgelen, vp_edgelen, 0, 25, -25);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    
  4. 我转换为坐标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]);
    
  5. 我用gluCylinder画圆柱体:

    GLUquadricObj *gluCylObj = gluNewQuadric();
    gluQuadricNormals(gluCylObj, GLU_SMOOTH);
    gluQuadricOrientation(gluCylObj, GLU_OUTSIDE);
    gluCylinder(gluCylObj, 10, 10, 50, 10, 10);
    

这是意外的结果:

由于圆柱体从正确的位置开始并且我能够在位置 B_vp 处画一个圆,所以唯一错误的是 [=15= 中的 "up" 矢量],对吧?

gluLookAt() 不是实现正确视角所必需的。旋转当前z向量指向圆柱体应该指向的方向即可。