将四元数旋转转换为旋转矩阵?

Posted

技术标签:

【中文标题】将四元数旋转转换为旋转矩阵?【英文标题】:Convert Quaternion rotation to rotation matrix? 【发布时间】:2010-12-06 02:08:54 【问题描述】:

基本上,给定一个四元数 (qx, qy, qz, qw)...如何将其转换为 OpenGL 旋转矩阵?我也对哪个矩阵行是“上”、“右”、“前”等感兴趣......我有一个四元数的相机旋转,我需要向量......

【问题讨论】:

【参考方案1】:

以下代码基于一个四元数(qw, qx, qy, qz),其中顺序基于Boost四元数:

boost::math::quaternion<float> quaternion;
float qw = quaternion.R_component_1();
float qx = quaternion.R_component_2();
float qy = quaternion.R_component_3();
float qz = quaternion.R_component_4();

首先你必须标准化四元数:

const float n = 1.0f/sqrt(qx*qx+qy*qy+qz*qz+qw*qw);
qx *= n;
qy *= n;
qz *= n;
qw *= n;

然后你可以创建你的矩阵:

Matrix<float, 4>(
    1.0f - 2.0f*qy*qy - 2.0f*qz*qz, 2.0f*qx*qy - 2.0f*qz*qw, 2.0f*qx*qz + 2.0f*qy*qw, 0.0f,
    2.0f*qx*qy + 2.0f*qz*qw, 1.0f - 2.0f*qx*qx - 2.0f*qz*qz, 2.0f*qy*qz - 2.0f*qx*qw, 0.0f,
    2.0f*qx*qz - 2.0f*qy*qw, 2.0f*qy*qz + 2.0f*qx*qw, 1.0f - 2.0f*qx*qx - 2.0f*qy*qy, 0.0f,
    0.0f, 0.0f, 0.0f, 1.0f);

根据您的矩阵类,您可能需要在将其传递给 OpenGL 之前对其进行转置。

【讨论】:

仅供参考,对于任何查看此内容的人来说,这看起来像是一个主要的解释。它应该在传递给 OpenGL 时按原样工作,因为列优先和行优先导致相同的线性数组。但是,如果将其与列优先库一起使用以与另一个矩阵相乘,则可能会遇到问题,具体取决于库的工作方式。 不错。所以 boost 几乎可以做任何事情,这就是我所发现的。 另见:***.com/questions/1274936/…,其中提到四元数没有惯用手,但矩阵有。因此,您可能必须修改上述转换的 6 个单元格,将它们结合起来。单元格 21、31、32、12、13、23。 (除此之外,我只是粘贴了这段代码,并针对我的特定库稍作更改,效果很好。谢谢!) 不需要sqrt 计算。取而代之的是 n = 2.f/(qx*qx+qy*qy+qz*qz+qw*qw) 并将矩阵中的所有 2.0f 因子替换为 n【参考方案2】:

一种很容易可视化的方法是将四元数指定的旋转应用于基本向量 (1,0,0)、(0,1,0) 和 (0,0 ,1)。旋转的值 给出旋转系统中相对于原始系统的基向量.使用这些 向量以形成旋转矩阵的行。生成的矩阵及其转置, 表示原系统与原系统之间的正向和逆变换 旋转系统。

我不熟悉 OpenGL 使用的约定,所以也许其他人可以回答 你问题的那一部分......

【讨论】:

是的,我忘了我能做到这一点......我会试一试 数学上是正确的,但这样做的计算成本更高。 我会测试它,因为这个版本使用的指令可能会专门针对某些硬件(我特别考虑 GPU 着色器)进行优化,所以虽然可能,但我不确定它是否更具计算性昂贵的......【参考方案3】:

您可能根本不需要处理旋转矩阵。这是一种似乎比转换为矩阵并与向量相乘更快的方法:

  // move vector to camera position co (before or after rotation depending on the goal)
  v -= co;

  // rotate vector v by quaternion q; see info [1]
  vec3 t = 2 * cross(q.xyz, v);
  v = v + q.w * t + cross(q.xyz, t);

[1]http://mollyrocket.com/forums/viewtopic.php?t=833&sid=3a84e00a70ccb046cfc87ac39881a3d0

【讨论】:

链接已失效。【参考方案4】:

使用 glm,您可以简单地使用强制转换运算符。 所以要将matrix4转换为四元数,只需编写

glm::mat4_cast(quaternion_name)

【讨论】:

以上是关于将四元数旋转转换为旋转矩阵?的主要内容,如果未能解决你的问题,请参考以下文章

转换矩阵平移矩阵旋转矩阵关系以及python实现旋转矩阵四元数欧拉角之间转换

从四元数到 OpenGL 旋转

将表示旋转的四元数从一个坐标系转换为另一个坐标系

欧拉角旋转矩阵及四元数

欧拉角旋转矩阵及四元数

四元数旋转与旋转矩阵略有不同