multiple 3D rotations on one object

I'm working on a 3D space game with no gravity but multiple engines at the spaceship. My problem is collecting the different rotations and put them together.

For example, this is the prototype of my spaceship: If I put force to the upper and lower part (A) the ship will rotate like a screw as shown in the picture. This is working very well... but if I add a second rotation onto the spaceship, like in picture number two: The ship rotates weird. I want to have it like in this video:

I know, that the problem is, that I multiply the rotation-matrices in the wrong order... but I tried every order and then I figured out, that with the euler-angles I always get the problem with the gimbal lock, because I split the rotation into x/y/z rotations. I don't know an other way, because in space if you make a rotation, it'll rotate infinite long... and I somehow have to save the different rotations and add them together. I also don't need a 100% physical correct rotation, and it also has to be calculated in real-time so 60 frames per second. Does someone have an idea of implementing it? BTW: At the end the ship will have a lot of engines and they are separate controllable.

More details:

I usually have some matrices:

1: model-matrix: this matrix is a 4x4 matrix which describes the position rotation and scale of the spaceship. the upper-left 3x3 matrix inside the 4x4 matrix describes the rotation and scale of the ship.

2: Rotation-matrix: this is a 3x3 matrix which describes an axis and an angle for rotating the model-matrix.

to make a rotation, I multiply the rotation-matrix with the model-matrix (upper-left 3x3 matrix). every engine(jet) makes a torque. And I split this rotation into x/y/z rotations. and add them to the rotation-matrix. That means, to stop a rotation (for example x rotation), I add the -x rotation onto the rotation-matrix.

I hope this description helps ;)

also: I don't need a 100% correct rotation. the spaceship should rotate like a sphere... maybe different models would rotate different.

