1

我试图通过分解矩阵来确定矩阵内的 X、Y、Z 角度。我正在使用 .net 4.5 c#。

我创建了一个测试来检查以下内容:

  • 如果我创建一个仅具有标识值的 Matrix4x4
  • 将矩阵旋转 45 度
  • 分解矩阵并计算返回的四元数(给出 x、y、z 角度)
  • 检查输出的 X 值是否与输入的 45 度匹配

我得到以下结果: X:0.5 Y:0 Z:0

我期待:X:0.45 Y:0 Z:0

测试代码

Quaternion quatDecomposed;
Vector3D translation;

Matrix4x4 rot = Matrix4x4.RotationAroundX(45);
rot.DecomposeNoScaling(out quatDecomposed, out translation);

我创建了自己的 Matrix4x4、Vector3D 和 Angle3D 结构,如下例所示。

我的 Matrix4x4 绕 x 旋转的方法如下:

    public static Matrix4x4 RotationAroundX(double degrees)
    {
        // [1, 0,  0,   0]
        // [0, cos,-sin,0]
        // [0, sin,cos, 0]
        // [0, 0,  0,   1]

        // convert degrees to radians.
        double radians = DoubleExtensions.DegreesToRadians(degrees);

        // return matrix.
        var matrixTransformed = Matrix4x4.Identity;

        matrixTransformed.M22 = (float)Math.Cos(radians);
        matrixTransformed.M23 = (float)-(Math.Sin(radians));

        matrixTransformed.M32 = (float)Math.Sin(radians);
        matrixTransformed.M33 = (float)Math.Cos(radians);

        //return matrix;
        return matrixTransformed;
    }

我的分解无缩放方法如下:

    public void DecomposeNoScaling(out Quaternion rotation, out Vector3D translation)
    {
        translation.X = this[1, 4];
        translation.Y = this[2, 4];
        translation.Z = this[3, 4];

        rotation = new Quaternion(new Matrix3x3(this));
    }

我想要得到的是 Matrix4x4 中包含的角度,我这样做如下:

Angle3D angles = new Angle3D(quatDecomposed.X, quatDecomposed.Y, quatDecomposed.Z);

谁能发现我做错了什么?我真正想要解决的是来自矩阵 4x4 的欧拉角,以 ZYX 顺序排列。

提前致谢!

4

2 回答 2

0

矩阵的最后一行不应该是“1”吗?

[1 0 0 0]

[0 cos -sin 0]

[0 罪因 0]

[0 0 0 1]

(最后一行最后一列应该是1)

于 2014-02-02T22:18:13.490 回答
0

以防万一其他人需要知道,这就是我直接从矩阵获得欧拉角的方法:

    public static Angle3D GetAngles(Matrix4x4 source)
    {
        double thetaX, thetaY, thetaZ = 0.0;
        thetaX = Math.Asin(source.M32);

        if (thetaX < (Math.PI / 2))
        {
            if (thetaX > (-Math.PI / 2))
            {
                thetaZ = Math.Atan2(-source.M12, source.M22);
                thetaY = Math.Atan2(-source.M31, source.M33);
            }
            else
            {
                thetaZ = -Math.Atan2(-source.M13, source.M11);
                thetaY = 0;
            }
        }
        else
        {
            thetaZ = Math.Atan2(source.M13, source.M11);
            thetaY = 0;
        }

        // Create return object.
        Angle3D angles = new Angle3D(thetaX, thetaY, thetaZ);

        // Convert to degrees.;
        angles.Format = AngleFormat.Degrees;

        // Return angles.
        return angles;
    }
于 2014-02-03T22:06:43.703 回答