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 matrix
3×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 matrix
3×3 Matrix{Float64}: -0.412686 0.620441 -2.84546 1.37408 -1.03458 0.788797 -0.940306 -0.338145 -0.45724
julia> R = nearest_rotation(M) # Find the nearest rotation matrix
3×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.153706
julia> 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}
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)(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)AngleAxis
RotationVec
QuatRotation
RodriguesParam
MRP
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))
.