Skip to content

Commit 1217540

Browse files
authored
Merge pull request #22 from adambrewster/dcm2q
Add a method to compute quaternion from direction cosine matrix
2 parents f702021 + 0b4d990 commit 1217540

File tree

2 files changed

+32
-0
lines changed

2 files changed

+32
-0
lines changed

src/Quaternion.jl

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,32 @@ function qrotation(rotvec::Vector{T}) where {T <: Real}
208208
Quaternion(one(T), zero(T), zero(T), zero(T), true)
209209
end
210210

211+
function qrotation{T<:Real}(dcm::Matrix{T})
212+
# See https://arxiv.org/pdf/math/0701759.pdf
213+
a2 = 1 + dcm[1,1] + dcm[2,2] + dcm[3,3]
214+
b2 = 1 + dcm[1,1] - dcm[2,2] - dcm[3,3]
215+
c2 = 1 - dcm[1,1] + dcm[2,2] - dcm[3,3]
216+
d2 = 1 - dcm[1,1] - dcm[2,2] + dcm[3,3]
217+
218+
if a2 >= max(b2, c2, d2)
219+
a = sqrt(a2)/2
220+
return Quaternion(a, (dcm[3,2]-dcm[2,3])/4a, (dcm[1,3]-dcm[3,1])/4a, (dcm[2,1]-dcm[1,2])/4a)
221+
elseif b2 >= max(c2, d2)
222+
b = sqrt(b2)/2
223+
return Quaternion((dcm[3,2]-dcm[2,3])/4b, b, (dcm[2,1]+dcm[1,2])/4b, (dcm[1,3]+dcm[3,1])/4b)
224+
elseif c2 >= d2
225+
c = sqrt(c2)/2
226+
return Quaternion((dcm[1,3]-dcm[3,1])/4c, (dcm[2,1]+dcm[1,2])/4c, c, (dcm[3,2]+dcm[2,3])/4c)
227+
else
228+
d = sqrt(d2)/2
229+
return Quaternion((dcm[2,1]-dcm[1,2])/4d, (dcm[1,3]+dcm[3,1])/4d, (dcm[3,2]+dcm[2,3])/4d, d)
230+
end
231+
end
232+
233+
function qrotation{T<:Real}(dcm::Matrix{T}, qa::Quaternion)
234+
q = qrotation(dcm)
235+
abs(q-qa) < abs(q+qa) ? q : -q
236+
end
211237

212238
rotationmatrix(q::Quaternion) = rotationmatrix_normalized(normalize(q))
213239

test/test_Quaternion.jl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,12 @@ for _ in 1:100
108108
@test normalize(qn) === qn
109109
end
110110

111+
let # test rotation <=> rotationmatrix
112+
q1 = nquatrand()
113+
q2 = qrotation(rotationmatrix(q1), q1)
114+
@test q1 q2
115+
end
116+
111117
let # test slerp and linpol if q1 = 1
112118
q1 = quat(1, 0, 0, 0.)
113119
# there are numerical stability issues with slerp atm

0 commit comments

Comments
 (0)