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.167537julia> θ = rotation_angle(R)2.3210234148741837julia> n = rotation_axis(R) # These matrices are approximately equal.3-element StaticArraysCore.SVector{3, Float64} with indices SOneTo(3): 0.5355785581183807 -0.4562206495732595 -0.7106464148835127julia> 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.737394julia> θ = 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 1julia> 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.0julia> 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.0julia> 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.0julia> 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.0julia> 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.0julia> Rotations.params(RodriguesParam(R)) # Rodrigues Parameters (x, y, z)3-element StaticArraysCore.SVector{3, Float64} with indices SOneTo(3): 0.0 0.0 0.0julia> 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.412686 0.620441 -2.84546 1.37408 -1.03458 0.788797 -0.940306 -0.338145 -0.45724julia> R = nearest_rotation(M) # Find the nearest rotation matrix3×3 RotMatrix3{Float64} with indices SOneTo(3)×SOneTo(3): 0.111725 0.105561 -0.988117 0.688409 -0.725322 0.0003508 -0.716666 -0.680268 -0.153706julia> U, V = R\M, M/R # Polar decomposition of M([1.5737100287181613 -0.40055764733304694 0.5527945896002082; -0.40055764733304733 1.0459271518489115 -0.5614564733412604; 0.5527945896002089 -0.5614564733412605 2.8822050278688716], [2.8310350792154293 -0.7351152816460444 0.3110556909943626; -0.7351152816460446 1.696612041835573 -0.4022111711227181; 0.3110556909943624 -0.40221117112271776 0.9741950873849418])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}Angle2dRotXRotYRotZ
The random distribution is based on Haar measure.
example
julia> R = rand(Angle2d)2×2 Angle2d{Float64} with indices SOneTo(2)×SOneTo(2)(2.26144): -0.637033 -0.770836 0.770836 -0.637033
rand for $SO(3)$
The following types have an algebraic structure that is homomorphic to $SO(3)$.
RotMatrix{3}RotXYZ(and other Euler angles)AngleAxisRotationVecQuatRotationRodriguesParamMRP
example
julia> R = rand(RotationVec)3×3 RotationVec{Float64} with indices SOneTo(3)×SOneTo(3)(1.19129, -0.523395, -0.0440173): 0.880476 -0.23754 -0.410288 -0.302729 0.384315 -0.872157 0.364852 0.892119 0.26647
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.95807, 2.74154): -0.92104 0.0 0.389468 0.360625 -0.377664 0.85283 0.147088 0.925943 0.347843
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 asRotX(2π*rand()).rand(RotXY)is same asRotXY(2π*rand(), 2π*rand()).rand(RotXYZ)is not same asRotXYZ(2π*rand(), 2π*rand(), 2π*rand()).- But
rand(RotXYZ)is same asRotXYZ(rand(QuatRotation)).