如何围绕原点倾斜相机

How to Pitch Camera Around Origin

我正在尝试实现一个绕原点旋转的相机,我已经成功地使用 gluLookat 函数实现了偏航的能力。我正在尝试实施俯仰,但结果存在一些问题(只有当我偏航到某个点然后俯仰时,俯仰才有效)。

这是我目前的尝试:

float distance, // radius (from origin) updated by -, + keys
      pitch,    // angle in degrees updated from W, S keys (increments of +- 10)
      yaw;      // angle in degrees updated from A, D keys (increments of +- 10)


view = lookAt(
        Eigen::Vector3f(distance * sin(toRadians(pitch)) * cos(toRadians(yaw)), distance * sin(toRadians(pitch)) * sin(toRadians(yaw)), distance * cos(toRadians(pitch))),
        Eigen::Vector3f(0.0f, 0.0f, 0.0f),
        Eigen::Vector3f(0.0f, 0.0f, 1.0f));

proj = perspective(toRadians(90.0f), static_cast<float>(width) / height, 1.0f, 10.0f);

我觉得我的问题是向上矢量,但我不确定如何正确更新它(同时我认为它很好,因为我总是希望相机的方向保持不变,我真的只是想移动相机的位置)

编辑: 我想补充一点,我正在计算此处找到的基于位置的信息:http://tutorial.math.lamar.edu/Classes/CalcIII/SphericalCoords.aspx 我不确定此处讨论的数学是否直接翻译以上,如有不妥请指正

这可能是一个解释问题。您的代码看起来正确,但 pitch 可能没有您认为的意思。

pitch0时,相机位于球体的北极(0, 0, 1)。这有点问题,因为您的向上矢量和视图方向变得平行并且您将无法获得有效的变换。然后,当pitch增加时,相机向南移动,直到pitch=PI时到达南极。您的代码应该适用于不在两极的任何点。您可能希望交换 sin(pitch)cos(pitch) 以在 pitch=0 时从赤道开始(并支持正和负间距)。

其实我更喜欢将这种相机更直接的建模为矩阵的组合:

view = Tr(0, 0, -distance) * RotX(-pitch) * RotY(-yaw)

Tr是平移矩阵,RotX是绕x轴旋转,RotY是绕y轴旋转。这假设 y 轴向上。如果你想让另一个轴向上,你可以添加一个相应的旋转矩阵。例如,如果您希望 z 轴向上,则

view = Tr(0, 0, -distance) * RotX(-pitch) * RotY(-yaw) * RotX(-Pi/2)