RandomRotate#

class RandomRotate(angle=None, center=None, axis='z', always_apply=False, p=0.5)[source]#

Bases: object

Rotate the cloud by a random angle about one axis.

With probability p (forced to 1 when always_apply), draws an angle uniformly from angle (in units of pi radians) and rotates coord about the chosen axis around center in place. The same rotation is applied to v3 vertex metadata, to aux_position_keys, to normal, and – as the linear part only, re-normalized – to aux_direction_keys. When center is None the bounding-box center is used. Requires coord. Registered as RandomRotate – use this string as the type in a transform=[...] config list.

Parameters:
  • angle (Sequence[float], optional) – [low, high] range, in units of pi radians, to sample the rotation angle from. None means [-1, 1] (full +/- pi). Defaults to None.

  • center (Sequence[float], optional) – rotation center. None uses the per-sample bounding-box center. Defaults to None.

  • axis (str) – rotation axis, one of "x", "y", "z". Defaults to "z".

  • always_apply (bool) – if True, always rotate (overrides p to 1). Defaults to False.

  • p (float) – probability of applying the rotation when not always_apply. Defaults to 0.5.

Note

The angle is expressed in multiples of pi, so angle=[-1, 1] spans a full turn. Chain three instances (one per axis) for full 3D rotation.

Example

>>> import numpy as np
>>> from pimm.datasets.transform import RandomRotate
>>> data = {"coord": np.array([[1., 0., 0.], [0., 1., 0.]], dtype="f4")}
>>> # angle=[0.5, 0.5] -> exactly 0.5*pi (90 deg) about z; always_apply forces it
>>> out = RandomRotate(angle=[0.5, 0.5], axis="z", center=[0, 0, 0],
...                    always_apply=True)(data)
>>> np.round(out["coord"], 3)  # +x -> +y, +y -> -x
array([[ 0.,  1.,  0.],
       [-1.,  0.,  0.]])