Нахождение оси вращения и угла в матрице - PullRequest
0 голосов
/ 08 февраля 2012

Я пытаюсь извлечь ось вращения и угол поворота из матрицы вращения 3х3.В настоящее время я использую этот метод, но не уверен, что я на правильном пути.Я сталкиваюсь с проблемами в других частях моей программы и думаю, что это может быть причиной, но не смог сам это проверить.

Я работаю с платформой 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();
        }
    }

Ответы [ 2 ]

0 голосов
/ 08 февраля 2012

См. Матрицу в http://en.wikipedia.org/wiki/Rotation_matrix#General_rotations.

Как видите, найти тэту довольно просто. Используйте это в других уравнениях, чтобы найти другие углы.

0 голосов
/ 08 февраля 2012

Предлагаю взглянуть на псевдокод из этого математического объяснения (pdf) , глава 2.1 (в зависимости от вашей матрицы). Я успешно использовал код в одном из моих проектов, и в моем случае он дал верные результаты.

...