public final void interpolate ( Quaternion q1 , double alpha ) { // From "Advanced Animation and Rendering Techniques" // by Watt and Watt pg. 364, function as implemented appeared to be // incorrect. Fails to choose the same quaternion for the double // covering. Resulting in change of direction for rotations. // Fixed function to negate the first quaternion in the case that the // dot product of q1 and this is negative. Second case was not needed. double dot , s1 , s2 , om , sinom ; dot = this . x * q1 . x + this . y * q1 . y + this . z * q1 . z + this . w * q1 . w ; if ( dot < 0 ) { // negate quaternion q1 . x = - q1 . x ; q1 . y = - q1 . y ; q1 . z = - q1 . z ; q1 . w = - q1 . w ; dot = - dot ; } if ( ( 1.0 - dot ) > EPS ) { om = Math . acos ( dot ) ; sinom = Math . sin ( om ) ; s1 = Math . sin ( ( 1.0 - alpha ) * om ) / sinom ; s2 = Math . sin ( alpha * om ) / sinom ; } else { s1 = 1.0 - alpha ; s2 = alpha ; } this . w = ( s1 * this . w + s2 * q1 . w ) ; this . x = ( s1 * this . x + s2 * q1 . x ) ; this . y = ( s1 * this . y + s2 * q1 . y ) ; this . z = ( s1 * this . z + s2 * q1 . z ) ; }
Performs a great circle interpolation between this quaternion and the quaternion parameter and places the result into this quaternion .