Как преобразовать углы Эйлера в представление угла оси в Python?

Я пытаюсь преобразовать углы Эйлера в представление угла оси в Python. Я уже скопировал функцию на этом веб-сайте: https://www.euclideanspace.com/maths/geometry/rotations/conversions/eulerToAngle/ и перевел его на Python. Однако здесь используется порядок Эйлера yzx, а у меня - zxy, так что это приводит к неправильному преобразованию.

Существуют ли какие-либо пакеты Python, которые могут выполнять это преобразование с помощью порядка Эйлера zxy, или кто-нибудь может предоставить мне псевдокод для этого преобразования?

В настоящее время мой код выглядит так (поэтому я хочу создать функцию под названием «euler_zxy_to_axis_angle» вместо той, которая есть у меня сейчас).

def euler_yzx_to_axis_angle(y_euler, z_euler, x_euler, normalize=True):
    # Assuming the angles are in radians.
    c1 = math.cos(y_euler/2)
    s1 = math.sin(y_euler/2)
    c2 = math.cos(z_euler/2)
    s2 = math.sin(z_euler/2)
    c3 = math.cos(x_euler/2)
    s3 = math.sin(x_euler/2)
    c1c2 = c1*c2
    s1s2 = s1*s2
    w = c1c2*c3 - s1s2*s3
    x = c1c2*s3 + s1s2*c3
    y = s1*c2*c3 + c1*s2*s3
    z = c1*s2*c3 - s1*c2*s3
    angle = 2 * math.acos(w)
    if normalize:
        norm = x*x+y*y+z*z
        if norm < 0.001:
            # when all euler angles are zero angle =0 so
            # we can set axis to anything to avoid divide by zero
            x = 1
            y = 0
            z = 0
        else:
            norm = math.sqrt(norm)
            x /= norm
            y /= norm
            z /= norm
    return x, y, z, angle

Итак, примером того, что я хочу сделать, было бы преобразование углов Эйлера с порядком zxy, где z=1.2, x=1.5, y=1.0 в правильное представление оси угла, которое в данном случае будет axis = [ 0.3150331, 0.6684339, 0.6737583], angle = 2.4361774. (Согласно https://www.andre-gaschler.com/rotationconverter/).

В настоящее время моя функция возвращает axis=[ 0.7371612, 0.6684339, 0.098942 ] angle = 2.4361774, поскольку она интерпретирует углы Эйлера как имеющие порядок yzx.


person Romi    schedule 22.11.2019    source источник
comment
Можете ли вы предоставить ввод и ожидаемый результат? Приведите пример для работы, пожалуйста   -  person Riccardo Bucco    schedule 22.11.2019
comment
Я добавил пример!   -  person Romi    schedule 22.11.2019


Ответы (1)


Итак, после того, как я возился с числами, я переназначил значения в уравнении и получил

import math

def euler_yzx_to_axis_angle(z_e, x_e, y_e, normalize=True):
    # Assuming the angles are in radians.
    c1 = math.cos(z_e/2)
    s1 = math.sin(z_e/2)
    c2 = math.cos(x_e/2)
    s2 = math.sin(x_e/2)
    c3 = math.cos(y_e/2)
    s3 = math.sin(y_e/2)
    c1c2 = c1*c2
    s1s2 = s1*s2
    w = c1c2*c3 - s1s2*s3
    x = c1c2*s3 + s1s2*c3
    y = s1*c2*c3 + c1*s2*s3
    z = c1*s2*c3 - s1*c2*s3
    angle = 2 * math.acos(w)
    if normalize:
        norm = x*x+y*y+z*z
        if norm < 0.001:
            # when all euler angles are zero angle =0 so
            # we can set axis to anything to avoid divide by zero
            x = 1
            y = 0
            z = 0
        else:
            norm = math.sqrt(norm)
            x /= norm
            y /= norm
            z /= norm
    return z, x, y, angle
print(euler_yzx_to_axis_angle(1.2, 1.5, 1.0))

выход которого

(0.31503310585743804, 0.668433885385261, 0.6737583269114973, 2.4361774412758335)

person Josh Harold    schedule 22.11.2019
comment
Вы возвращаете выходную ось в неправильном порядке. Но я полагаю, что правильного результата можно добиться, перебросив переменные в конце. Спасибо! - person Romi; 22.11.2019