矩阵到EulerAngles

时间:2012-06-21 11:55:11

标签: c++ matrix-multiplication opengl-3

我正在尝试从旋转矩阵中提取欧拉角。 我的对话: Matrix column-major,Coordinate System right-handed,Positive Angle right-handed,Rotation Order YXZ(第一个标题,然后是态度,然后是银行)

我发现了这个,但是因为他们使用其他轴命令而无法使用它:(http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToEuler/index.htm)

/** this conversion uses conventions as described on page:
*   http://www.euclideanspace.com/maths/geometry/rotations/euler/index.htm
*   Coordinate System: right hand
*   Positive angle: right hand
*   Order of euler angles: heading first, then attitude, then bank
*   matrix row column ordering:
*   [m00 m01 m02]
*   [m10 m11 m12]
*   [m20 m21 m22]*/
public final void rotate(matrix  m) {
    // Assuming the angles are in radians.
    if (m.m10 > 0.998) { // singularity at north pole
        heading = Math.atan2(m.m02,m.m22);
        attitude = Math.PI/2;
        bank = 0;
        return;
    }
    if (m.m10 < -0.998) { // singularity at south pole
        heading = Math.atan2(m.m02,m.m22);
        attitude = -Math.PI/2;
        bank = 0;
        return;
    }
    heading = Math.atan2(-m.m20,m.m00);
    bank = Math.atan2(-m.m12,m.m11);
    attitude = Math.asin(m.m10);
}

1 个答案:

答案 0 :(得分:1)

好的,我解决了这个问题。我拿了一个报纸和一支笔,然后写了3个旋转矩阵(在我的例子中:X,Y,Z)。然后我按照我愿意旋转的顺序乘以它们(在我的例子中:Y * X * Z)。

得到的矩阵的值之一等于 -sinB B 是第二次旋转。您可以从该值计算 B 旋转。如果继续查看矩阵,您还会注意到有2个值等于 sinA * cosB cosA * cosB ,这两个值的除法简化了 cosB 导致 sinA / cosA tanA 相同, A 是第一次旋转。您可以从该分部计算 A 轮换。同样,您会注意到 sinC * cosB cosC * cosB 值。

最后,您需要考虑 cosB = 0 的情况,这是 B = 90 B = -90 时的情况,在此如果你不能进行我之前告诉的分裂,因为你将除以零!因此,在这种情况下,您考虑 B = + - 90 C = 0 ,并从更简单的结果矩阵计算 A

所以这是我为我的修道院写的代码!!

/**
*   Matrix column-major
*   Coordinate System right-handed
*   Positive Angle right-handed
*   Rotation Order YXZ (first heading, then attitude, then bank)
*   [m00 m01 m02]
*   [m10 m11 m12]
*   [m20 m21 m22]
*/
public final void rotate(matrix  m) {
    // Assuming the angles are in radians.
    if ( m.m12 > 0.998 || m.m12 < -0.998 ) { // singularity at south or north pole
        heading = Math.atan2( -m.m20, m.m00 );
        bank = 0;
    } else {
        heading = Math.atan2( m.m02, m.m22 );
        bank = Math.atan2( m.m10, m.m11 );
    }
    attitude = Math.asin( m.m12 );
}