Cumulative rotations

Started by
2 comments, last by haegarr 18 years ago
Hello all, I have a question I'd like to ask you guys, about achieving a pretty standard effect. I would like to be able to guide my "craft" around a 3D space by adjusting the twist left and right( yaw? ), and the tilt up and down( pitch? ), but NOT the roll. So far I have achieved this by maintaining two matrices, one for the twist and one for the tilt. Whenever I draw my model and adjust my camera, I have to combine the two matrices in a specific order. First, I take my tilt matrix, and then I multiply it by my twist matrix. This gives me the effect I want. Previously I had problems, when using only ONE matrix. Whenever the player tried to twist or tilt, I would just generate a matrix that represented their motion, and multiply it into my single "rotation" matrix. This produced very bizarre effects, which I BELIEVE are caused by rotation around the X axis ( this is how I represent tilt ) AFTER having already been rotated around the Y axis ( this is how I represent twist ). When I changed it to ensure that multiplication was always occuring tilt-first, it solved my problem. But it seems to me I ought to be able to represent my orientation with just one matrix. I had considered that what I might be running into here is gimball lock, but I don't *think* that's the issue ( my understanding is that this causes transformations around certain axes to be ignored, not warped ). Plus, I'm pretty sure that a matrix can represent any rotation that a quaternion can, it's just slower to normalize. I am thinking that for my tilt rotations, I should be generating an axis based on my current facing vector crossed with my up vector ( in effect, my translated X axis ). I should be able to rotate around this at any time, and represent the whole transformation with one matrix. But then, that seems like a lot of work, and it might not really be advantageous over just holding two matrices and multiplying them. Does anyone have any suggestions? Is there an elegent solution for representing these kinds of combined rotations that I am missing? Thanks much for any advice, and let me know if you need more info. jujumbura
Advertisement
If you have either a quaternion or a matrix (or whatever) to represent the current orientation, and you have a way to get the local axes to rotate around for the cases the user "stears" the aircraft, then I don't see why a single representation shouldn't work. If I understand correctly, then heading means to rotate around the local upward axis, and pitching around the local sideways axis, since the airflow at the flaps would push the aircraft w.r.t. this local co-ordinate system. So I assume you could get the corresponding axis, compute a quaternion or matrix from it, and multiply that rotation with the current orientation to yield in the updated current orientation.

As long as the update step isn't that big, it may be sufficient to use the both axes simultanously (say that the order of rotation and picking of axes doesn't play a big role). Otherwise you may rotate around the one axis, pick the updated second axis, and the rotate around the second axis.

(However, I haven't implemented such a thing yet, and these are just my thoughts...)
As usual haegarr's answer pretty much covers it, but I'll throw out a couple more thoughts for you to consider. Given the kind of motion it sounds like you're after, combining two matrices (yaw and pitch) every frame to create your orientation matrix is perfectly reasonable. Keep in mind that for something like this, which is generally only done once per frame, minor performance tweaks aren't really that important.

There are certainly other ways you could do it. You could perform the rotations incrementally, with yaw being about the global up axis, and pitch about the local side axis. You would then have to worry about orthogonalization though, which if not handled in a specific way might result in some roll slowly creeping in to your object's orientation.

There are also ways to optimize the method you're using, but again I doubt it would make much difference. In any case, for the sort of motion you want, IMO the method you're using is entirely appropriate. I would just go with it if I were you, at least until you have need for more sophisticated motion (6DOF, physics simulation, etc.).
Just another approach to deal with a single matrix. This is only a small mathematical trick and depends heavily on how you compute the heading and pitching, but perhaps it works.

From what you've said in the OP it seems me that you compute the heading and pitching matrices by their own, and combine them just before use. Let me assume that the resulting matrix is given by
M := H * P

Computing both matrices as sequence of particular rotations means
H * P = ( H1 * H2 * H3 * ... ) * ( P1 * P2 * P3 * ... )
Now, since concatenating rotations around the same axis is commutative, one gets
= ( ... * H3 * H2 * H1 ) * ( P1 * P2 * P3 * ... )
= ... * ( H3 * ( H2 * ( H1 * P1 ) * P2 ) * P3 ) * ...
or, in other words, the matrix update may be performed as
Mt+1 := Ht+1 * Mt * Pt+1
and hence you need only one matrix to store.

However, you couldn't do reversal of the one branch of matrices if the rotation axis changes.

E.g. in jyk's reply heading is done around the global axis but pitching is done around a changing axis. Hence the above trick would work fine. But it wouldn't, of course, if your overall order is
M := P * H
instead. (EDIT: But notice that if you use row vectors, you have to invert all the statements; its just in a mess ;)

But, as jyk stated, there would be no real difference in performance. And since you already have a working solution ...

[Edited by - haegarr on March 28, 2006 12:29:25 PM]

This topic is closed to new replies.

Advertisement