clickbait
clickbait

Reputation: 2998

Doing an Euler rotation in 2 operations different result than doing it in 1 operation

I want to perform multiple rotations in succession with Tait–Bryan angles and get the final rotation matrix. I tried to do this with scipy.spatial.transform.Rotation, but it didn’t work as expected.

The problem is demonstrated with the example below.

from scipy.spatial.transform import Rotation as R

print(
    R.from_euler('zxy', (90, 0, 90), degrees=True).apply(
        R.from_euler('xyz', (-90, 0, 0), degrees=True).as_matrix()))

print(R.from_euler('xzy', (-90, 90, 90), degrees=True).as_matrix())

In the 1st print, I perform 2 rotation operations:

  1. rotate -90º about X
  2. rotate 90º about Z and then rotate 90º about Y

These rotations can be combined into 1 operation, which I did in the 2nd print:

  1. rotate -90º about X, then rotate 90º about Z, then rotate 90º about Y

The output:

[[ 0.00000000e+00  1.00000000e+00 -2.22044605e-16]
 [ 1.00000000e+00  4.93038066e-32  4.44089210e-16]
 [ 4.44089210e-16 -2.22044605e-16 -1.00000000e+00]]

[[ 0.00000000e+00 -1.00000000e+00  0.00000000e+00]
 [ 1.00000000e+00  0.00000000e+00  1.57009246e-16]
 [-1.57009246e-16  0.00000000e+00  1.00000000e+00]]

I don’t understand why the matrices aren’t the same.

The multi-rotation’s result is 180º off the single-rotation’s result.

print(R.from_matrix(
    R.from_euler('zxy', (90, 0, 90), degrees=True).apply(
        R.from_euler('xyz', (-90, 0, 0), degrees=True).as_matrix()
    )).as_euler('zxy', degrees=True))

print(R.from_euler('xzy', (-90, 90, 90), degrees=True).as_euler('zxy', degrees=True))

Here’s the output from printing the rotation matrices’ angles:

[ 9.00000000e+01 -2.54444375e-14 -1.80000000e+02]
[90.  0.  0.]

How do you make the 1st statement (the 2 chained rotations) give the same result as the 2nd statement (the 1 single rotation)?


What I want to achieve is chain multiple Euler rotations in succession to create a final rotation matrix. My current approach that doesn’t work correctly:

R.from_euler('zxy', arbitrary_rotation_2, degrees=True).apply(
    R.from_euler('zxy', arbitrary_rotation_1, degrees=True).as_matrix())

UPDATE:

@joostblack's answer solved my problem. However, I don't get the reason how come calling Rotation.apply returns a matrix that’s NOT the dot product of the 2 rotation matrices. Scipy's scipy.spatial.transform.Rotation.apply documentation says,

In terms of rotation matricies, this application is the same as self.as_matrix().dot(vectors).

So why isn't it the same?

Upvotes: 0

Views: 1057

Answers (1)

joostblack
joostblack

Reputation: 2525

To see what is happening you can print the matrices in between.

step 1: rotation around the z and y axis with 90 degrees:

r1 = R.from_euler('xzy', (0, 90, 90), degrees=True).as_matrix()

step 2: rotation around the x axis with -90 degrees:

r2 = R.from_euler('xzy', (-90, 0, 0), degrees=True).as_matrix()

step 3: multiply your rotation matrices:

print(r1@r2)

step 4: check if it is the same as your 2nd statement:

print(R.from_euler('xzy', (-90, 90, 90), degrees=True).as_matrix())

output:

[[ 0. -1.  0.]
 [ 1.  0.  0.]
 [ 0.  0.  1.]]
[[ 0. -1.  0.]
 [ 1.  0.  0.]
 [ 0.  0.  1.]]

Upvotes: 1

Related Questions