# Rotation Matrices

## Definition of rotation matrices

- `rotmat.R()` ... 3D rotation matrix for rotation about a coordinate axis

## Conversion Routines

- `rotmat.convert()` ... Convert a rotation matrix to the corresponding quaternion
- `rotmat.sequence()` ... Calculation of Euler, Fick, Helmholtz, ... angles

## Symbolic matrices

- `rotmat.R_s()` ... symbolix matrix for rotation about a coordinate axis

For example, you can e.g. generate a Fick-matrix, with

> R_Fick = R_s(2, ‘theta’) * R_s(1, ‘phi’) * R_s(0, ‘psi’)

## Details

Routines for working with rotation matrices

`rotmat.``R`(axis=0, angle=90)

  Rotation matrix for rotation about a cardinal axis. The argument is entered in degree.

  Parameters: | axis (skalar) – Axis of rotation, has to be 0, 1, or 2 alpha (float) – rotation angle [deg]
  Returns: | R
  Return type: | rotation matrix, for rotation about the specified axis

  Examples

      >>> rotmat.R(axis=0, alpha=45)
      array([[ 1.        ,  0.        ,  0.        ],
             [ 0.        ,  0.70710678, -0.70710678],
             [ 0.        ,  0.70710678,  0.70710678]])

      >>> rotmat.R(axis=0)
      array([[ 1.        ,  0.        ,  0.        ],
             [ 0.        ,  0.        , -1.        ],
             [ 0.        ,  1.        ,  0.       ]])

      >>> rotmat.R(1, 45)
      array([[ 0.70710678,  0.        ,  0.70710678],
             [ 0.        ,  1.        ,  0.        ],
             [-0.70710678,  0.        ,  0.70710678]])

      >>> rotmat.R(axis=2, alpha=45)
      array([[ 0.70710678, -0.70710678,  0.        ],
             [ 0.70710678,  0.70710678,  0.        ],
             [ 0.        ,  0.        ,  1.        ]])

`rotmat.``R1`(psi)
  Rotation about the 1-axis.
    Deprecated, use R(0, psi)

  Deprecated in 2.0, to be removed in 2.2. Use the ``R(0, angle)`` function instead

`rotmat.``R1_s`()

  > Symbolic rotation matrix about the 1-axis, by an angle psi Deprecated. Use R_s(0, ‘psi’)

  Deprecated in 2.0, to be removed in 2.2. Use the ``R_s(0, ‘psi’)`` function instead

`rotmat.``R2`(phi)
  Rotation about the 2-axis.
    Deprecated, use R(1, phi)

  Deprecated in 2.0, to be removed in 2.2. Use the ``R(1, angle)`` function instead

`rotmat.``R2_s`()

  > Symbolic rotation matrix about the 2-axis, by an angle phi Deprecated. Use R_s(1, ‘phi’)

  Deprecated in 2.0, to be removed in 2.2. Use the ``R_s(1, ‘phi’)`` function instead

`rotmat.``R3`(theta)
  Rotation about the 3-axis.
    Deprecated, use R(2, theta)

  Deprecated in 2.0, to be removed in 2.2. Use the ``R(2, angle)`` function instead

`rotmat.``R3_s`()

  > Symbolic rotation matrix about the 3-axis, by an angle theta Deprecated. Use R_s(2, ‘theta’)

  Deprecated in 2.0, to be removed in 2.2. Use the ``R_s(2, ‘alpha’)`` function instead

`rotmat.``R_s`(axis=0, angle='alpha')

  Symbolic rotation matrix about the given axis, by an angle with the given name

  Returns: | R_symbolic
  Return type: | symbolic matrix for rotation about the given axis

  Examples

      >>> R_yaw = R_s(axis=2, angle='theta')

      >>> R_aero = R_s(2) * R_s(1) * R_s(0)

