从模型视图矩阵中获取OpenGL位置和方向

4

我的问题如下:

我在我的OpenGL场景中有一个嵌套对象,我只知道它们的相对位置和方向。

如何获取内部对象的绝对位置和方向? 我想计算内部对象的模型视图矩阵,然后我就有了当前矩阵,但是如何将其转换为位置和方向? 换句话说,转换成两个浮点向量,这样我就可以调用以下代码:

glTranslatef(position.x,position.y,position.z);

glRotatef(alignment.x,1.0f,0.0f,0.0f);
glRotatef(alignment.y,0.0f,1.0f,0.0f);
glRotatef(alignment.z,0.0f,0.0f,1.0f);

提前感谢您!


1
抱歉,此刻太累了,无法给出完整的答案。实际上,旋转和平移只是与“特殊”矩阵相乘。 (易于谷歌搜索:“旋转平移矩阵”)。只需进行乘法并注意正确的顺序。然后进行矩阵向量乘法即可完成。(如果明天我醒来时还没有回答,我会再看一眼...) - Andreas
1个回答

5
如果您拥有对象的模型视图矩阵,可以使用以下代码提取位置:
// ... Some rotations/translations has been applied
GLfloat matrix[16]; 
glGetFloatv (GL_MODELVIEW_MATRIX, matrix);
const float position_x = matrix[12];
const float position_y = matrix[13];
const float position_z = matrix[14];

旋转有些复杂,请参考:欧拉角。我们想要的旋转矩阵是zyx矩阵的转置 =>
//c1 = cos(alignment_x)
//c2 = cos(alignment_y)
//c3 = cos(alignment_z)
//s1 = sin(alignment_x)
//s2 = sin(alignment_y)
//s3 = sin(alignment_z)
//matrix[0] = c1 * c2
//matrix[1] = -c2 * s1
//matrix[2] = s2
//matrix[4] = c3 * s1 + c1 * s2 * s3
//matrix[5] = c1 * c3 - s1 * s2 * s3
//matrix[6] = -c2 * s3
//matrix[8] = s1 * s3 - c1 * c3 * s2
//matrix[9] = c3 * s1 * s2 + c1 * s3
//matrix[10] = c2 * c3

从中提取实际角度相对比较麻烦,因为存在几个奇异点。如果我们忽略这些奇异点,则可得到如下结果:
// Assumes c2 != 0, you'll need more code to handle the special cases
if (matrix[0] != 0.0f || matrix[1] != 0.0f) {
    const float alignment_x = atanf(-matrix[1], matrix[0]);
    float c2;
    if (0 != cosf(alignment_x)) {
        c2 = matrix(0) / cosf(alignment_x);
    } else {
        c2 = matrix(1) / -sinf(alignment_x);
    }
    const float alignment_y = atanf(matrix[2], c2);
    const float alignment_z = atanf(-matrix[6], matrix[10]);
} else {
    alignment_y = atanf(matrix[2], 0);
    //Too tired to deduce alignment_x and alignment_z, someone else?
}

所有上述代码都假定您仅使用旋转/平移,而没有缩放或扭曲。
让我总结一下,欧拉角是邪恶的,如果我是你,我会寻找替代方案来解决你正在尝试解决的问题 ;)
/A.B.

你好,如果您能提供剩余的代码,我将不胜感激,因为我认为这正是我目前所需要的。我也有模型视图矩阵,并希望提取3个角度来执行类似于以下操作: glRotatef(x,1,0,0); glRotatef(y,0,1,0); glRotatef(z,0,0,1); 在我的情况下,我确定矩阵没有进行任何平移,但我认为这对旋转的计算并不重要(?)结果值的范围是0到360还是-PI到PI或类似的范围? - Simon
这里的问题是:http://www.songho.ca/opengl/gl_anglestoaxes.html#anglestoaxes 与你的代码有什么关系?你只是提取所有可能矩阵的角度吗? - Simon
是的和不,宋浩的网页向您展示了如何为六种可能的欧拉角组合之一计算旋转矩阵。您所要求的是其反:如何在给定旋转矩阵的情况下计算特定的欧拉角组合?正如我在原始答案中所说,这样做相当棘手,因为存在奇点使得计算不太明确。我提供的代码将以弧度给出所有角度。 - Andreas Brinck

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接