- Home /

# Problem finding relative rotation from one quaternion to another

I want to find a relative rotation between two quaternions quatA and quatB, i.e. quatC is a quaternion rotation that if applied to quatA would result in quatB. Basically I want something like this:

```
quatC = Quaternion.RelativeRotation( quatA, quatB );
```

The only way I can think of to do it is to make two Transforms modA and modB, with modB the child of modA, and use the following code:

```
modA.rotation = quatA;
modB.rotation = quatB;
quatC = modB.localRotation;
```

However I would prefer not to use Transforms, and just use quaternions instead.

This previous answer suggests the following code would work:

```
Quaternion rotationDelta = Quaternion.FromToRotation(modelA.transform.forward, modelB.transform.forward);
```

But it doesn't appear to work after all, as it only inputs two direction vectors, not rotations. To demonstrate this, attach the following script to a basic cube dragged into an empty scene. The code will position and size the cube.

Modify rotations for models A and/or B. Model C should display the RELATIVE rotation FROM A TO B. In other words, applying C's rotation to A's rotation should result in B's rotation.

Model D shows the ACTUAL result of applying C's rotation to A's rotation. If C showed the actual relative rotation, D would be identical to B. As you will see, this is NOT the case. Hopefully I'm just missing something, but if not, is there a way to get quatC only with code?

```
var modA : Transform;
var modB : Transform;
var modC : Transform;
var modD : Transform;
var D_Rot_Equals_B_Rot = true;
```

```
```

// Nothing in Start is important to the question, it just sets up
// other objects to help demonstrate the problem
function Start() {
modA = transform;
modA.gameObject.name = "Model A";
modA.position = Vector3(0,0,0);
modA.rotation = Quaternion.identity;
modA.localScale = Vector3(.1,.1,.8);
modB = GameObject.CreatePrimitive(PrimitiveType.Cube).transform;
modB.gameObject.name = "Model B";
modB.position = Vector3(1,0,0);
modB.localScale = Vector3(.1,.1,.8);
modC = GameObject.CreatePrimitive(PrimitiveType.Cube).transform;
modC.gameObject.name = "Model C";
modC.position = Vector3(2,0,0);
modC.localScale = Vector3(.1,.1,.8);
modD = GameObject.CreatePrimitive(PrimitiveType.Cube).transform;
modD.gameObject.name = "Model D";
modD.position = Vector3(3,0,0);
modD.localScale = Vector3(.1,.1,.8);
var bump : Transform;
bump = GameObject.CreatePrimitive(PrimitiveType.Sphere).transform;
bump.gameObject.name = "Angle Helper";
bump.localScale = Vector3(.2,.2,.2);
bump.position = Vector3(0,.15,-.3);
bump.parent = modA;
bump = GameObject.CreatePrimitive(PrimitiveType.Sphere).transform;
bump.gameObject.name = "Angle Helper";
bump.localScale = Vector3(.2,.2,.2);
bump.position = Vector3(1,.15,-.3);
bump.parent = modB;
bump = GameObject.CreatePrimitive(PrimitiveType.Sphere).transform;
bump.gameObject.name = "Angle Helper";
bump.localScale = Vector3(.2,.2,.2);
bump.position = Vector3(2,.15,-.3);
bump.parent = modC;
bump = GameObject.CreatePrimitive(PrimitiveType.Sphere).transform;
bump.gameObject.name = "Angle Helper";
bump.localScale = Vector3(.2,.2,.2);
bump.position = Vector3(3,.15,-.3);
bump.parent = modD;
}

function Update () {

```
// Modify rotations for models A and/or B.
// Model C should display the RELATIVE rotation FROM A TO B.
// In other words, applying C's rotation to A's rotation should result in B's rotation.
// Model D shows the ACTUAL result of applying C's rotation to A's rotation.
// If C showed the actual relative rotation, D would be identical to B.
// As you will see, this is NOT the case.
modC.rotation = Quaternion.FromToRotation(modA.forward, modB.forward);
modD.rotation = modA.rotation * modC.rotation;
if (modD.rotation==modB.rotation) {
D_Rot_Equals_B_Rot = true;
} else {
D_Rot_Equals_B_Rot = false;
}
```

}

**Answer** by Mike 3
·
Nov 26, 2010 at 12:57 PM

This should do it:

```
Quaternion relative = Quaternion.Inverse(a) * b;
```

Nearly! I tested it both ways and it's actually the other way round - "Quaternion relative = Quaternion.Inverse(a) * b;" works a charm. Thanks! I'll tick this answer, maybe you could update it?

Oh strange, I tested that like 5 times, I must have had a thinko when I wrote it in here. Fixing it now

Thanks! It helped me too. I used to have headache from some problem with planets, and had been suffered with that for weeks, and with this solution anything got to work. Thanks again.:)

Weird, I wonder why in Unity the from is inverted and comes first, while in regular mathematics (at least according the the following link), the from is still inverted but comes last. http://stackoverflow.com/questions/1755631/difference-between-two-quaternions

I have the same doubt that @$$anonymous$$ax-Pixel, can someone explain why in Unity we put the Inverse first? Is this really correct or the Inverse in last can work as well?

**Answer** by HonoraryBob
·
Jul 06, 2018 at 09:53 PM

I tried to use the suggested code, but for some reason the result is always (0,0,0,1) even when there is a difference between the two quaternions as proven by using debug.log. Here's the code I'm using:

```
var ThisRot:Quaternion = transform.rotation;
var RotChange:Quaternion = Quaternion.Inverse(LastRot) * ThisRot;
Debug.Log("LastRot ="+LastRot+" ThisRot="+ThisRot+" RotChange="+RotChange);
LastRot = ThisRot;
```

Anyone know why this doesn't work?

[Edit: it turns out that it only seemed it didn't work because when Debug.Log prints out quaternions there's a one-digit limit for the fractional value, which means small angles don't show up.]

**Answer** by LarryTheBrave
·
Apr 27, 2019 at 05:24 PM

I would convert the rotations to Euler Angles, do a Vector3 difference, then convert back to Quaternions. This can be done with .eulerAngles against the transform.rotation and then Quaternion.Euler outside the parentheses enclosing the Vector3 subtraction. To simply get the angle you can do Quaternion.Angle.

Surprisingly, this is wrong. It makes sense, but it's completely not-even-close wrong. If you have two eulerAngle rotations, the inverse is *not* Quaternion.Euler(difference-in-xyz's). Put another way q1*(difference in xyz's) != q2. Not the other way around, either. You can test by computing the inverse and printing the euler angles.

It's because in q1*q2, q2 is on the *local* axis of the q1. If you went 20 on the real y, you can't cancel it by going -20 on the local y.

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