* @param alpha alpha in the range [0,1]\r
* @return this quaternion for chaining */\r
public Quaternion slerp (Quaternion end, float alpha) {\r
- if (this.equals(end)) {\r
- return this;\r
- }\r
-\r
- float result = dot(end);\r
-\r
- if (result < 0.0) {\r
- // Negate the second quaternion and the result of the dot product\r
- end.mul(-1);\r
- result = -result;\r
- }\r
+ final float dot = dot(end);\r
+ float absDot = dot < 0.f ? -dot : dot;\r
\r
// Set the first and second scale for the interpolation\r
float scale0 = 1 - alpha;\r
\r
// Check if the angle between the 2 quaternions was big enough to\r
// warrant such calculations\r
- if ((1 - result) > 0.1) {// Get the angle between the 2 quaternions,\r
+ if ((1 - absDot) > 0.1) {// Get the angle between the 2 quaternions,\r
// and then store the sin() of that angle\r
- final double theta = Math.acos(result);\r
- final double invSinTheta = 1f / Math.sin(theta);\r
+ final double angle = Math.acos(absDot);\r
+ final double invSinTheta = 1f / Math.sin(angle);\r
\r
// Calculate the scale for q1 and q2, according to the angle and\r
// it's sine value\r
- scale0 = (float)(Math.sin((1 - alpha) * theta) * invSinTheta);\r
- scale1 = (float)(Math.sin((alpha * theta)) * invSinTheta);\r
+ scale0 = (float)(Math.sin((1 - alpha) * angle) * invSinTheta);\r
+ scale1 = (float)(Math.sin((alpha * angle)) * invSinTheta);\r
}\r
\r
+ if (dot < 0.f)\r
+ scale1 = -scale1;\r
+ \r
// Calculate the x, y, z and w values for the quaternion by using a\r
// special form of linear interpolation for quaternions.\r
- final float x = (scale0 * this.x) + (scale1 * end.x);\r
- final float y = (scale0 * this.y) + (scale1 * end.y);\r
- final float z = (scale0 * this.z) + (scale1 * end.z);\r
- final float w = (scale0 * this.w) + (scale1 * end.w);\r
- set(x, y, z, w);\r
+ x = (scale0 * x) + (scale1 * end.x);\r
+ y = (scale0 * y) + (scale1 * end.y);\r
+ z = (scale0 * z) + (scale1 * end.z);\r
+ w = (scale0 * w) + (scale1 * end.w);\r
\r
// Return the interpolated quaternion\r
return this;\r