<p>I had to change the order of inputs to <code>def euler_to_quaternion</code> as follow and have to convert the inputs to radians:</p>

<pre><code>def euler_to_quaternion(roll, pitch, yaw):

        qx = np.sin(roll/2) * np.cos(pitch/2) * np.cos(yaw/2) - np.cos(roll/2) * np.sin(pitch/2) * np.sin(yaw/2)
        qy = np.cos(roll/2) * np.sin(pitch/2) * np.cos(yaw/2) + np.sin(roll/2) * np.cos(pitch/2) * np.sin(yaw/2)
        qz = np.cos(roll/2) * np.cos(pitch/2) * np.sin(yaw/2) - np.sin(roll/2) * np.sin(pitch/2) * np.cos(yaw/2)
        qw = np.cos(roll/2) * np.cos(pitch/2) * np.cos(yaw/2) + np.sin(roll/2) * np.sin(pitch/2) * np.sin(yaw/2)

        return [qx, qy, qz, qw]
</code></pre>

<p>Also, quaternion_to_euler was returning degrees and I had to change it to radians:</p>

<pre><code>def quaternion_to_euler(x, y, z, w):

    t0 = +2.0 * (w * x + y * z)
    t1 = +1.0 - 2.0 * (x * x + y * y)
    roll = math.atan2(t0, t1)
    t2 = +2.0 * (w * y - z * x)
    t2 = +1.0 if t2 &gt; +1.0 else t2
    t2 = -1.0 if t2 &lt; -1.0 else t2
    pitch = math.asin(t2)
    t3 = +2.0 * (w * z + x * y)
    t4 = +1.0 - 2.0 * (y * y + z * z)
    yaw = math.atan2(t3, t4)
    return [yaw, pitch, roll]
</code></pre>

CC BY-SA 4.0
2018-11-06T16:40:43.313Z
2018-11-06T16:40:43.313Z
Amir
<p>I am rotating n 3D shape using Euler angles in the order of XYZ meaning that the object is first rotated along the <code>X</code> axis, then <code>Y</code> and then <code>Z</code>. I want to convert the Euler angle to Quaternion and then get the same Euler angles back from the Quaternion using some [preferably] Python code or just some pseudocode or algorithm. Below, I have some code that converts Euler angle to Quaternion and then converts the Quaternion to get Euler angles. However, this does not give me the same Euler angles.</p>

<p>I think the problem is I don't know how to associate <em>yaw, pitch and roll</em> to X, Y an Z axes. Also, I don't know how to change order of conversions in the code to correctly convert the Euler angles to Quaternion and then convert the Quaternion to Euler angle so that I am able to get the same Euler angle back. Can someone help me with this?</p>

<p>And here's the code I used:</p>

<p>This function converts Euler angles to Quaternions:</p>

<pre><code>def euler_to_quaternion(yaw, pitch, roll):

        qx = np.sin(roll/2) * np.cos(pitch/2) * np.cos(yaw/2) - np.cos(roll/2) * np.sin(pitch/2) * np.sin(yaw/2)
        qy = np.cos(roll/2) * np.sin(pitch/2) * np.cos(yaw/2) + np.sin(roll/2) * np.cos(pitch/2) * np.sin(yaw/2)
        qz = np.cos(roll/2) * np.cos(pitch/2) * np.sin(yaw/2) - np.sin(roll/2) * np.sin(pitch/2) * np.cos(yaw/2)
        qw = np.cos(roll/2) * np.cos(pitch/2) * np.cos(yaw/2) + np.sin(roll/2) * np.sin(pitch/2) * np.sin(yaw/2)

        return [qx, qy, qz, qw]
</code></pre>

<p>And this converts Quaternions to Euler angles:</p>

<pre><code>def quaternion_to_euler(x, y, z, w):

        import math
        t0 = +2.0 * (w * x + y * z)
        t1 = +1.0 - 2.0 * (x * x + y * y)
        X = math.degrees(math.atan2(t0, t1))

        t2 = +2.0 * (w * y - z * x)
        t2 = +1.0 if t2 &gt; +1.0 else t2
        t2 = -1.0 if t2 &lt; -1.0 else t2
        Y = math.degrees(math.asin(t2))

        t3 = +2.0 * (w * z + x * y)
        t4 = +1.0 - 2.0 * (y * y + z * z)
        Z = math.degrees(math.atan2(t3, t4))

        return X, Y, Z