• Difficult to answer your question on a forum like this. Not very tight and focussed. Also, you would need to provide a lot more details on exactly how you're implementing the vehicle rotation, and that would almost certainly turn into an unacceptably long question. If you're going to post a question here, it would be better if it were focussed on a very specific problem issue (and it had an arguably good connection to physics). – Samuel Weir Sep 2 '17 at 22:51
• @SamuelWeir: I'm sorry, first time I'm writing here... I'm also not a physicist. I had the hope, that someone can give me a paper or some kind of tutorial to implement that... I also don't think that the stuff I already have is helpful :(, like I said: I tried with rotation-matrices and multiply them together... but to make an X rotation, Y rotation then - X rotation -Y rotation does not give me the original position. But what do you think I can do to make my question more specific? Thanks for your answer! – Thomas Sep 2 '17 at 23:23
• for me it's also hard to see, if the rotation is correct... because the since fiction spaceships are flying like planes (with air) and I had the hope, that stuff like that is normal exercise in physics education :/ – Thomas Sep 2 '17 at 23:26

Judging by the way you've worded your question, the problem could be in how you are "adding" rotation matrices. You can't just add rotation matrices. Let's introduce the notation $\textbf{R}\left(\hat{a}, \theta \right)$ to be a rotation matrix around the axis $\hat{a}$, by an amount $\theta$. Say we want to rotate a vector $\vec{v}$ around $\hat{x}$ by $\varphi$. That is $$\vec{w}=\textbf{R}\left( \hat{x}, \varphi \right) \vec{v}.$$ This is a new vector, and if we want to rotate it around say $\hat{y}$, we just treat it as rotating $\vec{w}$. So we get: $$\vec{u}= \textbf{R}\left(\hat{y}, \theta \right) \vec{w} = \textbf{R}\left(\hat{y}, \theta \right)\textbf{R}\left( \hat{x}, \varphi \right) \vec{v}.$$ Hence to do multiple rotations, we have to chain these rotations together, by multiplying the matrices together. Note that $$\textbf{R}\left(\hat{y}, \theta \right)\textbf{R}\left( \hat{x}, \varphi \right) \neq \textbf{R}\left(\hat{y}, \theta \right)+\textbf{R}\left( \hat{x}, \varphi \right).$$ You also speak about undoing rotations. The inverse of a rotation matrix is handily the same rotation matrix, but with $\theta \rightarrow -\theta$. However matrices don't commute, so you need to be careful about the order you use them in. If we want to get $\vec{v}$ from $\vec{u}$, we first need to undo the rotation about $\hat{y}$, and then undo the rotation about $\hat{x}$. That is: $$\vec{v} = \textbf{R}\left(\hat{x}, -\varphi\right)\textbf{R}\left(\hat{y}, -\theta\right)\vec{u} =\textbf{R}\left(\hat{x}, -\varphi\right) \textbf{R}\left(\hat{y}, -\theta\right)\textbf{R}\left(\hat{y}, \theta \right)\textbf{R}\left( \hat{x}, \varphi \right) \vec{v} =\textbf{R}\left(\hat{x}, -\varphi\right) \textbf{I}~\textbf{R}\left( \hat{x}, \varphi \right) \vec{v} = \textbf{R}\left(\hat{x}, -\varphi\right) \textbf{R}\left( \hat{x}, \varphi \right) \vec{v} = \textbf{I} ~\vec{v} =\vec{v},$$ where I've used $\textbf{I}$ as the identity matrix. You can see how the order I've applied the un-rotations on the left means they're able to cancel out the original rotations.

Not sure if this will have answered your questions fully, feel free to comment questions.

• I'm not sure, if I understood it correctly... let me explain: because in space is no friction, so if I make a rotation, it will rotate forever... so after R(y,θ)R(x,φ), R(x,φ) will change every time-step... that means, I can not combine these matrices to one matrix? And after playing 5 minutes this chain of matrices is so long, that the calculation will take to much time? Thank you for your response! – Thomas Sep 3 '17 at 1:42
• I'm sorry, if I wrongly described my knowledge about rotation-matrices... I know that R(x,-φ)R(y,-θ)R(y,θ)R(x,φ) = I. My only problem is, that the rotations never end. I'm looking for a way of saving the information about the actual (end) rotation without remembering every step before. And I was trying to do that with subdividing into x/y/z rotation. (And I can see, that this does not work as thought) – Thomas Sep 3 '17 at 1:47
• @Thomas Given this is more a question about implementation, you could try it on the gamedev se, gamedev.stackexchange.com It seems to me you should say $\vec{v}(t+dt) = \textbf{R}(\hat{a}, d\theta)\vec{v}(t)$, and then save that new vector, and repeat in the next time-step. So you are incrementally rotating your space-ship, and saving its new position each step of the way. – CDCM Sep 3 '17 at 2:55
• If you're looking at frictionless things/spinning, it may be easier to say that a force adds to the spaceships angular velocity in each dimension. Then you can rotate it each time-step by some amount proportional to that angular velocity. – CDCM Sep 3 '17 at 3:08

The short answer is, use quaternions. You start with an orientation $$M = (0,x,y,z)$$.

You do a rotation like this: choose your axis of rotation $$R = (0,a,b,c)$$.

Choose how much to rotate, probably a small angle $$\alpha$$, the amount it rotates in 1/60 second.

Calculate $$A = (\cos(\alpha),0,0,0) + sin(\alpha)R$$.

To get the rotated version, do 2 quaternion multiplications, $$M_1 = A M A'$$.

Next time do $$M_2 = A M_1 A'$$. Simple.

I won't try to explain that here, you'll look it up anyway unless you just find the code and use it.

To do a second rotation at the same time, just calculate $$C = BA$$ and $$C' = A'B'$$. Once you've calculated those, you can multiply $$C M_2 C'$$, $$C M_3 C'$$ $$C M_4 C'$$ etc. Simple.

Rounding error will eventually build up, and you can interpolate every now and then to reduce that.

This approach won't do gimbal lock. It just works.