当我只有相机四元数时,如何有效限制相机的俯仰角?我是否必须先转换为欧拉角,然后再转换为四元数,或者还有其他方法吗?

最佳答案

如果相机永不滚动(这在许多游戏中很常见,例如第一人称射击),那么解决方案很简单。如果有滚动,那么还需要执行其他步骤。我将从没有滚动的情况开始,然后将解决方案归纳为如果没有滚动的情况。

令qc为相机旋转。让qy旋转与qc相同,但俯仰为零。如果没有侧倾,则相机旋转为偏航旋转,然后为俯仰旋转:

qc = qp * qy

我们可以将音高旋转qp恢复为从qy到qc的旋转:
qp = qc * qy^-1

然后,诀窍是构造qy,因此我们可以将其插入上面的方程式来求解qp。令vc为指向摄像机镜头的单位矢量,即“前向矢量”。令vy为相同的向量,但投影到水平面并进行归一化。最后,当摄像机旋转qc为恒等旋转时,令v0为正向向量。将v0旋转为vy的旋转是偏航旋转。角度可以表示为:
yaw = asin(Norm(cross(v0, vy)))

相应的偏航旋转为:
qy = { cos(yaw/2), up * sin(yaw/2) }

其中“up”是向上方向的单位矢量,又称为偏航旋转的轴。将此插入上面的qp = qy ^ -1 * qc以获得音调四元数qp。最后,从qp获得俯仰角为:
pitch = 2*asin(Dot(right, [qp[1], qp[2], qp[3]]))

其中“右”是右方向上的单位矢量,又称螺距旋转轴。

就像我说的,如果相机也有侧倾,情况会变得更加复杂,但是总体策略是相同的。您可以将相机旋转公式化为旋转分量的乘积,然后隔离所需的分量(在这种情况下为俯仰)。例如,如果用于定义“俯仰”的欧拉序列是常见的偏航-俯仰-滚动序列,则将qc定义为:
qc = qr * qp * qy

我们可以将变量qx定义为俯仰和横滚旋转的组合:
qx = qr * qp

我们现在可以将qc编写为:
qc = qx * qy

我们已经知道如何通过追溯上面用于求解qp的步骤来求解这种形式的qx。重新排列qx的定义,我们得到:
qp = qr^-1 * qx

我们只是求解qx,所以要解决俯仰旋转qp,我们只需要滚动qr。我们可以像以前一样使用向量构造它。令vc再次为正向向量。滚动将围绕此向量旋转。设vu为相机的向上矢量(在世界坐标系中),并让vu0为相机的零滚动向上矢量。我们可以通过将全局上矢量投影到垂直于vc的平面上,然后进行归一化来构造vu0。侧倾旋转qr是从vu0到vu的旋转。该旋转的轴是正向向量vc。横滚角为
roll = asin(Dot(vc, cross(vu0, vu)))

相应的四元数为:
qr = { cos(roll/2), forward * sin(roll/2) }

其中“正向”是横摇旋转轴。

10-08 08:46