# Verifying Euler to Quaternion calculations

I'm new to Quaternions so to learn more about them I decided to read up on various resources and try to construct my own elementary Quaternion library in python and then validate it with results from Unity.

So what I do is create a new project and place a cube in space. I then add to that cube a new script that simply copies its transform.rotation to a public variable that I call "myQuaternion". A snippet of the innards of the script are:

```
public Quaternion myQuaternion;
void Update() {
myQuaternion = transform.rotation;
}
```

So that seems to be working as expected, I can inspect the cube, change its rotation and get different values in myQuaternion. Great.

So now based on this wikipedia section: https://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles#Conversion

I create this python function:

```
def euler_to_quaternion(phi,theta,psi):
return [math.cos(math.pi*phi/360)*math.cos(math.pi*theta/360)*math.cos(math.pi*psi/360)+
math.sin(math.pi*phi/360)*math.sin(math.pi*theta/360)*math.sin(math.pi*psi/360),
math.sin(math.pi*phi/360)*math.cos(math.pi*theta/360)*math.cos(math.pi*psi/360)-
math.cos(math.pi*phi/360)*math.sin(math.pi*theta/360)*math.sin(math.pi*psi/360),
math.cos(math.pi*phi/360)*math.sin(math.pi*theta/360)*math.cos(math.pi*psi/360)+
math.sin(math.pi*phi/360)*math.cos(math.pi*theta/360)*math.sin(math.pi*psi/360),
math.cos(math.pi*phi/360)*math.cos(math.pi*theta/360)*math.sin(math.pi*psi/360)-
math.sin(math.pi*phi/360)*math.sin(math.pi*theta/360)*math.cos(math.pi*psi/360)]
```

So now I run some tests:

**For rotation (45,0,0):**

Unity: w=0.9238795325112867 x=0.3826834323650898 y=0.0 z=0.0

Python: w=0.9238795325112867 x=0.3826834323650898 y=0.0 z=0.0

Looks good, they match

**For rotation (0,45,0):**

Unity: w=0.9238795325112867 x=0.0 y=0.3826834323650898 z=0.0

Python: w=0.9238795325112867 x=0.0 y=0.3826834323650898 z=0.0

Again, a match

**For rotation (0,0,45):**

Unity: w=0.9238795325112867 x=0.0 y=0.0 z=0.3826834323650898

Python: w=0.9238795325112867 x=0.0 y=0.0 z=0.3826834323650898

Again, a match

So here's the problem:

**For rotation (0,45,45):**

Unity: w=0.8535533905932737

**x=0.14644660940672624**y=0.3535533905932738 z=0.3535533905932738Python: w=0.8535533905932737

**x=-0.14644660940672624**y=0.3535533905932738 z=0.3535533905932738

So the polarity for the value of x is different, not good...

**For rotation (45,45,0):**

Unity: w= 0.8446231986207332

**x=0.46193976625564337****y=0.1913417161825449**z=0.1913417161825449Python: w= 0.8446231986207332

**x= 0.1913417161825449****y=0.46193976625564337**z= 0.1913417161825449

Now things look even more confusing, any idea what is going on?

Update: Doing more research and working through this issue, I've discovered that order of operations is very important when doing rotations. I found that I needed to break the rotations into 3 separate quaternions and then multiply them in a specific order, here's some additional python code:

```
def quaternion_mult(q,r):
return [r[0]*q[0]-r[1]*q[1]-r[2]*q[2]-r[3]*q[3],
r[0]*q[1]+r[1]*q[0]-r[2]*q[3]+r[3]*q[2],
r[0]*q[2]+r[1]*q[3]+r[2]*q[0]-r[3]*q[1],
r[0]*q[3]-r[1]*q[2]+r[2]*q[1]+r[3]*q[0]]
def unity_euler_to_quaternion(x,y,z):
return quaternion_mult(quaternion_mult(euler_to_quaternion(0,y,0),
euler_to_quaternion(x,0,0)),
euler_to_quaternion(0,0,z))
```

Now when I do a unity_euler_to_quaternion(45,45,45), the answers match.

Whew!

Ahh, yep. Looks like you did find what you were looking for. As an additional resource for others who may come across this:

The x, y, and z angles represent a rotation z degrees around the z axis, x degrees around the x axis, and y degrees around the y axis (in that order).

http://docs.unity3d.com/ScriptReference/Transform-eulerAngles.html

**Answer** by Bunny83
·
Mar 31, 2016 at 11:47 PM

Well, as you figured out yourself the order in which you apply the rotations matters. There is not just one valid euler angles representation. Unity uses the order Z-X-Y around worldspace axes. To express this combination by rotations around localspace axes you just need to reverse the order. So it's the same as Y-X-Z around the localspace axes.

I haven't looked at the conversion used on the wikipedia page, but i guess it's X-Y-Z or Z-Y-X so you need a different order of your rotations. That means the combination of all those sin / cos will look different.

You shouldn't use your "euler_to_quaternion" method inside your "unity_euler_to_quaternion" method. You do way to many calculations that way. You should first implement the AngleAxis method. I don't really know python so here's a C# example:

```
public static Quaternion AngleAxis(float aAngle, float aX, float aY, float aZ)
{
float s = Mathf.Sin(aAngle/2f);
return new Quaternion(Mathf.Cos(aAngle/2f), aX*s, aY*s, aZ*s);
}
```

This method should create a quaternion rotation of "aAngle" radians around the normalized axis defined by (aX,aY,aZ)

To create your 3 rotations you would simply use:

```
AngleAxis(x, 1f,0, 0 );
AngleAxis(y, 0, 1f,0 );
AngleAxis(z, 0, 0, 1f);
```

Finally multiply them in the right order. Keep in mind that you can calculate the combined result in one go just like the example on the wikipedia page. However i would recommend to cache each sin / cos value in a local variable. At the moment inside your "euler_to_quaternion" method you calculate each sin and cos value 4 times.

Thanks! For the first cut of code, I wanted to write something as loyal to the reference as possible, not thinking about efficiency. Once it has proven itself, I'll go in and optimize and validate against the first version of inefficient code.

It would be excellent to distill the Sin & Cos combinations for the Unity style rotations so that I did not need to multiply Quaternions at all. That might take a few sheets of paper :)

### Your answer

### Welcome to Unity Answers

The best place to ask and answer questions about development with Unity.

To help users navigate the site we have posted a site navigation guide.

If you are a new user to Unity Answers, check out our FAQ for more information.

Make sure to check out our Knowledge Base for commonly asked Unity questions.

If you are a moderator, see our Moderator Guidelines page.

We are making improvements to UA, see the list of changes.