GLM角度轴错了?

Posted

技术标签:

【中文标题】GLM角度轴错了?【英文标题】:GLM angleAxis wrong? 【发布时间】:2019-10-10 12:24:12 【问题描述】:

从 OpenGL 中的四元数测试中,我注意到多轴上的旋转无法正常工作。所以我写了一个简单的程序来调试它。这是我的程序:

glm::quat rotation = glm::angleAxis(glm::radians(45.0f), glm::vec3(1.0f, 1.0f, 0.0f));
glm::vec3 eulerRotation = glm::degrees(glm::eulerAngles(rotation));
printf("X = %f\tY = %f\tZ = %f\n", eulerRotation.x, eulerRotation.y, eulerRotation.z);

根据我对旋转的理解,这应该输出:

X = 45.0  Y = 45.0  Z = 0.0

但是程序会输出这个:

X = 51.589348   Y = 45.000004   Z = 18.939444

我正在使用 GLM 版本 0.9.9.5 和 C++ 14 那么,我对旋转的理解是错误的还是 GLM 搞砸了?

【问题讨论】:

我没有验证您找到的角度是否正确,但请注意 Axis-Angle Representation 与 Euler Angles 不同,正确的结果看起来更像 glm 的输出而不是您的期待。 @Gilles-PhilippePaillé 您的文章说:“轴-角度表示相当于更简洁的旋转矢量,也称为欧拉矢量” 这些名字让人很困惑,但欧拉向量与包含欧拉角的向量不同。 @Gilles-PhilippePaillé 感谢您的解释,请您将其写为答案,以便我结束问题。 【参考方案1】:

Axis-Angle Representation 和Euler Angles 是编码旋转的两种不同方式。对于规范轴(X、Y、Z)上的旋转,表示非常相似,并且可能导致错误推断为转换是微不足道的。例如,轴角(45,(1,0,0)) 就是欧拉角(45,0,0)。但是,对于更通用的轴,转换并不总是那么明显。

更令人困惑的是,当我们使用 Axis-Angle 表示创建单个 3D 向量时使用了名称 Euler Vector,使用向量的长度来编码旋转角度。例如,(45,(1,0,0)) 可以编码为45*(1,0,0)。但是,欧拉向量与包含欧拉角的向量不同,原因与轴-角表示不同于欧拉角的原因相同。

最后,正如 Amadeus 的另一个回答中所述,glm 框架要求对输入轴向量进行归一化处理。规范化这个向量会得到预期的结果。

【讨论】:

【参考方案2】:

来自GLM_GTC_quaternion:

glm::angleAxis:

从一个角度和一个归一化轴构建一个四元数。

参数

角度如果定义了 GLM_FORCE_RADIANS,则角度以弧度表示,否则以度数表示。

axis四元数的轴,必须标准化。 (重点是我的)

您的 sn-p 中没有标准化轴

【讨论】:

我标准化了,但结果是这样的:X = 35.264389 Y = 30.000002 Z = 9.735612 对我来说,这似乎是正确的。您可以在此处验证四元数和欧拉角之间的转换规则:en.wikipedia.org/wiki/…。特别是,我已经验证了 Y 角,它给出了 30 @user11914177 我在this website 上进行了验证,归一化后结果正确。请注意,正确的欧拉角顺序是 ZYX。

以上是关于GLM角度轴错了?的主要内容,如果未能解决你的问题,请参考以下文章

更改 glm::perspective 中的角度反映对象

OpenGL 数学库 GLM 投影矩阵公式 glm::perspective 已经抛弃角度的使用,转为使用弧度

使用角度向量的高效 3D 旋转

Unity中如何获取指定角度的方向向量

opengl 使用 glm 单独旋转对象

opengl