opengl - 如何根据前向矢量计算俯仰和偏航值

标签 opengl camera glm-math euler-angles

我想根据实例化相机时获得的位置和目标点来计算相机的俯仰和偏航值。如果我将俯仰角初始化为 0,将偏航角初始化为 -90(如 LearnOpenGL Camera Tutorial ),当第一次旋转发生时,相机会突然跳跃;之后旋转工作正常。因此,首先,从该教程中给出的方程开始,我尝试从前向矢量获取俯仰和偏航值:

float pitch = glm::degrees(glm::asin(forward.y));
float yaw = glm::degreees(glm::acos((float)x/glm::cos(glm::asin(y))));

而且

float yaw = glm::degreees(glm::asin((float)z/glm::cos(glm::asin(y))));

并且 cos(sin(y)) 不应该为 0,因此 y 不应该为 0 或 -1。 我尝试实现这些,但偏航的两个值不相同,偏航的第一个值似乎是我正在寻找的,但俯仰不是。 之后,我尝试了一种简单的方法,知道俯仰是前向矢量和 y 轴之间的角度,偏航是前向矢量和 x 轴之间的角度,我尝试计算(在纸上)以下内容:

const glm::vec3 yUnit(0, 1, 0);
const glm::vec3 xUnit(1, 0, 0);
float pitch = glm::degrees(glm::acos(glm::dot(forward, yUnit)));
float yaw = glm::degrees(glm::acos(glm::dot(forward, xUnit)));

具有以下 2 个输入:位置 = (0, 0, 0),目标 = (0, 1, 2,5),前向 = 目标 - 位置 = (0, 1, 2.5),标准化前向 ~ (0 , 0.37, 0.926),结果为俯仰 ~ 68 度,偏航 = 90 度。 另外,我在应用程序内打印了俯仰和偏航值,预期值应为俯仰 = -20 和偏航 = -90。

如果我错了,你能解释一下吗?为什么以及在哪里犯了错误?

最佳答案

根据您的预期值,您的音高似乎应在 -90 到 90 度之间变化,因此您应该使用 asin 而不是 acos 作为音高。

计算偏航时,需要将前向矢量投影到xz平面上。您可以通过将 y 分量设置为零然后对其进行标准化来实现此目的。

偏航需要在 0 到 360 度之间变化,但 acos 仅返回 0 到 180 度之间。偏航角在前 180 度范围内是正确的,但随着偏航角从 180 度增加到 360 度,acos 将从 180 度减小到零。 当前向向量与(0,0,1)的点积大于0时,偏航角将大于180度,因此需要调整acos值,用360减去它。

根据您的预期值,我对正确的偏航和俯仰值的猜测是

pitch = degrees(-asin(dot(forward, y_unit)))
forward.y = 0
forward = normalize(forward)
yaw = degrees(acos(dot(forward, x_unit)))
if(dot(forward, z_unit) > 0)
    yaw = 360 - yaw

关于opengl - 如何根据前向矢量计算俯仰和偏航值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60372070/

相关文章:

c - OpenGL 纹理渲染

java - 如何将CameraX与PreviewView一起使用?

c++ - 如何在 C++ 中从相机流式传输图像/数据

c++ - 将 3D 变换转换为 2D

c++ - 在 Blender 中制作模型并在 opengl 中加载

c++ - 使用 OpenGL 和 gluLookAt 绕球体旋转

c++ - 只能看到单个白点 CUDA/OpenGL interop

c++ - 在第二个线程上加载 OpenGL 资源

android - Intent 相机使应用程序崩溃

c++ - glm::rotate() 调用无法编译?