</code></pre>

<p>And I use them as follow:</p>

<pre><code>import numpy as np
euler_Original = np.random.random(3) * 360).tolist() # Generate random rotation angles for XYZ within the range [0, 360)
quat = euler_to_quaternion(euler_Original[0], euler_Original[1], euler_Original[2]) # Convert to Quaternion
newEulerRot = quaternion_to_euler(quat[0], quat[1], quat[2], quat[3]) #Convert the Quaternion to Euler angles

print (euler_Original)
print (newEulerRot)
</code></pre>

<p>The print statements print different numbers for <code>euler_Original</code> and <code>newEulerRot</code> which I don't want to be the case. For example if <code>euler_original</code> contains numbers like <code>(0.2, 1.12, 2.31)</code> in radians I get this Quaternion --> <code>[0.749, 0.290, -0.449, 0.389]</code> and converting the Quaternion to Euler angles gives me this --> <code>(132.35, 64.17, 11.45)</code> which is pretty wrong. I wonder how I can fix this?</p>

<p>Although I'm interested in getting the above code to work by making changes to it but, I would rather learn how to set up the equations correctly. This way I would know how I can get the correct Quaternions even if the order of rotations (XYZ --> YZX etc) for applying Euler angles is changed.</p>

CC BY-SA 4.0
2018-10-28T23:02:44.627Z
"*This way I would know how I can get the correct Quaternions even if the order of rotations (XYZ --> YZX etc) for applying Euler angles is changed.*" That makes no sense. If you change the order of the Euler angle composition, then the "same" rotation angles will represent a different orientation. And therefore, you would get a different quaternion. The math you use *must* be aware of the ordering, and you would therefore have to provide that ordering in some way.
Nicol Bolas
CC BY-SA 4.0
2018-10-28T23:31:05.237Z
@NicolBolas Sorry I'm pretty bad at stuff like Quaternions and other rotation-related stuff.
Amir
<3d><mathematics><geometry>
How to convert Euler angles to Quaternions and get the same Euler angles back from Quaternions?
Amir
# How to convert Euler angles to Quaternions and get the same Euler angles back from Quaternions?

(Asked by: username_0 on 2018-10-28)

I am rotating n 3D shape using Euler angles in the order of XYZ meaning that the object is first rotated along the `X` axis, then `Y` and then `Z`. I want to convert the Euler angle to Quaternion and then get the same Euler angles back from the Quaternion using some [preferably] Python code or just some pseudocode or algorithm. Below, I have some code that converts Euler angle to Quaternion and then converts the Quaternion to get Euler angles. However, this does not give me the same Euler angles.

I think the problem is I don't know how to associate *yaw, pitch and roll* to X, Y an Z axes. Also, I don't know how to change order of conversions in the code to correctly convert the Euler angles to Quaternion and then convert the Quaternion to Euler angle so that I am able to get the same Euler angle back. Can someone help me with this?

And here's the code I used:

This function converts Euler angles to Quaternions:

```
def euler_to_quaternion(yaw, pitch, roll):

        qx = np.sin(roll/2) * np.cos(pitch/2) * np.cos(yaw/2) - np.cos(roll/2) * np.sin(pitch/2) * np.sin(yaw/2)
        qy = np.cos(roll/2) * np.sin(pitch/2) * np.cos(yaw/2) + np.sin(roll/2) * np.cos(pitch/2) * np.sin(yaw/2)
        qz = np.cos(roll/2) * np.cos(pitch/2) * np.sin(yaw/2) - np.sin(roll/2) * np.sin(pitch/2) * np.cos(yaw/2)
        qw = np.cos(roll/2) * np.cos(pitch/2) * np.cos(yaw/2) + np.sin(roll/2) * np.sin(pitch/2) * np.sin(yaw/2)

        return [qx, qy, qz, qw]

```

And this converts Quaternions to Euler angles:

