【问题标题】:OpenGL - Rotating around a cube using gluLookAt rotates very quicklyOpenGL - 使用 gluLookAt 围绕立方体旋转会非常快速地旋转
【发布时间】:2013-02-02 20:16:43
【问题描述】:

我正在尝试使用 gluLookAt 围绕以原点为中心的立方体移动,而不是直接在对象上执行 R*T 转换。起初,我不确定如何解决这个问题。然后我意识到(在圆坐标中实现了一半的解决方案之后)我应该尝试使用球坐标系表示。我能够编写一些代码来做到这一点,但我(相机的“眼睛”)在立方体周围旋转得非常快。另外,我注意到我也向立方体移动了一点,而不是保持一个恒定的半径。当我使用 Rotate*Translate 方法时,它以更合适的速度旋转相同的距离。

我的旋转方法是使用球坐标,但我不确定这是否正确。我根据the Wikipedia page 上的图表计算了这两个角度。我计算我所在的当前点的大小(distX,distY,distZ)。我们最初在 XY 平面上看负 Z 平面)。我还得到了两个角度,一个指定绕 x 轴的旋转角度,一个指定绕 y 轴的旋转角度。这五个值是根据我的鼠标点击方式计算得出的。

我根据一些三角函数计算 theta 和 phi,然后最后计算新位置。这些公式可以在之前的链接中找到。最后一步是将其插入 gluLookAt。同样,在运行这个程序时,我可以围绕立方体旋转,但它非常快并且还可以平移相机。我做错了什么?

下面列出了我的代码,以供您参考。引用“y”和“up”的部分是我尝试计算绕 Z 轴的旋转。我可以描述这种旋转的最佳方式是,如果你看着一个物体,想象你自己是相机,然后左右倾斜你的头。我没有将它包含在我对 gluLookAt 的调用中,因为我也无法让它工作。

编辑:它现在以看起来正确的速度旋转,但它并没有完全旋转。我的意思是,在旋转时,“眼睛”会以一定角度朝向立方体移动,但随后会向后旋转,从而撤消旋转。但这会循环,因此眼睛所走的路径看起来类似于弯曲的无限符号。

void sceneTransformation(){
glLoadIdentity( );
    //Using the R*T approach. Works flawlessly
//glTranslatef(-distX, distY, -distZ);
//glRotatef( anglex, 1.0, 0.0, 0.0 );
//glRotatef( angley, 0.0, 1.0, 0.0 );

GLdouble radx = anglex*PI/180.;
GLdouble rady = angley*PI/180.;

GLdouble l = sqrt(pow(distX, 2) + pow(distY, 2) + pow(distZ, 2));
GLdouble phi = atan(distY/distZ) + radx;
GLdouble theta = acos(distZ/l) + radx;


GLdouble deltaZ = l*sin(theta)*cos(phi);
GLdouble deltaY = l*sin(theta)*sin(phi);
GLdouble deltaX = l*cos(theta);


GLdouble ytheta = atan(distX/distY); 
GLdouble y = sqrt(pow(distX,2) + pow(distY, 2));
GLdouble yangle = PI/2.-ytheta-rady;

GLdouble up_y = y*sin(yangle);
GLdouble up_x = y*cos(yangle);

gluLookAt((distX - deltaX), (distY - deltaY), (distZ - deltaZ), 0, 0, 0, 0,1,0);
}

【问题讨论】:

    标签: opengl rotation glulookat


    【解决方案1】:

    sin()cos() 和朋友等数学函数希望以弧度而不是度数输入。看起来你在假设度数,所以你的旋转速度比预期快了大约 57.3 倍(确切地说:360 / (2 * pi))。

    【讨论】:

    • 我明白你在说什么。我将所有“anglex”和“angley”变量分别更改为“radx”和“rady”。我仍然快速绕着立方体旋转。
    • @soplu:您的up_yup_x 仍在以角度计算。
    • 我错过了,但现在它已修复。但是,我在调用 gluLookAT 时不使用 up_y 或 up_x。
    【解决方案2】:

    您需要使您的移动基于时间,这意味着将旋转角度乘以开始最后一帧和当前帧之间的增量。

    angle += 90 * timeDelta; // Rotate by 90 degree each second
    

    【讨论】:

      【解决方案3】:

      您的问题有一个很好的解决方案。进行一些调查,但我认为它会满足您的需求。 Quaternions

      Some code for it

      适合将矢量转换为旋转和向后

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-02-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多