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}: 1.13191 1.28938 0.149988 0.523156 -0.546136 -0.773541 0.875881 1.52741 -0.853885julia> 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.678931julia> 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}Angle2dRotXRotYRotZ
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)AngleAxisRotationVecQuatRotationRodriguesParamMRP
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 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)).