```
def quaternion_to_euler(x, y, z, w):

        import math
        t0 = +2.0 * (w * x + y * z)
        t1 = +1.0 - 2.0 * (x * x + y * y)
        X = math.degrees(math.atan2(t0, t1))

        t2 = +2.0 * (w * y - z * x)
        t2 = +1.0 if t2 > +1.0 else t2
        t2 = -1.0 if t2 < -1.0 else t2
        Y = math.degrees(math.asin(t2))

        t3 = +2.0 * (w * z + x * y)
        t4 = +1.0 - 2.0 * (y * y + z * z)
        Z = math.degrees(math.atan2(t3, t4))

        return X, Y, Z

```

And I use them as follow:

```
import numpy as np
euler_Original = np.random.random(3) * 360).tolist() # Generate random rotation angles for XYZ within the range [0, 360)
quat = euler_to_quaternion(euler_Original[0], euler_Original[1], euler_Original[2]) # Convert to Quaternion
newEulerRot = quaternion_to_euler(quat[0], quat[1], quat[2], quat[3]) #Convert the Quaternion to Euler angles

print (euler_Original)
print (newEulerRot)

```

The print statements print different numbers for `euler_Original` and `newEulerRot` which I don't want to be the case. For example if `euler_original` contains numbers like `(0.2, 1.12, 2.31)` in radians I get this Quaternion --> `[0.749, 0.290, -0.449, 0.389]` and converting the Quaternion to Euler angles gives me this --> `(132.35, 64.17, 11.45)` which is pretty wrong. I wonder how I can fix this?

Although I'm interested in getting the above code to work by making changes to it but, I would rather learn how to set up the equations correctly. This way I would know how I can get the correct Quaternions even if the order of rotations (XYZ --> YZX etc) for applying Euler angles is changed.

**Tags:** 3d, mathematics, geometry

> **Comments:**
> **username_1**: "*This way I would know how I can get the correct Quaternions even if the order of rotations (XYZ --> YZX etc) for applying Euler angles is changed.*" That makes no sense. If you change the order of the Euler angle composition, then the "same" rotation angles will represent a different orientation. And therefore, you would get a different quaternion. The math you use *must* be aware of the ordering, and you would therefore have to provide that ordering in some way.  
> **username_0**: @username_1 Sorry I'm pretty bad at stuff like Quaternions and other rotation-related stuff.  

---

## 1 answers

### Answer by username_0 on 2018-11-06. Score: 1 | Accepted answer

I had to change the order of inputs to `def euler_to_quaternion` as follow and have to convert the inputs to radians:

```
def euler_to_quaternion(roll, pitch, yaw):

        qx = np.sin(roll/2) * np.cos(pitch/2) * np.cos(yaw/2) - np.cos(roll/2) * np.sin(pitch/2) * np.sin(yaw/2)
        qy = np.cos(roll/2) * np.sin(pitch/2) * np.cos(yaw/2) + np.sin(roll/2) * np.cos(pitch/2) * np.sin(yaw/2)
        qz = np.cos(roll/2) * np.cos(pitch/2) * np.sin(yaw/2) - np.sin(roll/2) * np.sin(pitch/2) * np.cos(yaw/2)
        qw = np.cos(roll/2) * np.cos(pitch/2) * np.cos(yaw/2) + np.sin(roll/2) * np.sin(pitch/2) * np.sin(yaw/2)

        return [qx, qy, qz, qw]

```

Also, quaternion\_to\_euler was returning degrees and I had to change it to radians:

```
def quaternion_to_euler(x, y, z, w):

    t0 = +2.0 * (w * x + y * z)
    t1 = +1.0 - 2.0 * (x * x + y * y)
    roll = math.atan2(t0, t1)
    t2 = +2.0 * (w * y - z * x)
    t2 = +1.0 if t2 > +1.0 else t2
    t2 = -1.0 if t2 < -1.0 else t2
    pitch = math.asin(t2)
    t3 = +2.0 * (w * z + x * y)
    t4 = +1.0 - 2.0 * (y * y + z * z)
    yaw = math.atan2(t3, t4)
    return [yaw, pitch, roll]

```


---

