Angus Hollands
Angus Hollands

Reputation: 396

How can i extrapolate a new quaternion rotation from two previous packets?

I'm at my wits end here! I'm working on lag-reduction in my First Person Shooter, and now it's just a case of adding some extrapolation. I can extrapolate position; getting the last two positions and the velocity from them, then adding the velocity to the existing position (* delta time). However, i cannot do the same for rotation. By default, the angles are Euler, but i can (and do) convert them to quaternions as they can suffer gimball lock. How would i extrapolate a new orientation from 2 previous orientations? I have time between packets, 2 packets and current orientation.

Upvotes: 5

Views: 3268

Answers (2)

Oliver Zendel
Oliver Zendel

Reputation: 2901

I found a good answer here: http://answers.unity3d.com/questions/168779/extrapolating-quaternion-rotation.html

I adapted the code to my needs and it works quite well!

For the two quaternions qa, qb, this will give you interpolation and extrapolation using the same formula. t is the amount of interpolation/extrapolation, t of 0.1 = 0.1 of the way from qa->qb, t = -1 -> extrapolate a whole step from qa->qb back, etc. I used selfwritten functions to allow the use of quaternions/axisAngle with opencv cv::Mat but I would probably choose Eigen for that instead

Quat qc = QuaternionMultiply(qb, QuaternionInverse(qa)); // rot is the rotation from qa to qb     
AxisAngle axisAngleC = QuaternionToAxisAngle(qc); // find axis-angle representation

double ang = axisAngleC.angle; //axis will remain the same, changes apply to the angle

if (ang > M_PI) ang -= 2.0*M_PI; // assume rotation to take the shortest path
ang = fmod(ang * t,2.0*M_PI);   // multiply angle by the interpolation/extrapolation factor and remove multiples of 2PI

axisAngleC.angle = ang;

return QuaternionMultiply(AxisAngleToQuaternion(axisAngleC),qa); // combine with first rotation

Upvotes: 5

caf
caf

Reputation: 239041

If you represent the two orientations as vectors, the vector cross product of them will give you the axis of rotation and the vector dot product can be used to find the angle of rotation.

You can then calculate an angular velocity in the same way as you calculated the scalar velocity, and use it to calculate the extrapolated rotation around the axis determined earlier.

Upvotes: 1

Related Questions