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}:
  0.108071     0.815012   -1.01709
  0.00314509   0.76479     0.518906
 -0.268036    -0.0841989   0.970901
julia> R = nearest_rotation(M) # Find the nearest rotation matrix3×3 RotMatrix3{Float64} with indices SOneTo(3)×SOneTo(3): 0.603942 0.616426 -0.505245 -0.49322 0.787004 0.370619 0.62609 0.0253642 0.779338
julia> U, V = R\M, M/R # Polar decomposition of M([-0.10409719452140989 0.06229432700073618 -0.26232723968797106; 0.06229432700073592 1.1021517238627405 -0.1939542073305788; -0.2623272396879715 -0.1939542073305794 1.4628578920200628], [1.0815434869290217 0.2111611642681816 -0.7043239732942626; 0.2111611642681809 0.7926584092522306 0.4257705695724016; -0.7043239732942627 0.42577056957240145 0.5867105251801409])
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)(1.70268):
 -0.131499  -0.991316
  0.991316  -0.131499

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)(0.412973, 0.498808, 2.00269):
 -0.450884   -0.748863  0.485704
  0.889193   -0.424226  0.171371
  0.0777151   0.509152  0.857161

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)(0.342432, 4.231):
 -0.463006  0.0       -0.886355
 -0.297619  0.941941   0.155468
  0.834894  0.335779  -0.436125

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)).