@@ -243,6 +243,12 @@ This algorithm was obtained from:
243243* q: (OUTPUT) Pre-allocated quaternion.
244244* dcm: Direction Cosine Matrix that will be converted.
245245
246+ ##### Remarks
247+
248+ By convention, the real part of the quaternion will always be positive.
249+ Moreover, the function does not check if `dcm` is a valid direction cosine
250+ matrix. This must be handle by the user.
251+
246252##### Example
247253
248254 dcm = angle2dcm(pi/2,0.0,0.0,"XYZ")
@@ -254,14 +260,57 @@ This algorithm was obtained from:
254260function dcm2quat! (q:: Quaternion{T1} ,
255261 dcm:: Array{T2,2} ) where T1<: Real where T2<: Real
256262
257- q. q0 = sqrt ( max ( zero (T1), one (T1) + dcm[1 ,1 ] + dcm[2 ,2 ] + dcm[3 ,3 ] ) )/ 2
258- q. q1 = sqrt ( max ( zero (T1), one (T1) + dcm[1 ,1 ] - dcm[2 ,2 ] - dcm[3 ,3 ] ) )/ 2
259- q. q2 = sqrt ( max ( zero (T1), one (T1) - dcm[1 ,1 ] + dcm[2 ,2 ] - dcm[3 ,3 ] ) )/ 2
260- q. q3 = sqrt ( max ( zero (T1), one (T1) - dcm[1 ,1 ] - dcm[2 ,2 ] + dcm[3 ,3 ] ) )/ 2
263+ if trace (dcm) > 0
264+ # f = 4*q0
265+ f = sqrt (trace (dcm)+ one (T2))* 2
266+
267+ q. q0 = f/ 4
268+ q. q1 = (dcm[2 ,3 ]- dcm[3 ,2 ])/ f
269+ q. q2 = (dcm[3 ,1 ]- dcm[1 ,3 ])/ f
270+ q. q3 = (dcm[1 ,2 ]- dcm[2 ,1 ])/ f
271+ elseif (dcm[1 ,1 ] > dcm[2 ,2 ]) && (dcm[1 ,1 ] > dcm[3 ,3 ])
272+ # f = 4*q1
273+ f = sqrt (one (T2) + dcm[1 ,1 ] - dcm[2 ,2 ] - dcm[3 ,3 ])* 2
274+
275+ # Real part.
276+ q. q0 = (dcm[2 ,3 ]- dcm[3 ,2 ])/ f
277+
278+ # Make sure that the real part is always positive.
279+ s = (q. q0 > 0 ) ? one (T2) : - one (T2)
280+
281+ q. q0 = s* q. q0
282+ q. q1 = s* f/ 4
283+ q. q2 = s* (dcm[1 ,2 ]+ dcm[2 ,1 ])/ f
284+ q. q3 = s* (dcm[3 ,1 ]+ dcm[1 ,3 ])/ f
285+ elseif (dcm[2 ,2 ] > dcm[3 ,3 ])
286+ # f = 4*q2
287+ f = sqrt (one (T2) + dcm[2 ,2 ] - dcm[1 ,1 ] - dcm[3 ,3 ])* 2
288+
289+ # Real part.
290+ q. q0 = (dcm[3 ,1 ]- dcm[1 ,3 ])/ f
291+
292+ # Make sure that the real part is always posiive.
293+ s = (q. q0 > 0 ) ? one (T2) : - one (T2)
294+
295+ q. q0 = s* q. q0
296+ q. q1 = s* (dcm[1 ,2 ]+ dcm[2 ,1 ])/ f
297+ q. q2 = s* f/ 4
298+ q. q3 = s* (dcm[3 ,2 ]+ dcm[2 ,3 ])/ f
299+ else
300+ # f = 4*q3
301+ f = sqrt (one (T2) + dcm[3 ,3 ] - dcm[1 ,1 ] - dcm[2 ,2 ])* 2
302+
303+ # Real part.
304+ q. q0 = (dcm[1 ,2 ]- dcm[2 ,1 ])/ f
261305
262- q. q1 = copysign (q. q1, dcm[2 ,3 ] - dcm[3 ,2 ])
263- q. q2 = copysign (q. q2, dcm[3 ,1 ] - dcm[1 ,3 ])
264- q. q3 = copysign (q. q3, dcm[1 ,2 ] - dcm[2 ,1 ])
306+ # Make sure that the real part is always posiive.
307+ s = (q. q0 > 0 ) ? one (T2) : - one (T2)
308+
309+ q. q0 = s* q. q0
310+ q. q1 = s* (dcm[1 ,3 ]+ dcm[3 ,1 ])/ f
311+ q. q2 = s* (dcm[2 ,3 ]+ dcm[3 ,2 ])/ f
312+ q. q3 = s* f/ 4
313+ end
265314
266315 nothing
267316end
@@ -283,6 +332,12 @@ This algorithm was obtained from:
283332
284333* The quaternion that represents the same rotation of the `dcm`.
285334
335+ ##### Remarks
336+
337+ By convention, the real part of the quaternion will always be positive.
338+ Moreover, the function does not check if `dcm` is a valid direction cosine
339+ matrix. This must be handle by the user.
340+
286341##### Example
287342
288343 dcm = angle2dcm(pi/2,0.0,0.0,"XYZ")
0 commit comments