# Slerping rotation mirrors

I rotate my game character to watch at the target using the following code:

        transform.rotation = Quaternion.Slerp(startQuaternion, lookQuaternion, turningNormalizer*turningSpeed/10f)


startQuaternion is the character's current rotation when a new target is given.

lookQuaternion is the direction the character should look at and it's set like this:

    destinationVector = currentWaypoint.transform.position - transform.position;
lookQuaternion = Quaternion.LookRotation(destinationVector, Vector3.up);


turningNormalizer is just Time.deltaTime incremented and turningSpeed is a static value given in the editor.

The problem is that while the character turns as it should most of the time, it has problems when it has to do close to 180 degrees. Then it at times jitters and mirrors the rotation: In this poorly drawn image the character(on the right) starts to turn towards the circle on the left. Instead of just turning either through left or right it starts this "mirror dance":

1. It starts to rotate towards the new facing
2. Then it suddenly snaps to the same angle but on other side and keeps rotating

It does this "mirroring" so long until it looks at the target. Is this a thing with quaternions, slerping/lerping or something else?

EDIT1: Apparently the issue does not arise from the rotating itself. The more likely issue is that the character moves toward the facing while it rotates. As limiting the angle, between facing and target, when the character is allowed to move reduces and at times eliminates the jittering/mirroring rotation.

This of course raises more questions, why cannot the character move and rotate at the same time without issues? Code used for the movement:

transform.Translate(Vector3.forward * runningSpeed/10f * Time.deltaTime);

• Is 'lookQuaternion' being updated every frame? If so, then my presumption would be that some small inaccuracies are leading to a sort of jitter where the player 'overshoots' the look-rotation and so the new direction to look is just on the other side of 'directly behind'.... Oct 28, 2013 at 6:49

Each orientation in 3D space can be represented by 2 distinct unit quaternions, q and -q (component-wise negated q). For instance the orientation represented by the 3x3 identity matrix I can be represented by 2 quaternions:

 q:  { 0,  0,  0},  1
-q:  {-0, -0, -0}, -1


Both represent the same orientation in 3D space, their dot product is exactly -1, each of them lying in the other hemisphere, exactly on the opposite sides of the hypersphere.

The result you observe when the slerp takes the longer arc to rotate, is when slerping between 2 quaternions that do not lie in the same hemisphere. If that happens, just negate one of them before slerping them, then the slerp will take the shorter arc.

The dot product is an easy tool to find out whether that happens. If the dot product of both quaternions is less than 0, then they do not lie in the same hemisphere. So if the dot product of both of them is less than 0, just component-wise negate the other quaternion before slerping them.

• I wonder if I understood you correctly as I tried it with this if(Quaternion.Dot (lookQuaternion, startQuaternion) < 0) { startQuaternion = Quaternion.Inverse(startQuaternion); } But it did not correct the issue. Sorry for the poor formatting, I can't seem to tame this comment section.
– Esa
Oct 23, 2013 at 9:08
• Almost, but not Inverse, that is a different operation than Negate. if(Quaternion.Dot (lookQuaternion, q) < 0) { q.x = -q.x; q.y = -q.y; q.z = -q.z; q.w = -q.w; } I do not use C#, but from the looks of the docu, it seems you could also use the Negate-Function directly. Oct 23, 2013 at 9:46
• if(Quaternion.Dot (lookQuaternion, startQuaternion) < 0) { startQuaternion = Quaternion.Negate(startQuaternion); } Oct 23, 2013 at 9:48
• I'm afraid these did not fix the issue. I have updated the question.
– Esa
Oct 28, 2013 at 6:37
• Yeah thats probably a mix of different bugs. Simplify your test setup, test one thing at a time, not translation and rotation at the same time. First make sure one works, then the other, and then both together. Focus only on rotation first, use some well known orientation values, like start at 170 degrees, moving down to zero, see where it goes wrong and post it here Oct 28, 2013 at 13:34

Well your problem is because those two vectors that form your quaternions make 180 degrees, so the question that should be asked when interpolating which arc is it supposed to take? the upper arc or the lower one ??

This is what basically causing the mirroring, each time you are interpolating it's taking the other way around while still maintaining the angle.