This site uses strictly necessary cookies. More Information

X- Home /

# how do I compare Quaternions?

I'm trying to compare two rotations. I'm checking to see if they are equal like this

```
if(rot==prevrot){
dosomething;
}
else{
dosomethingelse
}
```

Here's an example of the Debug.Log of two that were not equal according to the if statement. But look at the output...

```
prevrot=(0.0, 0.0, 0.0, 1.0) rot=(0.0, 0.0, 0.0, 1.0)
```

Why doesn't the Debug.Log output match the if statement?

**Answer** by ScroodgeM
·
Jul 22, 2012 at 06:32 AM

internally quaternion stored as 4 floats, so two quaternions can be different but both logs as (0,0,0,1) due to precision of float.

http://docs.unity3d.com/Documentation/ScriptReference/Quaternion.Angle.html

use this to compare two rotations by angle between them - for example if angle is lower then some threshold then these quaternions are same

**Answer** by silentreaver
·
Oct 09, 2019 at 10:45 AM

Just to formalise @reddtoric's answer into something you can use:

```
public static bool Approximately(this Quaternion quatA, Quaternion value, float acceptableRange)
{
return 1 - Mathf.Abs(Quaternion.Dot(quatA, value)) < acceptableRange;
}
```

That'll extend the Quaternion class so you can use it in future to compare two quaternions

**Answer** by SoxwareInteractive
·
Jan 02, 2017 at 09:23 AM

You should note that Quaternion.Angle() will sometimes not return 0 even though the Quaternions are an exact copy of each other. The same applies for the "==" equality operator of quaternions.

```
Quaterion q2 = q1;
if (q1 == q2)
{
Debug.Log("That's what you would expect!");
}
else
{
// Please note that the result depends on the value q1 has.
Debug.Log("That's what happens!");
}
```

This is due to floating point errors introduced by the Mathf() functions used in the implementations of Quaternion.Angle() and the equality operator. The equality operator for example uses the dot product of the two quaternions to compare them.

The Equal() method on the other hand compares each element of the quaterion (x, y, z, w) binary wise. So when you have exact copies it is guaranteed to return true. But it will have troubles if the 2 quaternions are really close to each other but due to some floating point rounding errors they may be binary wise not exactly the same. That's when the equality operator does a better job.

So something like this would combine the best of both:

```
public bool QuaternionsEqual(Quaternion q1, Quaternion q2)
{
return (q1.Equals(q2) || (q1 == q2));
}
```

**Answer** by winxalex
·
Sep 30, 2017 at 06:14 PM

```
public static bool Approximately(Quaternion val, Quaternion about, float range) {
return Quaternion.Dot(val,about) > 1f-range;
}
```

This worked for me, although I did have to use the absolute value of the dot product as it sometimes returns the opposite sign

**Answer** by reddtoric
·
Jul 12, 2019 at 04:46 AM

**Improvement on winxalex's answer**

More understandable variable names and some explanation.

If anyone has any suggestions to a better solution for the precision variable, please chime in. For example, a float representing the angle of acceptance across all 3 axes rather than what it is now. (I usually use 0.01f or 0.001f to check approx. but in this case for 1 degree on 1 axis results in 0.0000004f difference which is very small and I don't go that small but the results isn't what I want.

If okay with 1 degree difference on 1 axis:

```
bool isQ1Q2Exact = isApproximate(q1, q2, 0.0000004f);
```

```
public static bool isApproximate(Quaternion q1, Quaternion q2, float precision)
{
return Mathf.Abs(Quaternion.Dot(q1, q2)) >= 1 - precision;
}
```

Quaternion.Dot method returns a value between 1 and -1. If it returns 1 or -1, it means the 2 quaternions are "exact". It's like 0 degrees and 360 degrees. If it returns 0, it is far from exact. Closer to Mathf.Abs(1) means more exact. Closer to 0 means further from exact.

```
Quaternion zero = Quaternion.identity;
// returns 0.9999996 => precision = 0.0000004
Quaternion tenthDegree1Axis = Quaternion.Euler(0.1f, 0, 0);
float veryClose = Quaternion.Dot(zero, tenthDegree1Axis);
// returns 0.9999619 => precision = 0.0000381
Quaternion oneDegree1Axis = Quaternion.Euler(1f, 0, 0);
float alsoVeryClose = Quaternion.Dot(zero, oneDegree1Axis);
// returns -4.371139E-08 ≈ 0
Quaternion _180Degree1Axis = Quaternion.Euler(180f, 0, 0);
float farFromClose = Quaternion.Dot(zero, _180Degree1Axis);
// returns => 0.5
Quaternion _90Degree2Axis = Quaternion.Euler(90f, 90f, 0);
float alsoFarFromClose = Quaternion.Dot(zero, _90Degree2Axis);
```

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

### Follow this Question

### Related Questions

preventing errors by calling Debug.Log on a property 1 Answer

Set (not offset) rotation on Vector3 axis? 0 Answers

Amplifying HMD rotation in VR 2 Answers

Damage Indicator not showing correct position of attack. 0 Answers

Is there a logging method, similar to C#'s Console.WriteLine? (what I want is the {N}) 3 Answers