`rotmat.``convert`(rMat, to='quat')

  Converts a rotation matrix to the corresponding quaternion. Assumes that R has the shape (3,3), or the matrix elements in columns

  Parameters: | rMat (array, shape (3,3) or (N,9)) – single rotation matrix, or matrix with rotation-matrix elements. to (string) – Currently, only ‘quat’ is supported
  Returns: | outQuat – corresponding quaternion vector(s)
  Return type: | array, shape (4,) or (N,4)

  Notes

  \[\begin{split}\vec q = 0.5*copysign\left( {\begin{array}{*{20}{c}} {\sqrt {1 + {R_{11}} - {R_{22}} - {R_{33}}} ,}\\ {\sqrt {1 - {R_{11}} + {R_{22}} - {R_{33}}} ,}\\ {\sqrt {1 - {R_{11}} - {R_{22}} + {R_{33}}} ,} \end{array}\begin{array}{*{20}{c}} {{R_{32}} - {R_{23}}}\\ {{R_{13}} - {R_{31}}}\\ {{R_{21}} - {R_{12}}} \end{array}} \right)\end{split}\]

  More info under http://en.wikipedia.org/wiki/Quaternion

  Examples

      >>> rotMat = array([[cos(alpha), -sin(alpha), 0],
      >>>    [sin(alpha), cos(alpha), 0],
      >>>    [0, 0, 1]])
      >>> rotmat.convert(rotMat, 'quat')
      array([[ 0.99500417,  0.        ,  0.        ,  0.09983342]])

`rotmat.``rotmat2Euler`(R)

  > This function takes a rotation matrix, and calculates the corresponding Euler-angles. Deprecated. Use “sequence(R, ‘Euler’)”

  Deprecated in 2.0, to be removed in 2.2. Use the ``sequence(R, ‘Euler’)`` function instead

`rotmat.``rotmat2Fick`(R)

  > This function takes a rotation matrix, and calculates the corresponding Fick-angles. Deprecated. Use “sequence(R, ‘Fick’)”

  Deprecated in 2.0, to be removed in 2.2. Use the ``sequence(R, ‘Fick’)`` function instead

`rotmat.``rotmat2Helmholtz`(R)

  > This function takes a rotation matrix, and calculates the corresponding Helmholtz-angles. Deprecated. Use “sequence(R, ‘Helmholtz’)”

  Deprecated in 2.0, to be removed in 2.2. Use the ``sequence(R, ‘Helmholtz’)`` function instead

`rotmat.``sequence`(R, to='Euler')

  This function takes a rotation matrix, and calculates the corresponding angles for sequential rotations.

  R_Euler = R3(gamma) * R1(beta) * R3(alpha)

  Parameters: | R (ndarray, 3x3) – rotation matrix to (string) – Has to be one the following: - Euler ... Rz * Rx * Rz - Fick ... Rz * Ry * Rx - aero ... same as “Fick” - Helmholtz ... Ry * Rz * Rx
  Returns: | alpha (first rotation(right-most matrix)) beta (second rotation) gamma (third rotation (left-most matrix))

  Notes

  The following formulas are used:

  Euler:

  \[ \begin{align}\begin{aligned}\beta = -arcsin(\sqrt{ R_{13}^2 + R_{23}^2 }) * sign(R_{23})\\\gamma = arcsin(\frac{R_{13}}{sin\beta})\\\alpha = arcsin(\frac{R_{31}}{sin\beta})\end{aligned}\end{align} \]

  aero / Fick:

  \[ \begin{align}\begin{aligned}\theta = arctan(\frac{R_{21}}{R_{11}})\\\phi = arcsin(R_{31})\\\psi = arctan(\frac{R_{32}}{R_{33}})\end{aligned}\end{align} \]

  Note that it is assumed that psi < pi !

  Helmholtz:

  \[ \begin{align}\begin{aligned}\theta = arcsin(R_{21})\\\phi = -arcsin(\frac{R_{31}}{cos\theta})\\\psi = -arcsin(\frac{R_{23}}{cos\theta})\end{aligned}\end{align} \]

  Note that it is assumed that psi < pi