This site uses strictly necessary cookies. More Information

X- Home /

# Quaternion.ToAngleAxis is Unprecise?

In the code below, I create a quaternion with a rotation of 0.02 degrees and print the quaternion's angle to the 5th decimal place.

```
Quaternion q = Quaternion.Euler(0.02f, 0f, 0f);
q.ToAngleAxis( out float qAngle, out Vector3 qAxis);
print(qAngle.ToString("F5"));
```

But according to Unity, the angle of the quaternion is:

```
0.00000
```

What's causing this lack of precision? I'm so lost :(

**Answer** by Bunny83
·
Aug 21 at 07:32 AM

Because the angle is below the precision of 32 floating point numbers. The issue here is the way how rotations are represented as a quaternion. The quaternion that is created has the 4 values:

```
float halfRadians = angleInDegree * Mathf.Deg2Rad / 2;
x = 1 * Mathf.Sin(halfRadians);
y = 0 * Mathf.Sin(halfRadians);
z = 0 * Mathf.Sin(halfRadians);
w = Mathf.Cos(halfRadians);
```

As you may know a quaternion is always represented as a "vector" (x,y,z) and the cosine of half the angle around that vector. The issue here is that 0.02 degree yields a cosine value of `0.99999998476912...`

. However this is beyond the precision that a float can represent, so the value is rounded to 1. Though 1 represents an angle of 0°. The vector part itself is scaled down by sine of half the angle and results in 0.0001745329 which can be represented with a float. That means the quaternion may still work within some error margin, but the "normal" way of retrieving the the axis / angle just doesn't work. Usually you would use "Acos" on the w value to retrieve half the angle which we would double. Though since that would yield a value of 0 that doesn't really help.

You can still recover the angle to a higher precision by manually recovering the angle from the vector part instead of the scaler part. However you have to handle the sign manually. Something like this should work:

```
Vector3 axis = new Vector3(q.x, q.y, q.z);
float len = axis.magnitude;
float angle = Mathf.Asin(len) * Mathf.Rad2Deg * 2f * Mathf.Sign(q.w);
axis *= 1f / len;
```

Note that this solution will have similar issues when the half the angle gets closer to 90° (so angle is close to 180°).

So you may want to use this solution only if the absolute value of "w" is very close to "1".

### 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.