Not interpolate quaternion on shortest path?

Hi,

I have been searching a long time but I did not find something that hints at a solution.
Basically I want to smoothly interpolate between two Rotations. However I do not want to interpolate along the shortest path.

When I use Quaternion.Lerp, SLerp or RoateTowards it would rotate 90 degrees when interpolating between (in eulers) (0,270,0) and (0,0,0), but I want it to rotate 270 degrees.

I tried using eulerAngles on both source and target rotation, interpolating the vectors and reconverting them into quaternions with Quaternion.Euler but that gives me the same results.

Is there an inbuilt way to use this “non-optimal” interpolation?

greetings

I had the same problem, so I have written the lerp and slerp myself, with a flag to indicate whether you want to force the short way or not. I am pretty sure that Unity checks that to invert the rotation. With this code, you can indicate if you want that behaviour.

I have checked myself and it seems it works ok, but check yourself just in case:

public static class QuaternionExtension
 {
     public static Quaternion Lerp(Quaternion p, Quaternion q, float t, bool shortWay)
     {
         if (shortWay)
         {
             float dot = Quaternion.Dot(p, q);
             if (dot < 0.0f)
                 return Lerp(ScalarMultiply(p, -1.0f), q, t, true);
         }
 
         Quaternion r = Quaternion.identity;
         r.x = p.x * (1f - t) + q.x * (t);
         r.y = p.y * (1f - t) + q.y * (t);
         r.z = p.z * (1f - t) + q.z * (t);
         r.w = p.w * (1f - t) + q.w * (t);
         return r;
     }
 
     public static Quaternion Slerp(Quaternion p, Quaternion q, float t, bool shortWay)
     {
         float dot = Quaternion.Dot(p, q);
         if (shortWay)
         {
             if (dot < 0.0f)
                 return Slerp(ScalarMultiply(p, -1.0f), q, t, true);
         }
 
         float angle = Mathf.Acos(dot);
         Quaternion first = ScalarMultiply(p, Mathf.Sin((1f - t) * angle));
         Quaternion second = ScalarMultiply(q, Mathf.Sin((t) * angle));
         float division = 1f / Mathf.Sin(angle);
         return ScalarMultiply(Add(first, second), division);
     }
 
 
     public static Quaternion ScalarMultiply(Quaternion input, float scalar)
     {
         return new Quaternion(input.x * scalar, input.y * scalar, input.z * scalar, input.w * scalar);
     }
 
     public static Quaternion Add(Quaternion p, Quaternion q)
     {
         return new Quaternion(p.x + q.x, p.y + q.y, p.z + q.z, p.w + q.w);
     }
 }

If you do some searching around on UA, you will find a number of answers to this question. One answer is to treat eulerAngles as write-only and maintain your own Vector3. Here is one of those answers:

http://answers.unity3d.com/questions/475760/rotation-direction-in-coroutine.html

ok @FreetimeCoder i know of at least 2 ways to fix that off the top of my head first as a dev not as a just programmer how is your object set up wat does the scenario look like in the scene view and as well the inspector setting s and setup in hierarchy cold you either upload a sort video or a couple screen shots showing this? or another option is you could go to discord to Discord and go to the programing and general unity channel and @ john nic?9wolfgraphicsllc) that’s me I am one of the tutors and moderators there as well there is a create a ticket channel where you can get a little more focused assistance. and i would be glad to look it over and walk you through and trouble shoot it with you
for like i always say when it comes to dev work and coding alike there is always more than one way to skinn a cat