Although I have encountered this issue while programming, I want to ask here, because it is a mere math problem.

The task

I have an arbitrary object placed in a three-dimensional space at a certain location with a certain scale and rotation. I know its initial rotation and orientation. Now, I want to know the new orientation of the object after I rotated it in any dimension.

My approach

My idea is this: After I rotate my object, I know the new rotation for all three axes. I calculate the difference between the current rotation and the initial rotation to know how much the object has rotated. Then, I calculate a rotation matrix with these values and transform my initial orientation vector with it. This way, I should get the new orientation of the object. At least, that's what I thought. Spoiler: Does not work.


When I place my object initially, I know all its properties, including its rotation and orientation. The vectors below are the initial values in my test case. The initial_orientation vector means, the object faces to the right. The values for initial_rotation are the rotations around the X-, Y- and Z-axes.

initial_orientation =  1.00000,    0.00000,    0.00000
initial_rotation    = -1.39626,   -4.71239,    0.00000

After rotating the object around its local x axis, the new rotation value is:

new_rotation = -1.94626,   -4.71239,    0.00000

That means the difference between the new and initial orientation is:

'initial_rotation' - 'new_rotation' = 'rotation_difference'

initial_rotation    = -1.39626,   -4.71239,    0.00000
new_rotation        = -1.94314,   -4.71239,    0.00000

rotation_difference = -0.54687,    0.00000,    0.00000

I calculate the rotation_matrix by calling a function from the coding framework. The result is listed below.

rotation_matrix = SharpDX.Matrix.RotationYawPitchRoll(rotation_difference.Y, rotation_difference.X, rotation_difference.Z);

rotation_matrix = 1.00000,    0.00000,    0.00000,    0.00000
                  0.00000,    0.85415,   -0.52002,    0.00000
                  0.00000,    0.52002,    0.85415,    0.00000
                  0.00000,    0.00000,    0.00000,    1.00000

Now, I calculate the new vector by transforming the initial orientation with the new rotation matrix:

vector = SharpDX.Vector3.TransformCoordinate(initial_orientation, rotation_matrix);

vector = 1.00000,    0.00000,    0.00000

So, the result equals the input. However, from the object's point of view it now looks a bit upwards.


Where is the mistake in my thoughts?

  • $\begingroup$ I haven't thought too carefully about all this but one thing to check is that you have applied the rotations in the same order. Note that applying the same rotations in different orders leads to different results. $\endgroup$ – Omnomnomnom Jul 20 at 23:14
  • $\begingroup$ The rotation matrix is calculated the same way for the initial_rotation matrix and the rotation_matrix when I update the model. $\endgroup$ – Endgegner85 Jul 21 at 0:40

I don't think it is correct to substract the Euler angles of the rotations in order to get the delta (difference) rotation between them, the reason is that Euler angles aren't in the tangent space of the rotation group $SO(3)$.

Instead you can obtain the delta rotation matrix $\delta R$ multiplying the start rotation matrix $R_s$ with thr final rotation matrix $R_f$ in the following way:

$$\delta R = R_f R_s^T$$

Also, in the example you show that the initial orientation vector happens to be an eigenvector of the rotation matrix. If you really want to capture all possible changes in orientation you need to define not a single orientation vector but a "Frame" i.e., three linearly independent vectors. Usually a Frame is composed by three orthogonal unit vectors (a.k.a, orthonormal vectors). The orientation of those vectors defines completely the orientation of any object.

  • $\begingroup$ You sir, deserve a cookie! I actually came up with the same idea as you, but it made it wrong in two ways: I used the inverted initial rotation matrix instead of the transposed one and I also multiplied the matrices in the wrong order. When I write (A * B) in code (where A and B are matrices), it actually calculates (B * A). Thanks to your solution, I was able to adjust my code and I always get the correct orientation. I use more vectors to store my orientation, but for my example above, I just gave one vector to keep my example slim. Thank you! $\endgroup$ – Endgegner85 Jul 21 at 10:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.