irfpy.util.eulerangle
¶
Implementation on Euler angle.
Euler angle is a set of three angles to represent any rotation in 3D.
See https://en.wikipedia.org/wiki/Euler_angles for better description.
EulerAngleZXZ
reporesents zxz-Euler angle.matrix3d_rot_vec_x()
,matrix3d_rot_vec_y()
,matrix3d_rot_vec_z()
gives the rotation matrix for vectors with respective to x, y, and z axis by a given angle.matrix3d_rot_frm_x()
,matrix3d_rot_frm_y()
,matrix3d_rot_frm_z()
gives the conversion matrix of the components of a vector when the axes of the frame are rotated around x, y, and z with a given angle.
- class irfpy.util.eulerangle.EulerAngleZXZ(alpha, beta, gamma)[source]¶
Bases:
object
Z-X-Z Euler angle
Z-X-Z Euler angle
Z-X-Z Euler angle, represented by the angles \(\alpha, \beta, \gamma\).
Also, see figure https://commons.wikimedia.org/wiki/File:Eulerangles.svg for reference.
- Parameters:
alpha – \(\alpha\) in radians. No restriction of the range.
beta – \(\beta\) in radians. No restriction of the range.
gamma – \(\gamma\) in radians. No restriction of the range.
Rotate \(\alpha\) with respective to z. Range -\(\pi\) to \(\pi\), theoretically
Rotate \(\beta\) with respective to new x. Range 0 to \(\pi\), theoretically
Rotate \(\gamma\) with respective to new z. Range -\(\pi\) to \(\pi\), theoretically
- get_matrix3d_rot_frm()[source]¶
Return the conversion matrix of the vector components.
Let us think a fixed vector. The vector is expressed by components of the original frame (x, y, z). Then, the frame (x, y, z) is rotated to (X, Y, Z) according to the Euler angles. The fixed vector is expressed by components of (X, Y, Z). The obtained matrix, R, shows the relation of
\[\begin{split}\left(\begin{array}{c} X \\ Y \\ Z \end{array}\right) = R\cdot \left(\begin{array}{c} x \\ y \\ z \end{array}\right)\end{split}\]- Returns:
(3, 3) shaped np.array, R
- get_matrix3d_rot_vec()[source]¶
Return the rotation matrix for the vector.
Let us think a vector in the original system, (x, y, z). The vector is rotated according to the Euler angles. The rotated vector is expressed in the original frame \((x', y', z')\).
The obtained matrix, M, exhibids the relation of
\[\begin{split}\left(\begin{array}{c} x' \\ y' \\ z' \end{array}\right) = M\cdot \left(\begin{array}{c} x \\ y \\ z \end{array}\right)\end{split}\]- Returns:
(3,3) shaped np.array, M
>>> import numpy as np >>> from irfpy.util.nptools import trim_epsilon as trim >>> alpha = np.pi / 2 # 90 deg >>> euler_zxz = EulerAngleZXZ(alpha, 0, 0) # This will give the rotation of axes of x -> y and y -> -x. >>> euler_m_vec = euler_zxz.get_matrix3d_rot_vec() >>> v2 = euler_m_vec.dot((1, 0, 0)) # x-axis is converted to y >>> print('{v[0]:.2f} {v[1]:.2f} {v[2]:.2f}'.format(v=trim(v2))) 0.00 1.00 0.00 >>> v2 = euler_m_vec.dot((0, 1, 0)) # y-axis is conveted to -x >>> print('{v[0]:.2f} {v[1]:.2f} {v[2]:.2f}'.format(v=trim(v2))) -1.00 0.00 0.00
>>> beta = np.pi / 2 # 90 deg >>> euler_zxz = EulerAngleZXZ(alpha, beta, 0) # This will give x->y->y, y->-x->z, z->z->x. >>> euler_m_vec = euler_zxz.get_matrix3d_rot_vec() >>> v2 = euler_m_vec.dot((1, 0, 0)) # x-axis is converted to y >>> print('{v[0]:.2f} {v[1]:.2f} {v[2]:.2f}'.format(v=trim(v2))) 0.00 1.00 0.00 >>> v2 = euler_m_vec.dot((0, 1, 0)) # y-axis is conveted to z >>> print('{v[0]:.2f} {v[1]:.2f} {v[2]:.2f}'.format(v=trim(v2))) 0.00 0.00 1.00 >>> v2 = euler_m_vec.dot((0, 0, 1)) # z-axis is conveted to x >>> print('{v[0]:.2f} {v[1]:.2f} {v[2]:.2f}'.format(v=trim(v2))) 1.00 0.00 0.00
>>> gamma = np.pi / 2 # 90 deg >>> euler_zxz = EulerAngleZXZ(alpha, beta, gamma) # This will give x->y->y->z, y->-x->z->-y, z->z->x->x. >>> euler_m_vec = euler_zxz.get_matrix3d_rot_vec() >>> v2 = euler_m_vec.dot((1, 0, 0)) # x-axis is converted to z >>> print('{v[0]:.2f} {v[1]:.2f} {v[2]:.2f}'.format(v=trim(v2))) 0.00 0.00 1.00 >>> v2 = euler_m_vec.dot((0, 1, 0)) # y-axis is conveted to -y >>> print('{v[0]:.2f} {v[1]:.2f} {v[2]:.2f}'.format(v=trim(v2))) 0.00 -1.00 0.00 >>> v2 = euler_m_vec.dot((0, 0, 1)) # z-axis is conveted to x >>> print('{v[0]:.2f} {v[1]:.2f} {v[2]:.2f}'.format(v=trim(v2))) 1.00 0.00 0.00
- rotate_vectors(vec)[source]¶
Rotate the vectors.
- Parameters:
vec – Vector, shaped with (…, 3)
- Returns:
The rotated vector. Same shape as input.
The vector is rotated according to the Euler angle. See
get_matrix3d_rot_vec()
.>>> import numpy as np >>> from irfpy.util.nptools import trim_epsilon as trimep # To trim the very small floating points from matrix >>> alpha = beta = gamma = np.pi / 2. >>> euler_zxz = EulerAngleZXZ(alpha, beta, gamma) # This will give x->y->y->z, y->-x->z->-y, z->z->x->x. >>> v1 = [1, 0, 0] >>> v2 = [0, 1, 0] >>> v3 = [0, 0, 1] >>> v4 = [-1, 0, 0] >>> v5 = [0, -1, 0] >>> v6 = [0, 0, -1] >>> v = np.array([v1, v2, v3, v4, v5, v6]) >>> print(v.shape) (6, 3)
>>> vr = euler_zxz.rotate_vectors(v) # Rotate six vectors at once. >>> print(vr.shape) (6, 3)
>>> print('{v[0]:.2f} {v[1]:.2f} {v[2]:.2f}'.format(v=trimep(vr[0]))) # +x to +z 0.00 0.00 1.00 >>> print('{v[0]:.2f} {v[1]:.2f} {v[2]:.2f}'.format(v=trimep(vr[1]))) # +y to -y 0.00 -1.00 0.00 >>> print('{v[0]:.2f} {v[1]:.2f} {v[2]:.2f}'.format(v=trimep(vr[2]))) # +z to +x 1.00 0.00 0.00 >>> print('{v[0]:.2f} {v[1]:.2f} {v[2]:.2f}'.format(v=trimep(vr[3]))) # -x to -z 0.00 0.00 -1.00 >>> print('{v[0]:.2f} {v[1]:.2f} {v[2]:.2f}'.format(v=trimep(vr[4]))) # -y to +y 0.00 1.00 0.00 >>> print('{v[0]:.2f} {v[1]:.2f} {v[2]:.2f}'.format(v=trimep(vr[5]))) # -z to -x -1.00 0.00 0.00
- irfpy.util.eulerangle.matrix3d_rot_vec_z(angle_radian)[source]¶
Return the 3D matrix that rotate a vector by a given angle with respective to z.
- Parameters:
angle_radian – The angle \(\theta\), in radians.
- Returns:
Matrix, M.
Theory
\[\begin{split}\mathbf{M} = \left(\begin{array}{ccc} \cos\theta & -\sin\theta & 0 \\ \sin\theta & \cos\theta & 0 \\ 0 & 0 & 1 \end{array}\right)\end{split}\]Any vector \(\vec{v}\) will be rotated by \(\theta\) with
\[\vec{v'} = \mathbf{M}\vec{v}\]y v' ^ v \ | / \ | / theta \<-|--/ \ | / \|/ +-----------------> x
Example
Obtain the 30 degree’s rotation matrix.
>>> import numpy as np >>> rot30z = matrix3d_rot_vec_z(np.deg2rad(30)) >>> print(rot30z) [[ 0.8660254 -0.5 0. ] [ 0.5 0.8660254 0. ] [ 0. 0. 1. ]]
The vector
(1, 0, 0)
will be rotated to(sqrt(3)/2, 1/2, 0)
>>> x0 = (1, 0, 0) >>> x1 = rot30z.dot(x0) >>> print(x1) [0.8660254 0.5 0. ]
The vector
(0, 1, 0)
will be rotated to(-1/2, sqrt(3)/2, 0)
>>> y0 = (0, 1, 0) >>> y1 = rot30z.dot(y0) >>> print(y1) [-0.5 0.8660254 0. ]
- irfpy.util.eulerangle.matrix3d_rot_frm_z(angle_radian)[source]¶
Return the 3D matrix that convert a vector to the frame rotated by a given angle with respective to z.
- Parameters:
angle_radian – The angle \(\alpha\), in radians.
- Returns:
The conversion matrix, R.
Theory
\[\begin{split}\mathbf{R} = \left(\begin{array}{ccc} \cos\theta & \sin\theta & 0 \\ -\sin\theta & \cos\theta & 0 \\ 0 & 0 & 1 \end{array}\right)\end{split}\]It is the inverse matrix of the matrix M obtained in
matrix3d_rot_vec_z()
. As M is an orthogonal matrix, the inverse is the same as transpose.\[R = M^{-1} (=M^{T})\]Let the original frame, (x, y, z), and rotate the frame by 45 degrees with respective to z axis. Let us denote the new frame as (X, Y, Z).
Then the components of the vector \(\vec{v}\) expressed in (x, y, z) frame is different from those in (X, Y, Z). The relation is
\[\vec{v}_{XYZ} = R \vec{v}_{xyz}\]y X Y ^ / v \ | / / \ | /\ / \ | / / \ | / / \ theta \|// \ +-----------------> x
>>> import numpy as np >>> vec_xyz = (1, 0, 0)
Then, consider a vector, \(\vec{v}=(1, 0, 0)\) in the original frame, (x, y, z). If we see the vector in the new frame (X, Y, Z). It can be done with
>>> r_mat = matrix3d_rot_frm_z(np.deg2rad(30)) >>> vec_XYZ = r_mat.dot(vec_xyz) >>> print(vec_XYZ) [ 0.8660254 -0.5 0. ]
- irfpy.util.eulerangle.matrix3d_rot_vec_x(angle_radian)[source]¶
Return the 3D matrix that rotate a vector by a given angle with respective to x.
- Parameters:
angle_radian – The angle \(\theta\), in radians.
- Returns:
Matrix, M.
Theory
\[\begin{split}\mathbf{M} = \left(\begin{array}{ccc} 1 & 0 & 0 \\ 0 & \cos\theta & -\sin\theta\\ 0 & \sin\theta & \cos\theta \end{array}\right)\end{split}\]z v' ^ v \ | / \ | / theta \<-|--/ \ | / \|/ +-----------------> y
Example
Obtain the 30 degree’s rotation matrix.
>>> import numpy as np >>> rot30x = matrix3d_rot_vec_x(np.deg2rad(30)) >>> print(rot30x) [[ 1. 0. 0. ] [ 0. 0.8660254 -0.5 ] [ 0. 0.5 0.8660254]]
The vector
(0, 1, 0)
will be rotated to(0, sqrt(3)/2, 1/2)
>>> y0 = (0, 1, 0) >>> y1 = rot30x.dot(y0) >>> print(y1) [0. 0.8660254 0.5 ]
The vector
(0, 0, 1)
will be rotated to(0, -1/2, sqrt(3)/2)
>>> z0 = (0, 0, 1) >>> z1 = rot30x.dot(z0) >>> print(z1) [ 0. -0.5 0.8660254]
- irfpy.util.eulerangle.matrix3d_rot_frm_x(angle_radian)[source]¶
Return the 3D matrix that convert a vector to the frame rotated by a given angle with respective to x.
- Parameters:
angle_radian – The angle \(\alpha\), in radians.
- Returns:
The conversion matrix, R.
Theory
\[\begin{split}\mathbf{R} = \left(\begin{array}{ccc} 1 & 0 & 0 \\ 0 & \cos\theta & \sin\theta \\ 0 & -\sin\theta & \cos\theta \end{array}\right)\end{split}\]It is the inverse matrix of the matrix M obtained in
matrix3d_rot_vec_x()
. As M is an orthogonal matrix, the inverse is the same as transpose.\[R = M^{-1} (=M^{T})\]Let the original frame, (x, y, z), and rotate the frame by 45 degrees with respective to x axis. Let us denote the new frame as (X, Y, Z).
Then the components of the vector \(\vec{v}\) expressed in (x, y, z) frame is different from those in (X, Y, Z). The relation is
\[\vec{v}_{XYZ} = R \vec{v}_{xyz}\]z Y Z ^ / v \ | / / \ | /\ / \ | / / \ | / / \ theta \|// \ +-----------------> y
>>> import numpy as np >>> vec_xyz = (0, 1, 0)
Then, consider a vector, \(\vec{v}=(0, 1, 0)\) in the original frame, (x, y, z). If we see the vector in the new frame (X, Y, Z). It can be done with
>>> r_mat = matrix3d_rot_frm_x(np.deg2rad(30)) >>> vec_XYZ = r_mat.dot(vec_xyz) >>> print(vec_XYZ) [ 0. 0.8660254 -0.5 ]
- irfpy.util.eulerangle.matrix3d_rot_vec_y(angle_radian)[source]¶
Return the 3D matrix that rotate a vector by a given angle with respective to y.
- Parameters:
angle_radian – The angle \(\theta\), in radians.
- Returns:
Matrix, M.
Theory
\[\begin{split}\mathbf{M} = \left(\begin{array}{ccc} \cos\theta & 0 & \sin\theta \\ 0 & 1 & 0 \\ -\sin\theta & 0 & \cos\theta \end{array}\right)\end{split}\]Any vector \(\vec{v}\) will be rotated by \(\theta\) with
\[\vec{v'} = \mathbf{M}\vec{v}\]x v' ^ v \ | / \ | / theta \<-|--/ \ | / \|/ +-----------------> z
Example
Obtain the 30 degree’s rotation matrix.
>>> import numpy as np >>> rot30y = matrix3d_rot_vec_y(np.deg2rad(30)) >>> print(rot30y) [[ 0.8660254 0. 0.5 ] [ 0. 1. 0. ] [-0.5 0. 0.8660254]]
The vector
(1, 0, 0)
will be rotated to(sqrt(3)/2, 0, -1/2)
>>> x0 = (1, 0, 0) >>> x1 = rot30y.dot(x0) >>> print(x1) [ 0.8660254 0. -0.5 ]
The vector
(0, 0, 1)
will be rotated to(1/2, 0, sqrt(3)/2)
>>> z0 = (0, 0, 1) >>> z1 = rot30y.dot(z0) >>> print(z1) [0.5 0. 0.8660254]
- irfpy.util.eulerangle.matrix3d_rot_frm_y(angle_radian)[source]¶
Return the 3D matrix that convert a vector to the frame rotated by a given angle with respective to y.
- Parameters:
angle_radian – The angle \(\alpha\), in radians.
- Returns:
The conversion matrix, R.
Theory
\[\begin{split}\mathbf{R} = \left(\begin{array}{ccc} \cos\theta & 0 & \sin\theta \\ 0 & 1 & 0 \\ -\sin\theta & 0 & \cos\theta \end{array}\right)\end{split}\]It is the inverse matrix of the matrix M obtained in
matrix3d_rot_vec_y()
. As M is an orthogonal matrix, the inverse is the same as transpose.\[R = M^{-1} (=M^{T})\]Let the original frame, (x, y, z), and rotate the frame by 45 degrees with respective to z axis. Let us denote the new frame as (X, Y, Z).
Then the components of the vector \(\vec{v}\) expressed in (x, y, z) frame is different from those in (X, Y, Z). The relation is
\[\vec{v}_{XYZ} = R \vec{v}_{xyz}\]x Z X ^ / v \ | / / \ | /\ / \ | / / \ | / / \ theta \|// \ +-----------------> z
>>> import numpy as np >>> vec_xyz = (1, 0, 0)
Then, consider a vector, \(\vec{v}=(1, 0, 0)\) in the original frame, (x, y, z). If we see the vector in the new frame (X, Y, Z). It can be done with
>>> r_mat = matrix3d_rot_frm_y(np.deg2rad(30)) >>> vec_XYZ = r_mat.dot(vec_xyz) >>> print(vec_XYZ) [0.8660254 0. 0.5 ]