Skip to content

SLERP

SLERP means Spherical Linear Interpolation.

It is used to smoothly move from one orientation quaternion to another.

1
2
3
t = 0.0  -> start orientation
t = 0.5  -> halfway orientation
t = 1.0  -> end orientation

SLERP is useful when you want a rotation to move smoothly and at a steady angular speed.

Common uses:

  • robot attitude interpolation
  • drone or gimbal motion
  • camera orientation animation
  • animation between two poses

Interactive demo

Move the t slider from 0 to 1.

The muted blue body is the start orientation q0. The muted orange body is the end orientation q1. The bright green body is the interpolated orientation q(t).

Formula

SLERP interpolates between two unit quaternions:

\[ SLERP(q_0, q_1, t) \]

where:

  • q0 is the start orientation
  • q1 is the end orientation
  • t is the interpolation amount from 0 to 1

The full equation is:

\[ SLERP(q_0, q_1, t) = \frac{\sin((1-t)\theta)}{\sin(\theta)}q_0 + \frac{\sin(t\theta)}{\sin(\theta)}q_1 \]

theta is the angle between q0 and q1.

Unit quaternions

SLERP expects unit quaternions. If a quaternion is not unit length, normalize it before interpolation.

Why not lerp?

Linear interpolation can cut through quaternion space and may change angular speed. SLERP follows the spherical path between orientations, so the rotation looks smooth and natural.


Demo: using scipy
import numpy as np
from scipy.spatial.transform import Rotation as R, Slerp

# Define two orientations (Euler angles in degrees)
r0 = R.from_euler('xyz', [0, 0, 0], degrees=True)     # facing forward
r1 = R.from_euler('xyz', [0, 90, 0], degrees=True)    # rotate 90° around Y

# Define key times and rotations
key_times = [0, 1]              # start=0, end=1
key_rots = R.concatenate([r0, r1])  # list of rotations

# Create SLERP object
slerp = Slerp(key_times, key_rots)

# Interpolation at multiple times
times = np.linspace(0, 1, 5)    # t=0.0,0.25,0.5,0.75,1.0
interp_rots = slerp(times)

# Print quaternions
print("Interpolated quaternions [x, y, z, w]:")
for q in interp_rots.as_quat():
    print(q.round(3))