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