我正在尝试遵循 Rust 中的 TheCherno 光线追踪系列(目前在第 6 集),但我遇到了数学障碍。我不确定如何处理这段代码:
if (delta.x != 0.0f || delta.y != 0.0f)
{
float pitchDelta = delta.y * GetRotationSpeed();
float yawDelta = delta.x * GetRotationSpeed();
glm::quat q = glm::normalize(glm::cross(glm::angleAxis(-pitchDelta, rightDirection),
glm::angleAxis(-yawDelta, glm::vec3(0.f, 1.0f, 0.0f))));
m_ForwardDirection = glm::rotate(q, m_ForwardDirection);
moved = true;
}
GLM
如何允许四元数交叉和标准化?我对这个概念很陌生,但它在数学上似乎并不合理。我正在尝试使用
cgmath
箱在 Rust 中重写此代码,但这两个
GLM
函数没有对应的功能。我尝试自己查找源代码并实现这些功能,但除了古代文档之外,我找不到任何提及。
好吧,我们这里的季铵盐使用率相当低。该代码生成两个四元数,一个用于绕 x 轴旋转(我假设),另一个用于绕 y 轴旋转。
auto qr_xaxis = glm::angleAxis(-pitchDelta, rightDirection);
auto qr_yaxis = glm::angleAxis(-yawDelta, glm::vec3(0.f, 1.0f, 0.0f);
GLM 中的
cross
实际上只是乘法 - 将其命名为
cross
确实是非常错误的!实际上,这一切都是将 X 轴和 Y 轴旋转组合成一个旋转:
glm::quat q = qr_xaxis * qr_yaxis;
出于未知的原因,作者认为对此处的结果进行标准化是一个“好主意”。这里不需要对 quat 进行标准化,因为根据定义 qr_xaxis
和 qr_yaxis
已经标准化,并且两个单位四元数的 quat 乘积始终是一个单位四元数。
最后,通过组合的 quat 来旋转 m_ForwardDirection。
m_ForwardDirection = glm::rotate(q, m_ForwardDirection);
老实说,我不完全确定这段代码想要做什么,但我会说原作者对四元数如何工作的理解显然
不太好。结果我会用大剂量的盐来对待他的教程系列......