从Quaternion查看矩阵

时间:2012-10-08 08:12:31

标签: c++ math camera directx quaternions

我正在构建自己的四元数相机。据我所知,你只需要一个四元数来完全指定相机的方向(如果我错了,请纠正我)。那么,我将如何创建视图矩阵?顺便说一下,我正在使用C ++作为编程语言。

任何帮助都将不胜感激。

4 个答案:

答案 0 :(得分:11)

首先是一些警告。你会在这个主题的网络和文献中看到许多明显相互矛盾的公式。大多数冲突只是明显的。一些是真正的冲突,但那是因为有人弄错了数学。问题是没有一种正确的方法可以做到这一点。您需要知道如何使用四元数和矩阵,源如何使用它们,以及如何纠正这些明显的差异。

轮换与转型
您的相机有一个与之关联的参考框架,底层空间也是如此。您的矩阵是否表示摄像机从底层空间到摄像机方向的物理旋转,或者矩阵是否将底层空间中表示的矢量转换为摄像机的帧? (或其他东西;这里有四种选择。)这些选择是相关的;变换矩阵是旋转矩阵的转置。转换和旋转是共轭操作。同样的概念适用于四元数。您使用转换四元数或旋转四元数吗?这些又是相关的概念;一个是另一个的共轭。

左右四元数
给定单位四元数 q 来转换或旋转向量 v ,有些人使用 qvq * 来转换/旋转vector,其他人使用 q * vq 。哪种形式是正确的?两者都是。这两种形式的区别仅在于非共轭四元数是左侧( qvq * )还是右侧( q * < / sup> vq )要转换/旋转的向量。

列与行向量
大多数人使用列向量,但有些人使用行向量。在这里,你遇到了矩阵的左右问题。列向量通过 Mv 进行变换/旋转,矩阵位于向量的左侧;通过 vM 的行向量,矩阵在右边。

<强>冲击
你必须小心阅读文献。关于从四元数形成矩阵,您需要注意构造矩阵的非对角元素时的符号变化。一种配方的加法/减法可能会改变为另一种配方中的减法/加法。

左变换四元数到行向量变换矩阵
我使用左变换四元数和变换矩阵,我将向量表示为行向量。我还将四元数 q 表示为包含实数标量部分 q s 和矢量虚部 q v 的。给定这些表示,从四元数生成矩阵的计算是(伪代码):

// Compute the cosine of the rotation angle.
cost = 2.0*qs*qs - 1.0;

// Construct the diagonal of the matrix:
// T_ii = cost + 2qv_i^2
for (i = 0; i < 3; ++i) {
   T[i][i] = cost + 2.0*qv[i]*qv[i];
}

// Construct off-diagonal transformation matrix elements:
//   T_ij = 2 (qv_i qv_j - eps_ijk qs qv_k), where eps is the Levi-Civita symbol
for (k = 0; k < 3; ++k) {
   i = (k+1)%3;
   j = (i+1)%3;
   T[i][j] = 2.0*(qv[i]*qv[j] - qs*qv[k]);
   T[j][i] = 2.0*(qv[i]*qv[j] + qs*qv[k]);
}

您可能希望将这些循环展开。第一个循环扩展为三个语句,后者为六个语句。您不需要在后一个循环的扩展中计算 i j ;循环的扩展使它们成为固定数量。

替代陈述
上面的那些警告并没有看起来那么糟糕。您需要确保我的陈述与您的陈述一致。赔率是50-50而不是。如果不是,只需将分配交换到非对角元素。对T[i][j]使用T[j][i]的计算,反之亦然。怎么说:

  • s = 1开始。
  • 如果使用旋转四元数而不是转换四元数,则将 s 乘以-1。
  • 如果使用右四元数而不是左四元数,则将 s 乘以-1。
  • 如果使用旋转矩阵而不是变换矩阵,则将 s 乘以-1。
  • 如果使用行向量而不是列向量,则将 s 乘以-1。

如果 s 的最终值为1,请使用我的公式。如果为-1,只需将作业交换为T[i][j]T[j][i]。或者你可以改变加法的加法,减法加法。

最后一个问题
当标量部分不接近零时,上述计算适用。如果我们有无限精度算术,它在任何地方都是有效的。您可能希望对非常接近零度或180度的旋转使用单独的计算。

答案 1 :(得分:2)

维基百科知道:Quaternions and spatial rotation

答案 2 :(得分:1)

我建议使用Eigen C ++库来表示四元数和矩阵。当你有一个四元数对象时,你可以简单地在它上面调用.toRotationMatrix()来得到一个3x3矩阵。

另一个可能有用的库是glm

答案 3 :(得分:0)

可配置数学库(http://cmldev.net/)是一个非常轻量级的库,可以为您进行计算。它是一个头库,因此集成到您的代码应该不是问题。此功能(http://cmldev.net/?p=196)也可能对您有所帮助。