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}: 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 matrix
3×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 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))
.