2011-07-29 108 views
2

我提取在OpenGL模型矩阵与 glGetFloatv(GL_MODELVIEW_MATRIX,(浮子*)x)的转换的OpenGL 4x4矩阵来旋转角度

,并希望从所得的4×4矩阵中的X,Y和z提取轴旋转。我怎样才能做到这一点 ? 谢谢!

+0

看这个SOQ http://stackoverflow.com/questions/1766284/opengl-position-and-orientation-from-modelview-matrix – epatel

+0

谢谢,我试图在其应用的脚本,但结果是不正确的。例如。我设置为OpenGL xyz rot = [80,80,80],并且链接中的脚本返回我[-85,70,-85]。任何想法,为什么这可能是?谢谢 ! –

+0

旋转的顺序是非常重要的... xyz可能必须应用zyx(也许)通常他们被称为欧拉角度http://en.wikipedia.org/wiki/Euler_angles和应用标题 - 俯仰 - 滚动明智 – epatel

回答

3

首先您应该知道,称为欧拉角的x,y,z轴旋转遭受严重的数值问题。他们也不是不明智的。因此,无论是存储旋转角度还是旋转轴,都可以有效地形成伪装的四元数,或者坚持使用完整的旋转矩阵。

从旋转矩阵中查找四元数称为特征值问题。从技术上讲,你要确定旋转矩阵的特征向量,这是轴和幅度指定的角度。

+0

为什么我喜欢它,是因为我将角度存储在3个变量中,而在我的OpenGL绘图函数中,我在这些角度上执行3次glRotate。现在我想在这3个轴上进一步旋转,所以我使用glRotate的额外时间,并将矩阵重新分配给系统以重新存储我的新旋转角度。有没有更好的方法来做到这一点? –

+2

@Laurent Crivello:请不要像欧拉角那样存储旋转角度,因为混乱和疯狂在等着你。而是将旋转存储为单个四元数。进一步的旋转是通过在四元数上相乘来实现的。将四元数转换为旋转矩阵可以应用到具有glMultMatrix的OpenGL矩阵堆栈上,这是微不足道的。此外,您不应该将OpenGL当作数学库使用; OpenGL-3删除了所有的矩阵处理函数,要求用户自己跟踪矩阵。这是为了让人们避免你在做什么。 – datenwolf

+0

所以基本上我不应该保留我的x,y,z作为数组中的独立角度并使用glRotate命令,而是保留一个3x3的旋转矩阵并将其乘以当前矩阵,对吧? –

0

像这样的东西应该会给你你想要的。

final double roll = Math.atan2(2 * (quat.getW() * quat.getX() + quat.getY() * quat.getZ()), 
      1 - 2 * (quat.getX() * quat.getX() + quat.getY() * quat.getY())); 
final double pitch = Math.asin(2 * (quat.getW() * quat.getY() - quat.getZ() * quat.getY())); 
final double yaw = Math.atan2(2 * (quat.getW() * quat.getZ() + quat.getX() * quat.getY()), 1 - 2 * (quat.getY() 
      * quat.getY() + quat.getZ() * quat.getZ())); 

我使用这个作为一个效用函数打印出摄像机角度时我使用球面线性插值,我已经从2点4X4矩阵衍生2四元数之间进行内插(2个3D点之间即照相机运动)。

+0

感谢您的回答。然而,我的四元数是一个4x4矩阵,第一个3x3用于旋转。然而,我不能在你的代码中检索mat [0-1-2/4-5-6/8-9-10]和getX,Y,Z或W之间的映射关系。对我有什么启示?谢谢 ! –

+0

如果你正在使用Java和vecmath库,你可以通过'Quat4d quaternion = new Quat4d()创建一个四元数。 quaternion.set(yourMatrix);'。 –

1

我正在写一个类似CAD的应用程序,所以我理解你的问题,我们在业务中知道欧拉角是多么可怕的线性转换 - 但最终用户发现它们比矩阵或四元数更直观。

对于我的应用,我解释了Ken Shoemake的精彩算法,它是支持任意旋转指令的极少数算法之一。它从'93开始,所以它是纯粹的C代码 - 不适合那些胆小的人!

http://tog.acm.org/resources/GraphicsGems/gemsiv/euler_angle/