UT_QuaternionT lerp incorrectly

   467   3   1
User Avatar
Member
14 posts
Joined: Oct. 2017
Offline
Hey guys, could you help me please, why UT_QuaternionT lerp work incorrectly? What I mean, if you look picture, I do linear interpolate quaternion between two object, first object red rectangle second blue rectangle, so green object rotated between them…. so… problem is when I make angle 210, the green object rotated by long angle… If I use UT_QuaternionT.interpolate() it work correctly… but I need lerp, how I can do linear interpolate correctly?

Thanks!
Edited by rash - March 5, 2018 05:06:19

Attachments:
lerp.png (115.8 KB)

User Avatar
Staff
265 posts
Joined: July 2005
Offline
rash
Hey guys, could you help me please, why UT_QuaternionT lerp work incorrectly? What I mean, if you look picture, I do linear interpolate quaternion between two object, first object red rectangle second blue rectangle, so green object rotated between them…. so… problem is when I make angle 210, the green object rotated by long angle… If I use UT_QuaternionT.interpolate() it work correctly… but I need lerp, how I can do linear interpolate correctly?

Thanks!

You are likely providing lerp() with quaternions that are further than 180 degrees apart (remember two quaternions may effectively describe the same rotation but still be a large distance away from each other on the four dimensional surface). Since you want to find the shortest path, you should modify the input quaternions (multiply one of them by -1) so they are no further than 180 degrees apart (of course, this should only be done if your inputs are more than 180 degrees apart).
Edited by derrick - March 5, 2018 11:00:31
User Avatar
Member
14 posts
Joined: Oct. 2017
Offline
Hey derrick, thanks man! how I find short path? with dot? I use interpolate like weighted sum, when I have Q1…Qn, where weight w(1..n)==1, what I need to do to find short path between several quaternions and do interpolate correctly?

below source code, GETWEIGHT() func where I got weight from parameter each object, DrvObjName names of objects and DrnObjName name of object who rotates between them.

UT_QuaternionD qori;
UT_Matrix3D _mt;

for (int objindex = 1; objindex <= numobj; objindex++)
{

  // var sum weight
  float sum = 0;

  for (int i = 1; i <= numobj; i++){
    sum += GETWEIGHT(i);
  }

  UT_String DrvObjName;
  OPPATH(DrvObjName, objindex, t);

  UT_Matrix4D matN;
  OP_Node *drvObj = findNode(DrvObjName);
  drvObj->getWorldTransform( matN, context);

  // compute offset list
  if(GETWEIGHT()){

    UT_Matrix4D matTempDrv, matTempDrn;
    OP_Node *drnObj = findNode(DrnObjName);
    drnObj->getWorldTransform( matTempDrn, context);
    drvObj->getWorldTransform( matTempDrv, context);
    matTempDrv.invertDouble();
    offsetMat[objindex-1] = matTempDrn * matTempDrv;

  }

  matN = offsetMat[objindex-1] * matN * matInv;
              
  UT_Matrix3D mt;
  UT_Vector3D  _pos;
              
  // Rotate compute
  matN.extractRotate(mt);
  UT_QuaternionD orient;
  orient.updateFromArbitraryMatrix(mt);
  orient.normalize();
  qori += orient*(GETWEIGHT(objindex)/sum);
  matN.getTranslates(_pos);
              
  // Translate compute
  x += _pos.x()*(GETWEIGHT(objindex)/sum);
  y += _pos.y()*(GETWEIGHT(objindex)/sum);
  z += _pos.z()*(GETWEIGHT(objindex)/sum);

}

qori.normalize();
UT_Vector3D _qrot;
qori.getRotationMatrix(_mt);
_mt.crack(_qrot, UT_XformOrder::rstOrder(5));


please help me to understand, what I have to do?
Edited by rash - March 6, 2018 04:40:37
User Avatar
Staff
265 posts
Joined: July 2005
Offline
rash
Hey derrick, thanks man! how I find short path? with dot? I use interpolate like weighted sum, when I have Q1…Qn, where weight w(1..n)==1, what I need to do to find short path between several quaternions and do interpolate correctly?

If you are just considering a pair of quaternions, you could use a test like this to tell if they are more than 180 degrees apart: (Q0 * conjugate(Q1)).w < 0

It is less clear what kind of result you are expecting when you have multiple quaternions. Weighted sums of quaternions might not produce the behaviour you expect (you are delving into an area with lots of subtle complications). The idea of shortest path is not so clear in this situation. If your use case has a natural reference orientation, you may want to consider using that as a hint on how the interpolation should proceed.
  • Quick Links