6

I'm making C++ program, and in my program I need a rotation matrix around any vector. I wanted to extract RotationMatrix[fi,{x,y,z}] output and put it in my program. Unfortunately Mathematica thinks I operate with imaginary components (x,y,z). Because of that the output that I get is in epic dimensions xD.

I tried to fix this problem with RotationMatrix[fi,{Re[x],Re[y],Re[z]}] but no luck there. Apparently Mathematica doesn't track what type of variable the user defined (real/imaginary).

Is there a way to fix this?

J. M.'s missing motivation
  • 124,525
  • 11
  • 401
  • 574
  • 3
    How about FullSimplify[RotationMatrix[fi, {x, y, z}], Assumptions -> {x \[Element] Reals, y \[Element] Reals, z \[Element] Reals}]? – Sjoerd C. de Vries Sep 11 '13 at 21:55
  • Sjoerd C. de Vries you are the MAN :) –  Sep 11 '13 at 22:26
  • Note, the the direct translation to C++ of Mathematica's matrix expression may not be efficient, maintainable and understandable. A production C++ implementation of Rodrigues rotation of a point about a vector is available at https://ceres-solver.googlesource.com/ceres-solver/+/master/include/ceres/rotation.h#587 as routine AngleAxisRotatePoint – Brian Swift Aug 27 '21 at 00:05

3 Answers3

8

An even much faster way to accomplish this is:

ComplexExpand[RotationMatrix[fi, {x, y, z}], TargetFunctions -> {Re, Im}] // FullSimplify
RunnyKine
  • 33,088
  • 3
  • 109
  • 176
5

As noted by Rahul, one can always fall back on using the Rodrigues rotation formula if need be:

rodrigues[th_, axis_?VectorQ] :=
  First[LinearAlgebra`Private`MatrixPolynomial[{{1, Sin[th], 2 Sin[th/2]^2}},
                                               -LeviCivitaTensor[3, List].Normalize[axis]]]

(In versions before 11.2, use LinearAlgebra`MatrixPolynomial[].)

J. M.'s missing motivation
  • 124,525
  • 11
  • 401
  • 574
  • +1. This is quite fast compared to the other solutions. Also, I like the new avatar :) – RunnyKine Apr 04 '16 at 21:44
  • It's what I was using way before the *Transform[] stuff came along (altho I was originally using Array[Signature[{##}] &, {3, 3, 3}] in place of what is now LeviCivitaTensor[3].) And yes, this function was involved in my latest work of art. ;) – J. M.'s missing motivation Apr 04 '16 at 22:55
5

One solution, as pointed out by Sjoerd, is to tell Mathematica that your variables are not complex.

FullSimplify[RotationMatrix[fi, {x, y, z}], {x, y, z} ∈ Reals]

This takes very long on my machine. Additionally, please note that it leads to undesired things in Mathematica version 8, because the result contains piecewise functions and Conjugate calls. To get the same result, you need to specify that the vector {x, y, z} does not vanish:

FullSimplify[RotationMatrix[fi, {x, y, z}],
             {x, y, z} ∈ Reals && ( x!=0 || y!=0 || z!=0 )]

Finally, on my machine it is much faster to first use ComplexExpand and then do the FullSimplify step:

FullSimplify[ComplexExpand[RotationMatrix[fi, {x, y, z}]], {x, y, z} ∈ Reals]
J. M.'s missing motivation
  • 124,525
  • 11
  • 401
  • 574
halirutan
  • 112,764
  • 7
  • 263
  • 474