我试图从3x3旋转中提取旋转轴和旋转角度 矩阵。我目前正在使用这种方法,但我不确定我是否正常。我在我的程序的其他地方遇到了问题,我认为这可能是一个原因,但我自己无法验证。
我正在使用XNA框架,如果有帮助的话。我研究了使用Matrix.Decompose()返回比例(vec3)转换(vec3)和旋转(四元数),但我不确定我是否可以从这些值中提取所需的数据数据。
public static void MatrixRotationAxisAngle(Matrix m, ref float theta, ref Vector3 rot_axis) {
float trace = m.M11 + m.M22 + m.M33;
float cos_theta = 0.5f * (trace - 1.0f);
if (cos_theta > 0.999999875f) {
//allow some epsilon value
theta = 0.0f;
rot_axis = new Vector3(1.0f, 0.0f, 0.0f);
} else if (cos_theta > -0.999999875f) {
theta = (float)Math.Acos(cos_theta);
rot_axis.X = (m.Up.Z - m.Forward.Y);
rot_axis.Y = (m.Forward.X - m.Right.Z);
rot_axis.Z = (m.Right.Y - m.Up.X);
rot_axis.Normalize();
} else { //angle within PI limits
theta = (float)Math.PI;
//find index of largest diag term in matrix
int index = 0;
if (m.M11 > m.M22 && m.M11 > m.M33) {
index = 0;
}
if (m.M22 > m.M11 && m.M22 > m.M33) {
index = 1;
}
if (m.M33 > m.M11 && m.M33 > m.M22) {
index = 2;
}
switch (index) {
case 0:
float ix = 1.0f / rot_axis.X;
rot_axis.X = (float)Math.Sqrt(m.M11 + 1.0f);
rot_axis.Y = m.M12 * ix;
rot_axis.X = m.M13 * ix;
break;
case 1:
float iy = 1.0f / rot_axis.Y;
rot_axis.Y = (float)Math.Sqrt(m.M22 + 1.0f);
rot_axis.X = m.M21 * iy;
rot_axis.Z = m.M23 * iy;
break;
case 2:
float iz = 1.0f / rot_axis.Y;
rot_axis.Z = (float)Math.Sqrt(m.M33 + 1.0f);
rot_axis.X = m.M31 * iz;
rot_axis.Y = m.M32 * iz;
break;
}
rot_axis.Normalize();
}
}
答案 0 :(得分:0)
我建议看一下第{2.1章}中的this mathematical explanation (pdf)伪代码(取决于你的矩阵)。我已经在我的一个项目中成功使用了代码,并在我的情况下返回了有效的结果。
答案 1 :(得分:0)
请参阅http://en.wikipedia.org/wiki/Rotation_matrix#General_rotations中的矩阵。
正如你所看到的,发现这很容易。在其他方程中使用它来找到其他角度。