[Math] Is this algorithm for 3D spherical interpolation correct

dynamic programminginterpolationspherical-geometry

I am attempting to write a spherical interpolation algorithm for for the application of smooth 3D animation in a game. The scripting language that the game engine uses is Lua. It is often easier for me to write an algorithm for 2D first and then 3D second, so I came up with the following (untested) algorithm for 2D spherical interpolation:

function slerp( x, y, x1, y1, t )
   local rad = t * math.acos( x*x1 + y*y1 )
   local newX = x * math.cos( rad ) - y * math.sin( rad )
   local newY = x * math.sin( rad ) + y * math.cos( rad )
   return newX, newY
end

From what I understand, the above formula should calculate a fraction of the radian angle between two 2D unit vectors and then rotate counterclockwise x and y by that fractional angle. For the 3D algorithm, I thought about changing the above code to the following:

function slerp( x, y, z, x1, y1, z1, t )
   local rad = t * math.acos( x*x1 + y*y1 + z * z1 )
   local newX = x * math.cos( rad ) - y * math.sin( rad )
   local newY = x * math.sin( rad ) + y * math.cos( rad )
   local newZ = z * math.cos( rad ) - x * math.sin( rad )
   return newX, newY, newZ
end

My question is the following 2 points:

  • Is my algorithm a correct implementation of spherical interpolation?
  • Is there a less expensive way of calculating spherical interpolation in 3D (preferably with a thorough explanation )?

Best Answer

No, your algorithm is not a correct implementation (if by "spherical interpolation" you mean this).

In the two-dimensional case, you were able to calculate the new point using only the point $(x,y)$ (using $(x_1,y_1)$ only to calculate the angle, but not as a component of a linear combination) because in two dimensions there is only one direction to rotate $(x,y)$ into, namely $(-y,x)$, so you don't need to use $(x_1,y_1)$ to rotate in its direction.

In three dimensions, this is different. Given a vector $(x,y,z)$, there are two linearly independent directions that are perpendicular to it, and you don't know which direction to rotate into without using the point $(x_1,y_1,z_1)$ that tells you. (In fact you're not even multiplying the sine by a vector that's perpendicular to $(x,y,z)$, so the result doesn't even lie on the sphere, let alone on the great circle through $(x_1,y_1,z_1)$.)

As regards your question about a more efficient way to do this, as far as I'm aware the Wikipedia article (linked to above) describes correctly how it's usually done, both using vectors and using quaternions.