axis_rotation

odl.tomo.util.utility.axis_rotation(axis, angle, vectors, axis_shift=(0, 0, 0))[source]

Rotate a vector or an array of vectors around an axis in 3d.

The rotation is computed by Rodrigues' rotation formula.

Parameters:
axisarray-like, shape (3,)

Rotation axis, assumed to be a unit vector.

anglefloat

Angle of the counter-clockwise rotation.

vectorsarray-like, shape (3,) or (N, 3)

The vector(s) to be rotated.

axis_shiftarray_like, shape (3,), optional

Shift the rotation center by this vector. Note that only shifts perpendicular to axis matter.

Returns:
rot_vecnumpy.ndarray

The rotated vector(s).

References

Examples

Rotating around the third coordinate axis by and angle of 90 degrees:

>>> axis = (0, 0, 1)
>>> rot1 = axis_rotation(axis, angle=np.pi / 2, vectors=(1, 0, 0))
>>> np.allclose(rot1, (0, 1, 0))
True
>>> rot2 = axis_rotation(axis, angle=np.pi / 2, vectors=(0, 1, 0))
>>> np.allclose(rot2, (-1, 0, 0))
True

The rotation can be performed with shifted rotation center. A shift along the axis does not matter:

>>> rot3 = axis_rotation(axis, angle=np.pi / 2, vectors=(1, 0, 0),
...                      axis_shift=(0, 0, 2))
>>> np.allclose(rot3, (0, 1, 0))
True

The distance between the rotation center and the vector to be rotated determines the radius of the rotation circle:

>>> # Rotation center in the point to be rotated, should do nothing
>>> rot4 = axis_rotation(axis, angle=np.pi / 2, vectors=(1, 0, 0),
...                      axis_shift=(1, 0, 0))
>>> np.allclose(rot4, (1, 0, 0))
True
>>> # Distance 2, thus rotates to (0, 2, 0) in the shifted system,
>>> # resulting in (-1, 2, 0) from shifting back after rotating
>>> rot5 = axis_rotation(axis, angle=np.pi / 2, vectors=(1, 0, 0),
...                      axis_shift=(-1, 0, 0))
>>> np.allclose(rot5, (-1, 2, 0))
True

Rotation of multiple vectors can be done in bulk:

>>> vectors = [[1, 0, 0], [0, 1, 0]]
>>> rot = axis_rotation(axis, angle=np.pi / 2, vectors=vectors)
>>> np.allclose(rot[0], (0, 1, 0))
True
>>> np.allclose(rot[1], (-1, 0, 0))
True