Common Methods for Rotations

rotation_angle, rotation_axis

3D

A rotation matrix can be expressed with one rotation around an axis and angle. these function can calculate these values.

example

julia> R = RotXYZ(2.4, -1.8, 0.5)3×3 RotXYZ{Float64} with indices SOneTo(3)×SOneTo(3)(2.4, -1.8, 0.5):
 -0.199389   0.108926  -0.973848
 -0.930798  -0.331759   0.153467
 -0.306366   0.937055   0.167537
julia> θ = rotation_angle(R)2.3210234148741837
julia> n = rotation_axis(R) # These matrices are approximately equal.3-element StaticArraysCore.SVector{3, Float64} with indices SOneTo(3): 0.5355785581183807 -0.4562206495732595 -0.7106464148835127
julia> R ≈ AngleAxis(θ, n...)true

2D

julia> R = Angle2d(2.4)2×2 Angle2d{Float64} with indices SOneTo(2)×SOneTo(2)(2.4):
 -0.737394  -0.675463
  0.675463  -0.737394
julia> θ = rotation_angle(R)2.4

Rotations.params

The parameters of the rotation can be obtained by Rotations.params.

example

julia> R = one(RotMatrix{3})  # Identity matrix3×3 RotMatrix3{Bool} with indices SOneTo(3)×SOneTo(3):
 1  0  0
 0  1  0
 0  0  1
julia> Rotations.params(RotYZY(R)) # Proper Euler angles, (y,z,y)3-element StaticArraysCore.SVector{3, Float64} with indices SOneTo(3): 0.0 0.0 0.0
julia> Rotations.params(RotXYZ(R)) # Tait–Bryan angles, (x,y,z)3-element StaticArraysCore.SVector{3, Float64} with indices SOneTo(3): 0.0 0.0 0.0
julia> Rotations.params(AngleAxis(R)) # Rotation around an axis (theta, axis_x, axis_y, axis_z)4-element StaticArraysCore.SVector{4, Float64} with indices SOneTo(4): 0.0 1.0 0.0 0.0
julia> Rotations.params(RotationVec(R)) # Rotation vector (v_x, v_y, v_z)3-element StaticArraysCore.SVector{3, Float64} with indices SOneTo(3): 0.0 0.0 0.0
julia> Rotations.params(QuatRotation(R)) # Quaternion (w, x, y, z)4-element StaticArraysCore.SVector{4, Float64} with indices SOneTo(4): 1.0 0.0 0.0 0.0
julia> Rotations.params(RodriguesParam(R)) # Rodrigues Parameters (x, y, z)3-element StaticArraysCore.SVector{3, Float64} with indices SOneTo(3): 0.0 0.0 0.0
julia> Rotations.params(MRP(R)) # Modified Rodrigues Parameters (x, y, z)3-element StaticArraysCore.SVector{3, Float64} with indices SOneTo(3): 0.0 0.0 0.0

isrotation

Check the given matrix is rotation matrix.

example

(TBW)

nearest_rotation

Get the nearest special orthonormal matrix from given matrix M. The problem of finding the orthogonal matrix nearest to a given matrix is related to the Wahba's problem.

example

julia> M = randn(3,3)  # Generate random matrix3×3 Matrix{Float64}:
 1.13191    1.28938    0.149988
 0.523156  -0.546136  -0.773541
 0.875881   1.52741   -0.853885
julia> R = nearest_rotation(M) # Find the nearest rotation matrix3×3 RotMatrix3{Float64} with indices SOneTo(3)×SOneTo(3): 0.803426 0.379156 0.459071 0.59392 -0.564759 -0.57298 0.0420156 0.732999 -0.678931
julia> U, V = R\M, M/R # Polar decomposition of M([1.256919252027621 0.7757340108879696 -0.37479346841586086; 0.7757340108879692 1.9169002205373529 -0.13216331039499596; -0.37479346841586086 -0.13216331039499657 1.0918078841032115], [1.4671368505701312 -0.14186446057345517 0.890838872515663; -0.1418644605734549 1.0623717832048662 0.14684445838264967; 0.8908388725156621 0.1468444583826493 1.7361187228931878])
julia> U ≈ U' # U is a symmetric matrix (The same for V)true

rand

rand for $SO(2)$

The following types have the same algebraic structure as $SO(2)$

  • RotMatrix{2}
  • Angle2d
  • RotX
  • RotY
  • RotZ

The random distribution is based on Haar measure.

example

julia> R = rand(Angle2d)2×2 Angle2d{Float64} with indices SOneTo(2)×SOneTo(2)(6.14632):
  0.990648  0.136443
 -0.136443  0.990648

rand for $SO(3)$

The following types have an algebraic structure that is homomorphic to $SO(3)$.

  • RotMatrix{3}
  • RotXYZ (and other Euler angles)
  • AngleAxis
  • RotationVec
  • QuatRotation
  • RodriguesParam
  • MRP

example

julia> R = rand(RotationVec)3×3 RotationVec{Float64} with indices SOneTo(3)×SOneTo(3)(-1.55778, 2.24923, -0.610538):
 -0.34323   -0.794176   0.501475
 -0.938737   0.307729  -0.155166
 -0.031089  -0.524011  -0.851144

The random distribution is based on Haar measure.

rand for RotXY and etc.

There also are methods for rand(::RotXY) and other 2-axis rotations.

example

julia> R = rand(RotXY)3×3 RotXY{Float64} with indices SOneTo(3)×SOneTo(3)(1.05718, 3.09581):
 -0.998952   0.0        0.045765
  0.0398601  0.491332   0.87006
 -0.0224858  0.870972  -0.490817

The random distribution is NOT based on Haar measure because the set of RotXY doesn't have group structure.

Note that:

  • rand(RotX) is same as RotX(2π*rand()).
  • rand(RotXY) is same as RotXY(2π*rand(), 2π*rand()).
  • rand(RotXYZ) is not same as RotXYZ(2π*rand(), 2π*rand(), 2π*rand()).
  • But rand(RotXYZ) is same as RotXYZ(rand(QuatRotation)).