Source code for giant.rotations.core.elementals

import numpy as np

from giant._typing import SCALAR_OR_ARRAY, ARRAY_LIKE, DOUBLE_ARRAY
from giant.rotations.core._helpers import _check_vector_array_and_shape


__all__ = ["rot_x", "rot_y", "rot_z", "skew"]


[docs] def rot_x(theta: SCALAR_OR_ARRAY) -> DOUBLE_ARRAY: r""" This function performs a right handed rotation about the x axis by angle theta. Mathematically this rotation is defined as: .. math:: \mathbf{R}_x(\theta)=\left[\begin{array}{ccc} 1 & 0 & 0 \\ 0 & \text{cos}(\theta) & -\text{sin}(\theta) \\ 0 & \text{sin}(\theta) & \text{cos}(\theta) \end{array}\right] Theta should be in units of radians and can be a scalar or a vector. If theta is a vector then each theta value will have a corresponding rotation vector down the first axis of the output. For example:: >>> from giant.rotations import rot_x >>> rot_x([2, 0.5]) array([[[ 1. , 0. , 0. ], [ 0. , -0.41614684, -0.90929743], [ 0. , 0.90929743, -0.41614684]], [[ 1. , 0. , 0. ], [ 0. , 0.87758256, -0.47942554], [ 0. , 0.47942554, 0.87758256]]]) :param theta: The angles to form the rotation matrix(ces) for :return: The rotation matrix(ces) corresponding to the rotation angle(s) """ # ensure we have an array of theta(s) theta = np.atleast_1d(np.asarray(theta)).flatten() # form an array of ones the same shape as theta ones = np.ones(theta.shape) # form an array of zeros the same shape as theta zeros = np.zeros(theta.shape) # compute the cosine of theta ctheta = np.cos(theta) # compute the sine of theta stheta = np.sin(theta) # form and return the matrix(ces) return np.vstack([ones, zeros, zeros, zeros, ctheta, -stheta, zeros, stheta, ctheta]).T.reshape(-1, 3, 3).squeeze()
[docs] def rot_y(theta: SCALAR_OR_ARRAY) -> DOUBLE_ARRAY: r""" This function performs a right handed rotation about the y axis by angle theta. This rotation is defined as: .. math:: \mathbf{R}_y(\theta)=\left[\begin{array}{ccc} \text{cos}(\theta) & 0 & \text{sin}(\theta) \\ 0 & 1 & 0 \\ -\text{sin}(\theta) & 0 & \text{cos}(\theta) \end{array}\right] Theta should be in units of radians and can be a scalar or a vector. If theta is a vector then each theta value will have a corresponding rotation vector down the first axis of the output. For example:: >>> from giant.rotations import rot_y >>> rot_y([2, 0.5]) array([[[-0.41614684, 0. , 0.90929743], [ 0. , 1. , 0. ], [-0.90929743, 0. , -0.41614684]], [[ 0.87758256, 0. , 0.47942554], [ 0. , 1. , 0. ], [-0.47942554, 0. , 0.87758256]]]) :param theta: The angles to form the rotation matrix(ces) for :return: The rotation matrix(ces) corresponding to the rotation angle(s) """ # ensure we have an array of theta(s) theta = np.atleast_1d(np.asarray(theta)).flatten() # form an array of ones the same shape as theta ones = np.ones(theta.shape) # form an array of zeros the same shape as theta zeros = np.zeros(theta.shape) # compute the cosine of theta ctheta = np.cos(theta) # compute the sine of theta stheta = np.sin(theta) # form and return the matrix(ces) return np.vstack([ctheta, zeros, stheta, zeros, ones, zeros, -stheta, zeros, ctheta]).T.reshape(-1, 3, 3).squeeze()
[docs] def rot_z(theta: SCALAR_OR_ARRAY) -> DOUBLE_ARRAY: r""" This function performs a right handed rotation about the z axis by angle theta. This rotation is defined as: .. math:: \mathbf{R}_z(\theta)=\left[\begin{array}{ccc} \text{cos}(\theta) & -\text{sin}(\theta) & 0 \\ \text{sin}(\theta) & \text{cos}(\theta) & 0 \\ 0 & 0 & 1 \end{array}\right] Theta should be in units of radians and can be a scalar or a vector. If theta is a vector then each theta value will have a corresponding rotation vector down the first axis of the output. For example:: >>> from giant.rotations import rot_z >>> rot_z([2, 0.5]) array([[[-0.41614684, -0.90929743, 0. ], [ 0.90929743, -0.41614684, 0. ], [ 0. , 0. , 1. ]], [[ 0.87758256, -0.47942554, 0. ], [ 0.47942554, 0.87758256, 0. ], [ 0. , 0. , 1. ]]]) :param theta: The angles to form the rotation matrix(ces) for :return: The rotation matrix(ces) corresponding to the rotation angle(s) """ # ensure we have an array of theta(s) theta = np.atleast_1d(np.asarray(theta)).flatten() # form an array of ones the same shape as theta ones = np.ones(theta.shape) # form an array of zeros the same shape as theta zeros = np.zeros(theta.shape) # compute the cosine of theta ctheta = np.cos(theta) # compute the sine of theta stheta = np.sin(theta) # form and return the matrix(ces) return np.vstack([ctheta, -stheta, zeros, stheta, ctheta, zeros, zeros, zeros, ones]).T.reshape(-1, 3, 3).squeeze()
[docs] def skew(vector: ARRAY_LIKE) -> DOUBLE_ARRAY: r""" This function returns a numpy array with the skew symmetric cross product matrix for vector. The skew symmetric cross product matrix is defined such that: .. math:: \mathbf{a}\times\mathbf{b}=\left[\mathbf{a}\times\right]\mathbf{b} \\ \left[\mathbf{a}\times\right] = \left[\begin{array}{ccc} 0 & -a_3 & a_2 \\ a_3 & 0 & -a_1 \\ -a_2 & a_1 & 0 \end{array}\right] where :math:`\times` indicates the cross product and :math:`\left[\bullet\times\right]` is the skew symmetric cross product matrix This function is vectorized, therefore you can input multiple vectors as a 3xn array where each column is an independent vector. The resulting skew matrix output will be nx3x3 where the first axis stores each matrix :param vector: The vector to compute a skew symmetric matrix for :return: The skew symmetric cross product matrix(ces) corresponding to the vector(s) """ vector = _check_vector_array_and_shape(vector) if vector.ndim > 1: zeros = np.zeros(vector.shape[-1]) else: zeros = 0 return np.array([zeros, -vector[2], vector[1], vector[2], zeros, -vector[0], -vector[1], vector[0], zeros]).T.reshape(-1, 3, 3).squeeze()