Как рассчитать углы XYZ из Matrix4x4

Я пытаюсь определить углы X, Y, Z, содержащиеся в матрице, путем разложения матрицы. Я использую .net 4.5 С#.

Я создал тест, чтобы проверить следующее:

  • Если я создам 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.

Заранее спасибо!


person Rob McCabe    schedule 02.02.2014    source источник


Ответы (2)


Разве последняя строка матрицы не должна быть «1»?

[1 0 0 0]

[0 cos-sin 0]

[0 грех, потому что 0]

[0 0 0 1]

(последний столбец строки должен быть 1)

person user1767754    schedule 02.02.2014
comment
Извините, это опечатка в моем комментарии! - person Rob McCabe; 03.02.2014

На всякий случай, если кому-то еще нужно знать, вот как я получаю углы Эйлера непосредственно из Матрицы:

    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;
    }
person Rob McCabe    schedule 03.02.2014