In this post, I simply want to play with the Euler angle representations of some rotations. This is not a thorough test suite, merely a handful of different cases:

- for a random rotation…
- ZYX
- ZXZ
- ZXZ for…
- x-axis rotation
- y-axis rotation
- z-axis rotation
- ZYX for…
- x-axis rotation
- y-axis rotation
- z-axis rotation

## A random orthogonal matrix

In the previous post, we worked an example starting from a given Euler angle sequence of the form ZYX. This time, let’s begin with a random matrix. By issuing the command

(t0=RandomInteger[{-5, 5}, {3, 3}])//MatrixForm

I get a 3×3 matrix whose entries are random integers between -5 and +5. The reason for choosing integers is so that we could record this case easily: its entries are random, and will change the next time I execute that command. (Or I could explicitly set a seed for the random number generator.)

Oh, the MatrixForm at the end is what sets up the TeXForm command to give me the nice display that follows.

The matrix I got this time was

Now make an orthogonal matrix out of it. In principle, take the three columns as vectors and apply Gram-Schmidt to get three orthonormal vectors. Mathematica will do that for me as follows – by taking row vectors:

(t1=Orthogonalize[t0])//MatrixForm

and I get

Is that a rotation? Or is a reflection? Compute the determinant… it’s +1, so we do have a rotation. (A reflection has determinant -1, and, more seriously for my computations, an eigenvalue of -1 instead of +1.)

I can let Mathematica make it right: if the determinant is -1, just multiply the matrix by -1. While we’re at it, make the matrix numerical.

m0=If[Det[t1]>0, t1, -t1]//N

We can check that m0 is orthogonal just by computing and seeing if it’s an identity matrix. (It is.)

## A ZYX Euler angle sequence for that matrix

Let me begin by simply calling calling my code.

e0=rotToE[“ZYX”, m0]

which returns

{ZYX, {-0.463648, -0.420534, 2.06928}}.

From now on I’m going to combine the call and the answer like this:

e0=rotToE[“ZYX”, m0] = {ZYX, {-0.463648, -0.420534, 2.06928}}.

Then let me check the answer by converting it back to a matrix, m1. I call

m1=eToRot[“ZYX”, e0[[2]]]

which matches the original matrix m0.

In case you’ve got code of your own for doing the individual calculations, let me show you the intermediate steps.

From the matrix to angle/axis…

a1=rotToAa[m0] = {2.03041, {0.934283, -0.349503, 0.0704478}}

From angle/axis to quaternion…

q1=aaToQ[a1] = Quaternion[0.527447, 0.793756, -0.296933, 0.0598517]

And, another check, from quaternion to Euler angle sequence…

e1=qToE[“ZYX”, q1] = {ZYX, {-0.463648, -0.420534, 2.06928}}.

Yes, that does match our first answer

e0 = {ZYX, {-0.463648, -0.420534, 2.06928}}

## an XZX Euler angle sequence for that matrix

Now let’s find a different Euler angle sequence, namely ZXZ, for the same matrix.

Again, let me simply call my code.

e0=rotToE[“ZXZ”, m0] = {ZXZ, {-0.244979, 2.02243, 0.470961}}.

Then let me check the answer by converting it back to a matrix, m1:

m1=eToRot[“ZXZ”, e0[[2]]]

which matches the original matrix,

Again, let me show you the intermediate steps for reference.

From the matrix m0 to angle/axis…

a1=rotToAa[m0] = {2.03041, {0.934283, -0.349503, 0.0704478}}.

From that angle/axis to quaternion…

q1=aaToQ[a1] = Quaternion[0.527447, 0.793756, -0.296933, 0.0598517].

And, another check, from that quaternion to Euler angle sequence…

e1=qToE[“ZXZ”, q1] = {ZXZ, {-0.244979, 2.02243, 0.470961}}.

Yes, that does match our first answer

e0 = {ZXZ, {-0.244979, 2.02243, 0.470961}}.

## ZXZ for an x-axis rotation

Let’s try some degenerate cases.

Here’s a rotation (of the coordinate axes) thru 60° about the x-axis. I start with the rotation matrix…

Convert to Euler angle sequence…

e0=rotToE[“ZXZ”, m0] = {ZXZ, {0, 1.0472, 0}}.

That’s nice: our z-axis rotations are identity matrices.

Check that answer anyway by converting it to a rotation matrix…

m1=eToRot[“ZXZ”, e0[[2]]]

We got back our initial matrix. Good.

For reference, here is the quaternion representation:

q0=eToQ[“ZXZ”, e0[[2]]] = Quaternion[0.866025, 0.5, 0., 0.].

And here is the angle/axis:

a0=qToAa[q0] = {1.0472, {1., 0., 0.}}

… which confirms that we have a rotation about the x-axis thru 1.0472 radians — which is Pi/3 = 60°.

## ZXZ: a y-axis rotation

Here’s a rotation (of the coordinate axes) thru 60° about the y-axis. This might be interesting, because there is no y-rotation in the Euler angle sequence. I start with the rotation matrix…

Convert to Euler angle sequence…

