### UT_QuaternionT lerp incorrectly

467   3   1
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)

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
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));
```