2009-10-12 67 views
14

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

回答

27

下面的代码是基于四元数(QW,QX,QY, QZ),如该命令是基于增压四元数:

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之前进行转置。

+0

fyi this看起来像一个行主要的解释,任何人看这个。它应该像传递给OpenGL一样工作,因为column-major和row-major会得到相同的线性数组。但是,如果将其与列主库一起使用以与另一个矩阵相乘,则可能会根据库的工作方式来解决问题。 – johnbakers 2013-06-13 02:26:14

+0

不错。所以提升可以做几乎所有我发现的事情。 – 2013-09-01 14:59:24

+0

另请参阅:http://stackoverflow.com/questions/1274936/flipping-a-quaternion-from-right-to-left-handed-coordianates其中提到四元数不具有惯用性,但矩阵DO。所以你可能需要修改上述变换的6个单元格,将它们进行排序。细胞21,31,32,12,13,23。 (除此之外,我只是粘贴了这段代码,稍微改变了一下我的特定库,它效果很好,谢谢!) – 2016-09-26 22:36:28

9

一种方法来做到这一点,这很容易可视化,就是将由四元数指定的旋转应用到基向量(1,0,0),(0,1,0)和(0,0,1)。旋转值 给出了旋转系统中相对于原始系统的基向量。使用这些向量来形成旋转矩阵的行。得到的矩阵及其转置 表示原始系统和旋转系统之间的正向和反向转换。

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

+0

是啊,我忘了我能做到这一点......我给它一个去 – Polaris878 2009-10-12 21:03:43

+0

数学上是正确的,但更多的计算这样做很昂贵。 – teodron 2013-03-18 15:28:50

+0

我会测试它,因为这个版本使用的指令,一些硬件(我特别想到的GPU着色器)可能会特别优化,所以虽然很可能,我不会那么肯定它是更计算昂贵... – 2013-04-27 14:04:41

0

使用GLM,可以简单地用一个铸造操作者。 所以从matrix4到四元数转换,简单的写

GLM :: mat4_cast(quaternion_name)