rot_a_to_b๏
- plasmapy.formulary.mathematics.rot_a_to_b(a: ndarray, b: ndarray) ndarray [source]๏
Calculates the 3D rotation matrix that will rotate vector
a
to be aligned with vectorb
.- Parameters:
a (
ndarray
, shape (3,)) โ Vector to be rotated. Should be a 1D, 3-element unit vector. Ifa
is not normalized, then it will be normalized.b (
ndarray
, shape (3,)) โ Vector representing the desired orientation after rotation. Should be a 1D, 3-element unit vector. Ifb
is not normalized, then it will be.
- Returns:
R โ The rotation matrix that will rotate vector
a
onto vectorb
.- Return type:
ndarray
, shape (3,3)- Raises:
ValueError โ If the argument is not of shape (3,).
Notes
The rotation matrix is calculated as follows. Let
\[\vec v = \vec a ร \vec b\]and let \(ฮธ\) be the angle between \(\vec a\) and \(\vec b\) such that the projection of \(\vec a\) along \(\vec b\) is
\[c = \vec a ยท \vec b \cos{ฮธ}\]Then the rotation matrix \(R\) is
\[R = I + v_x + v_x^2 \frac{1}{1 + c}\]where \(I\) is the identity matrix and \(v_x\) is the skew-symmetric cross-product matrix of \(v\) defined as
\[\begin{split}v_x = \begin{bmatrix} 0 & -v_3 & v_2 \\ v_3 & 0 & -v_1 \\ -v_2 & v_1 & 0 \end{bmatrix}\end{split}\]Note that this algorithm fails when \(1+c=0\), which occurs when \(a\) and \(b\) are anti-parallel. However, since the correct rotation matrix in this case is simply \(R=-I\), this function just handles this special case explicitly.
This algorithm is based on this discussion on StackExchange.
Examples
>>> a = np.array([0., 1., 0.]) >>> b = np.array([1., 0., 0.]) >>> rot_a_to_b(a, b) array([[ 0., -1., 0.], [ 1., 0., 0.], [ 0., 0., 1.]]) >>> a = np.array([-0.14, 2.2, 3.98]) >>> b = np.array([9.10, 4.17, -9.35]) >>> rot_a_to_b(a, b) array([[ 0.20118147, -0.9613676 , -0.18787857], [-0.30014001, 0.12207629, -0.94605145], [ 0.93243873, 0.2467179 , -0.2639854 ]])