psychopy.tools.mathtools.slerp

psychopy.tools.mathtools.slerp(q0, q1, t, shortest=True, out=None, dtype=None)[source]

Spherical linear interpolation (SLERP) between two quaternions.

The behaviour of this function depends on the types of arguments:

  • If q0 and q1 are both 1-D and t is scalar, the interpolation at t is returned.

  • If q0 and q1 are both 2-D Nx4 arrays and t is scalar, an Nx4 array is returned with each row containing the interpolation at t for each quaternion pair at matching row indices in q0 and q1.

Parameters:
  • q0 (array_like) – Initial quaternion in form [x, y, z, w] where w is real and x, y, z are imaginary components.

  • q1 (array_like) – Final quaternion in form [x, y, z, w] where w is real and x, y, z are imaginary components.

  • t (float) – Interpolation weight factor within interval 0.0 and 1.0.

  • shortest (bool, optional) – Ensure interpolation occurs along the shortest arc along the 4-D hypersphere (default is True).

  • out (ndarray, optional) – Optional output array. Must be same shape and dtype as the expected output if out was not specified.

  • dtype (dtype or str, optional) – Data type for computations can either be ‘float32’ or ‘float64’. If out is specified, the data type of out is used and this argument is ignored. If out is not provided, ‘float64’ is used by default.

Returns:

Quaternion [x, y, z, w] at t.

Return type:

ndarray

Examples

Interpolate between two orientations:

q0 = quatFromAxisAngle(90.0, degrees=True)
q1 = quatFromAxisAngle(-90.0, degrees=True)
# halfway between 90 and -90 is 0.0 or quaternion [0. 0. 0. 1.]
qr = slerp(q0, q1, 0.5)

Example of smooth rotation of an object with fixed angular velocity:

degPerSec = 10.0  # rotate a stimulus at 10 degrees per second

# initial orientation, axis rotates in the Z direction
qr = quatFromAxisAngle([0., 0., -1.], 0.0, degrees=True)
# amount to rotate every second
qv = quatFromAxisAngle([0., 0., -1.], degPerSec, degrees=True)

# ---- within main experiment loop ----
# `frameTime` is the time elapsed in seconds from last `slerp`.
qr = multQuat(qr, slerp((0., 0., 0., 1.), qv, degPerSec * frameTime))
_, angle = quatToAxisAngle(qr)  # discard axis, only need angle

# myStim is a GratingStim or anything with an 'ori' argument which
# accepts angle in degrees
myStim.ori = angle
myStim.draw()

Back to top