e0=rotToE[“ZXZ”, m0] = {ZXZ, {1.5708, 1.0472, -1.5708}}

Check by converting that to a rotation matrix…

m1=eToRot[“ZXZ”, e0[[2]]]//Chop

and we do get back the original matrix

For reference, here is the quaternion representation:

q0=eToQ[“ZXZ”, e0[[2]]]//Chop = Quaternion[0.866025, 0, 0.5, 0].

And here is the angle/axis:

a0=qToAa[q0] = {1.0472, {0, 1., 0}}

… which confirms that we have a rotation about the y-axis thru 1.0472 radians — i.e. Pi/3.

Hang on. Let’s return to the Euler angle sequence.

e0 = {ZXZ, {1.5708, 1.0472, -1.5708}}

Two of those numbers should look familiar: they’re Pi/2.

What’s this mean? The first z-rotation is thru -Pi/2, and the third z-rotation is thru Pi/2, and the x-rotation matches the Pi/3 y-rotation we started with.

Oh, okay. After the first z-rotation, the Pi/3 rotation about the new x-axis is equivalent to a rotation about the old y-axis, and then the second z-rotation restores the original x and y axes.

## ZXZ: a z-axis rotation

Finally (for this set of three examples), here’s a rotation (of the coordinate axes) thru 60° about the z-axis. This might be interesting because the Euler angle sequence specifies two Z-axis rotations.

As usual in these cases, I start with the rotation matrix…

Convert to Euler angle sequence…

e0=rotToE[“ZXZ”, m0]= {ZXZ, {0.523599, 0, 0.523599}}

Check by converting that to a rotation matrix…

m1=eToRot[“ZXZ”, e0[[2]]] =

We got back our initial matrix. Good.

For reference, here is the quaternion representation:

q0=eToQ[“ZXZ”, e0[[2]]] = Quaternion[0.866025, 0., 0., 0.5]

And here is the angle/axis:

a0=qToAa[q0] = {1.0472, {0., 0., 1.}}.

… which confirms that we have a rotation about the x-axis thru, once again, 1.0472 radians — i.e. Pi/3.

Now, return to that Euler angle sequence and look at it:

e0 = {ZXZ, {0.523599, 0, 0.523599}}

It specifies two rotations about the z-axis, each of half the angle (namely Pi/6). The x-axis rotation is an identity matrix.

Fine. Two consecutive rotations about z thru Pi/6 is equivalent to one rotation about z thru 2 Pi/6 = Pi/3.

## ZYX: an x-axis rotation

Now let’s do the same thing except to find a ZYX Euler angle sequence.

Here’s a rotation (of the coordinate axes) thru 60° about the x-axis. I start with the rotation matrix…

Convert to Euler angle sequence…

e0=rotToE[“ZYX”, m0] = {ZYX, {0, 0, 1.0472}}.

That’s nice: two rotations of zero angle. We get just an x-rotation thru Pi/3.

Check the code by converting that to a rotation matrix…

m1=eToRot[“ZYX”, e0[[2]]] =

We got back our initial matrix. Good.

For reference, here is the quaternion representation:

q0=eToQ[“ZYX”, e0[[2]]] = Quaternion[0.866025, 0.5, 0., 0.]

And here is the angle/axis:

a0=qToAa[q0] = {1.0472, {1., 0., 0.}}

… which also says that we have a rotation about the x-axis thru 1.0472 radians — i.e. Pi/6.

## ZYX: a y-axis rotation

Here’s a rotation (of the coordinate axes) thru 60° about the y-axis.

This will be interesting, but I wouldn’t have expected it.

I start with the rotation matrix…

Ry[60°] =

Convert to Euler angle sequence…

e0=rotToE[“ZYX”, m0] = {ZYX, {0, 1.0472, 0}}

Check by converting that to a rotation matrix…

m1=eToRot[“ZYX”, e0[[2]]]//Chop =

We got back our initial matrix. Good.

For reference, here is the quaternion representation:

q0=eToQ[“ZYX”, e0[[2]]]//Chop = Quaternion[0.866025, 0, 0.5, 0]

And here is the angle/axis:

a0=qToAa[q0] = {1.0472, {0, 1., 0}}

… which confirms that we have a rotation about the y-axis thru 1.0472 radians — i.e. Pi/6.

## ZYX: a z-axis rotation

Finally (for this set of three examples), here’s a rotation (of the coordinate axes) thru 60° about the z-axis.

I start with the rotation matrix…

Rz[Pi/3] =

Convert to Euler angle sequence…

e0=rotToE[“ZYX”, m0] = {ZYX, {1.0472, 0, 0}}

Check by converting that to a rotation matrix…

m1=eToRot[“ZYX”, e0[[2]]] =

We got back our initial matrix. Good.

For reference, here is the quaternion representation:

q0=eToQ[“ZYX”, e0[[2]]] = Quaternion[0.866025, 0., 0., 0.5]

And here is the angle/axis:

a0=qToAa[q0] = {1.0472, {0., 0., 1.}}

… which confirms that we have a rotation about the z-axis thru 1.0472 radians — i.e. Pi/6.

## Leave a Reply