2 Replies Latest reply on Sep 3, 2018 11:17 PM by Aaron Ecthelion

    How to smoothly interpolate between two orientation values?

    Aaron Ecthelion Level 1

      Hi everyone, recently I've been working on interpolating two orientation values smoothly in after effects expression. And I want to use only expression, no keyframes, so it can be dynamic.

       

      Here is my scenario. I have two cameras that are in different position and rotation status and I want to morph between them on the third camera.

      1.png

      The position and point of interest property, I can handle them with my expression. But the interpolating process of orientation property is going crazy.

      Probmatic Orientation.gif

      My expression used on orientation property is as below:

       

      var C1 = thisComp.layer("Camera 1");
      var C2 = thisComp.layer("Camera 2");
      var C1Orient = getWorldOrient(C1);
      var C2Orient = getWorldOrient(C2);
      linear(time,0,10,C1Orient,C2Orient);
      
      function getWorldOrient(L){
      
      var u = fromWorldVec(L.toWorldVec([1,0,0]));
      var v = fromWorldVec(L.toWorldVec([0,1,0]));
      var w = normalize(fromWorldVec(L.toWorldVec([0,0,1])));
      
      var sinb = clamp(w[0],-1,1);
      var b = Math.asin(sinb);
      var cosb = Math.cos(b);
      
      if (Math.abs(cosb) > .0005){
      
        var c = -Math.atan2(v[0],u[0]);
        var a = -Math.atan2(w[1],w[2]);
      
      }else{
      
        var a = (sinb < 0 ? -1 : 1)*Math.atan2(u[1],v[1]);
        var c = 0;
      
      }
      return [radiansToDegrees(a),radiansToDegrees(b),radiansToDegrees(c)];
      }
      

       

      Basically, I get the world Orientation of those two cameras, then linearly interpolate between them. But it doesn't work well.

       

      Then I got  another expression as between

       

      var C1 = thisComp.layer("Camera 1");
      var C2 = thisComp.layer("Camera 2");
      
      var u1 = fromWorldVec(C1.toWorldVec([1,0,0]));
      var u2 = fromWorldVec(C2.toWorldVec([1,0,0]));
      
      var v1 = fromWorldVec(C1.toWorldVec([0,1,0]));
      var v2 = fromWorldVec(C2.toWorldVec([0,1,0]));
      
      var w1 = fromWorldVec(C1.toWorldVec([0,0,1]));
      var w2 = fromWorldVec(C2.toWorldVec([0,0,1]));
      
      var u = linear(time,0,10,u1,u2);
      var v = linear(time,0,10,v1,v2);
      var w = normalize(linear(time,0,10,w1,w2));
      
      var sinb = clamp(w[0],-1,1);
      var b = Math.asin(sinb);
      var cosb = Math.cos(b);
      if (Math.abs(cosb) > .0005){
        var c = -Math.atan2(v[0],u[0]);
        var a = -Math.atan2(w[1],w[2]);
      }else{
        var a = (sinb < 0 ? -1 : 1)*Math.atan2(u[1],v[1]);
        var c = 0;
      }
      
      [radiansToDegrees(a),radiansToDegrees(b),radiansToDegrees(c)];
      

       

      In some cases it works, but in some it doesn't. Such as below:

      problem2.gif

       

      Here is the project file if you want to take a look at:

      https://www.sendspace.com/file/jv05o4

       

      So I am wondering how I can interpolate between them. I heard about quaternion. But It seems that quaternion is not built in after effects expression. And it is way beyond my ability.

       

      Anyone's help will be appreciated!

       

      Thanks,

      Aaron