Rotate points by angles according to axis. Args: points (np.ndarray or Tensor): Points with shape (N, M, 3). angles (np.ndarray or Tensor or float): Vector of angles with shape (N, ). axis (int): The axis to be rotated. Defaults to 0. return_mat (bool
(
points: Union[np.ndarray, Tensor],
angles: Union[np.ndarray, Tensor, float],
axis: int = 0,
return_mat: bool = False,
clockwise: bool = False
)
| 88 | |
| 89 | @array_converter(apply_to=('points', 'angles')) |
| 90 | def rotation_3d_in_axis( |
| 91 | points: Union[np.ndarray, Tensor], |
| 92 | angles: Union[np.ndarray, Tensor, float], |
| 93 | axis: int = 0, |
| 94 | return_mat: bool = False, |
| 95 | clockwise: bool = False |
| 96 | ) -> Union[Tuple[np.ndarray, np.ndarray], Tuple[Tensor, Tensor], np.ndarray, |
| 97 | Tensor]: |
| 98 | """Rotate points by angles according to axis. |
| 99 | |
| 100 | Args: |
| 101 | points (np.ndarray or Tensor): Points with shape (N, M, 3). |
| 102 | angles (np.ndarray or Tensor or float): Vector of angles with shape |
| 103 | (N, ). |
| 104 | axis (int): The axis to be rotated. Defaults to 0. |
| 105 | return_mat (bool): Whether or not to return the rotation matrix |
| 106 | (transposed). Defaults to False. |
| 107 | clockwise (bool): Whether the rotation is clockwise. Defaults to False. |
| 108 | |
| 109 | Raises: |
| 110 | ValueError: When the axis is not in range [-3, -2, -1, 0, 1, 2], it |
| 111 | will raise ValueError. |
| 112 | |
| 113 | Returns: |
| 114 | Tuple[np.ndarray, np.ndarray] or Tuple[Tensor, Tensor] or np.ndarray or |
| 115 | Tensor: Rotated points with shape (N, M, 3) and rotation matrix with |
| 116 | shape (N, 3, 3). |
| 117 | """ |
| 118 | batch_free = len(points.shape) == 2 |
| 119 | if batch_free: |
| 120 | points = points[None] |
| 121 | |
| 122 | if isinstance(angles, float) or len(angles.shape) == 0: |
| 123 | angles = torch.full(points.shape[:1], angles) |
| 124 | |
| 125 | assert len(points.shape) == 3 and len(angles.shape) == 1 and \ |
| 126 | points.shape[0] == angles.shape[0], 'Incorrect shape of points ' \ |
| 127 | f'angles: {points.shape}, {angles.shape}' |
| 128 | |
| 129 | assert points.shape[-1] in [2, 3], \ |
| 130 | f'Points size should be 2 or 3 instead of {points.shape[-1]}' |
| 131 | |
| 132 | rot_sin = torch.sin(angles) |
| 133 | rot_cos = torch.cos(angles) |
| 134 | ones = torch.ones_like(rot_cos) |
| 135 | zeros = torch.zeros_like(rot_cos) |
| 136 | |
| 137 | if points.shape[-1] == 3: |
| 138 | if axis == 1 or axis == -2: |
| 139 | rot_mat_T = torch.stack([ |
| 140 | torch.stack([rot_cos, zeros, -rot_sin]), |
| 141 | torch.stack([zeros, ones, zeros]), |
| 142 | torch.stack([rot_sin, zeros, rot_cos]) |
| 143 | ]) |
| 144 | elif axis == 2 or axis == -1: |
| 145 | rot_mat_T = torch.stack([ |
| 146 | torch.stack([rot_cos, rot_sin, zeros]), |
| 147 | torch.stack([-rot_sin, rot_cos, zeros]), |
no outgoing calls
no test coverage detected