# Quaternion Slerp - Shorter way around?

## Recommended Posts

I seem to be having an issue with making a quaternion interpolate through the shortest path. I am making use of Bullet's math/phyiscs package and the quaternion slerp function it provides. My research tells me that when the dot product of two quaternions is negative you should negate one of them. Is my approach correct? It doesn't seem to be producing the correct result.

void vSlerp(btQuaternion& start, btQuaternion& end, float t, btQuaternion& result)
{

start = start.normalize();
end = end.normalize();

float dot = start.dot(end);

if (dot > 0.999995)
{
result=start;
}
else if (dot >= 0)
{
result = slerp(start,end,t); // Bullet quaternion slerp
}
else
{
result = slerp(start, -end, t); // avoid going the longer way around?
}

result.normalize();
}

Any idea or suggestion is greatly appreciated! Thanks!

##### Share on other sites

The bullet slerp should already be a a slerp function. Meaning that inside of it, there is already a way to deal with a shortest path; it is what slerp is made for.

Just use slerp() as is.

Here is a look into what your slerp function should look like.

Spoiler


void vSlerp(btQuaternion& start, btQuaternion& end, float t)
{

start = start.normalize();
end = end.normalize();

float dot = start.dot(end); //Finds the dot product

//We need the absolute value of dot
if (dot < 0){
dot = dot *-1; //don't know if your start.dot does this.
}

if (dot > 0.999995)
{
//Interpolate, this is where everything gets done
btQuaternion& Result = start + t*(end – start);//This is just liniar interpolation

dot = Result.normalize();
}

//Now if dot is negative it means it's taking the long path, we want it to take the shorter path
//To do this we reverse one of the Quaternion so that the rotation goes to the other side
else if (dot < 0)
{
end = end *-1;//Now it thinks the end is on the other side
dot = dot *-1;
}

//We want some kind of safty here because of floating point errors.
dot = clamp(dot,-1,1);

float StartToEndAngle = acos(dot);
float StartToResultAngle = StartToEndAngle * t;

Quaternion basis = end – start*dot;
basis.normalize();

//Now we should get a smooth animation with it always taking the shortest path
return start*cos(StartToResultAngle) + basis*sin(StartToResultAngle);
}

Edited by Scouting Ninja

## Create an account

Register a new account

1. 1
2. 2
Rutin
20
3. 3
4. 4
frob
15
5. 5

• 10
• 9
• 13
• 9
• 33
• ### Forum Statistics

• Total Topics
632592
• Total Posts
3007289

×