I am trying to convert Euler angles to the Axis Angle representation in Python. I have already copied the function on this website: https://www.euclideanspace.com/maths/geometry/rotations/conversions/eulerToAngle/ and translated it to Python. However, the Euler order they use here is yzx, while mine is zxy, so this leads to incorrect conversion.
Are there any Python packages that can do this conversion with an Euler order of zxy or can someone supply me with the pseudocode for this transformation?
My code currently looks like this (so I want to make a function called "euler_zxy_to_axis_angle" instead of the one I have now).
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
So an example of what I want to do would be convert Euler angles with the order zxy, where z=1.2, x=1.5, y=1.0
to the correct angle-axis representation, which in this case would be axis = [ 0.3150331, 0.6684339, 0.6737583], angle = 2.4361774
. (According to https://www.andre-gaschler.com/rotationconverter/).
Currently my function is returning axis=[ 0.7371612, 0.6684339, 0.098942 ] angle = 2.4361774
, since it is interpreting the Euler angles as having an yzx order.
So after messing around with the numbers I reassigned values in the equation and got
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))
the output of which is
(0.31503310585743804, 0.668433885385261, 0.6737583269114973, 2.4361774412758335)