0
$\begingroup$

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 )?
$\endgroup$
0
$\begingroup$

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.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.