This site uses strictly necessary cookies. More Information

X- Home /

# Extrapolating Quaternion Rotation

Hi,

I writing a multi-player game and am having some trouble understanding how to extrapolate a quaternion during prediction on the client side.

For example, let us say I have a quaternion q1 at time t1 and quaternion q2 at time t2 and both are known values that have happened in the passed. On my client I am trying to predict what quaternion q3 will be at time t3 prior to the server providing me the real q3.

Note: t3 > t2 > t1

My quat math is pretty lousy and i'm guessing I can't just slerp outside the 0 - 1 range.

I hope I have explained myself clearly enough any help would be greatly appreciated

Thx

I modified the answer to include a simpler and more precise method based on angle-axis representation. This method works fine, without some hickups that appeared at certain angles in the previous approach. Give it a try - it's way better!

**Answer** by aldonaletto
·
Sep 21, 2011 at 02:03 AM

I think this can be done using the following algorithm: find the rotation **rot** from q1 to q2 multiplying the inverse of q1 by q2 and calculate the "extrapolation factor" **dt** = (t3-t1)/(t2-1). **dt** will be a number > 1, where the integer part means full **rot** rotations from q1. Apply these full rotations while decrementing **dt**, and when it falls below 1 use Slerp (or Lerp) to apply the last and partial rotation:

var rot = Quaternion.Inverse(q1)*q2; // rot is the rotation occurred from t1 to t2 var dt = (t3 - t1)/(t2 - t1); // dt = extrapolation factor var q4 = q2; while (dt > 1){ q3 = q4; // q3 is the last full rotation q4 = rot * q4; // q4 is the next full rotation dt -= 1; } q3 = Quaternion.Slerp(q3, q4, dt);I haven't tested this; let me know if it has any error.

**EDITED:** I tested this algorithm, and found a jerky behaviour at certain angles. Then I studied the case a little more and found (after some Google search) a simpler way to do this. The idea is: a Quaternion is just a rotation of some angle around an arbitrary axis - the angle and axis returned by the function ToAngleAxis. Thus, to extrapolate a quaternion, all we have to do is to get the angle-axis representation, multiply the angle by the extrapolation factor, convert it back to quaternion with AngleAxis, then combine this rotation with the first one.

var rot = q2*Quaternion.Inverse(q1); // rot is the rotation from t1 to t2 var dt = (t3 - t1)/(t2 - t1); // dt = extrapolation factor var ang: float; var axis: Vector3; rot.ToAngleAxis(ang, axis); // find axis-angle representation if (ang > 180) ang -= 360; // assume the shortest path ang = ang * dt % 360; // multiply angle by the factor q3 = Quaternion.AngleAxis(ang, axis) * q1; // combine with first rotationI tested this approach, and it works perfectly - even for t3 < t2! - without the strange hickups of the previous method.

This is wonderful.

Thank you so much

Have a great day

$$anonymous$$ark his answer as 'accepted', don't post replies as answers!

@aldonaletto I found your method and I thought that it would be completely safe. But it isn't unfortunately. At some points `ToAngleAxis`

returns the opposite axis as what it was working with. When that happens, the angle becomes 360-ang. Then, you calculate it with a factor. But this factor is now calculating in the wrong way and an inverse extrapolation is performed. The new quaternion lies withing q1 and q2.

I found an error: the first expression should be:

```
var rot = q2 * Quaternion.Inverse(q1);
```

The rotation reversion can be detected when the angle becomes greater than 180: we can just subtract 360 from it - this will force the object to take the shortest path, what is the most frequent case when predicting a rotation.

The fixed code is:

var rot = q2 * Quaternion.Inverse(q1); // rot is the rotation from t1 to t2 var dt = (t3 - t1)/(t2 - t1); // dt = extrapolation factor var ang: float; var axis: Vector3; rot.ToAngleAxis(ang, axis); // find axis-angle representation if (ang > 180) ang -= 360; // assume the shortest path ang = ang * dt % 360; // multiply angle by the factor q3 = Quaternion.AngleAxis(ang, axis) * q1; // combine with first rotation

@aldonaletto Thank you for the effort. I will test it later on in my project.

**Answer** by Siris
·
Jul 06, 2014 at 06:38 AM

Here is the same thing in C#:

```
Quaternion rot = q2 * Quaternion.Inverse( q1 );
double dt = ( t3 - t1 ) / ( t2 - t1 );
float ang = 0.0f;
Vector3 axis = Vector3.zero;
rot.ToAngleAxis(out ang , out axis );
if( ang > 180 )
{
ang -= 360;
}
ang = ang * (float)dt % 360;
q3 = Quaternion.AngleAxis( ang , axis ) * q1;
```

Hi, I have used the above code for extrapolation quaternion rotation but I am not sure whether I am getting the correct results. How to ensure that that my extrapolation gave me correct results. I tried using reverse engineering method where I used the first quaternion rotation(q1) and the resultant quaternion from extrapolation (q3) and tried to intrapolate to get the quaternion rotation q2, but unfortunately I am not getting q2. I am not sure what is the problem?Can anyone give some suggestions for testing this.

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