# quaternion interpolation behaves weirdly

This topic is 4482 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hi, i am interpolating between 2 quaternions with slerp. It's just that sometimes, it goes the "wrong" way. i.e., instead of rotating 10 degress clockwise, it rotates 350 degrees counter clockwise. Is it normal? How can this be fixed to always take the shortest path? And also, it doesn't always do that. I haven't been successful in finding when it does and when it doesn't. I suspect you might want to see my slerp function, so here it is:
[source lang=cpp]
Quat* slerp(Quat* qa, Quat* qb, double t) {

// quaternion to return
Quat* qm = new Quat();

// Calculate angle beteen them.
double costheta = qa->w * qb->w + qa->x * qb->x + qa->y * qb->y + qa->z * qb->z;
double theta = acos(costheta);

// if theta = 0 then return qa
if (abs(theta) < 0.01){
qm->w = qa->w;
qm->x = qa->x;
qm->y = qa->y;
qm->z = qa->z;
return qm;
}

// Calculate temporary values.
double sinTheta = sqrt(1.0 - costheta*costheta);
// if theta*2 = 180 degrees then result is undefined
if (abs(sinTheta) < 0.01){
qm->w = (qa->w * 0.5 + qb->w * 0.5);
qm->x = (qa->x * 0.5 + qb->x * 0.5);
qm->y = (qa->y * 0.5 + qb->y * 0.5);
qm->z = (qa->z * 0.5 + qb->z * 0.5);
return qm;
}
double ratioA = sin((1 - t) * theta) / sinTheta;
double ratioB = sin(t * theta) / sinTheta;

//calculate Quaternion.
qm->w = (qa->w * ratioA + qb->w * ratioB);
qm->x = (qa->x * ratioA + qb->x * ratioB);
qm->y = (qa->y * ratioA + qb->y * ratioB);
qm->z = (qa->z * ratioA + qb->z * ratioB);
return qm;
}



##### Share on other sites
The first thing I would try is to negate one of the quaternions before performing the interpolation if the dot product of the two is negative; this will ensure that the interpolation takes the shortest path between the two orientations. You'll probably want to use a local copy for this to avoid altering the input quaternions.

Also, assuming this is C++ you should probably return a temporary Quat object rather than a dynamically allocated Quat. (A further improvement would be to use constant references rather than pointers for the input arguments.)

##### Share on other sites
it works! may thanks

about the C++ code... you're right! before doing C++ i was doing Java, i think it shows [totally]

1. 1
Rutin
38
2. 2
3. 3
4. 4
5. 5

• 11
• 9
• 12
• 14
• 9
• ### Forum Statistics

• Total Topics
633350
• Total Posts
3011473
• ### Who's Online (See full list)

There are no registered users currently online

×