how to concatenate 3d rotations?

Started by
41 comments, last by xoxos 9 years, 5 months ago

i have a ~bootstrap background in 1d audio dsp which lends me an idiosyncratic manner when coding. i decided to write my own 3d soft engine with geometric knowledge and ran into what seems to be the canonical issue..

rotation_error.jpg

i do understand everyone wants to jump ahead to telling me the solution, but let's state the problem for explicitness -

the problem:
in the illustration, the observer turns left, then rolls to the left, positioning the object that was initially straight ahead to the lower right of the frustrum. and of course, subsequent commands to turn left or right are desired to be applied from the current orientation, whereas in the illustration, turning left or right is applied to the now disjunct world y axis (which would only be a correct application for left/right turns for an upright observer).

so the problem is applying a rotation in terms of a given arbitrary orientation.. i've seen dozens of threads wording it in various ways.. rotating on an arbitrary pole, applying consecutive rotations.. a ton of language has been applied to describing this issue.

you have probably intuited that i am comfortable with 2d geometry and am aspiring for a yaw-pitch-roll implementation. i *really* would like to store my 3d rotations as 3 radian values.

the solution:
everybody can tell me that the solution for this is to adopt quaternions. or, maybe matrices, some will say. i've even seen a few cryptic sources with long reams or arctan functions that didn't use matrices.

i have been researching for a couple of weeks, and there are a few reasons why i haven't been able to commit myself to quaternions, the most meaningful is that i have yet to determine if i am actually going to be able to solve the problem i am having by using them...


what i would like to do is concatenate radian rotations and return a radian rotation.......

.......start with three radian values for my current orientation, a.x, a.y, and a.z.. and then take my second radian rotation vector, b.x, b.y, b.z, and put these together so i have a radian rotation vector that is the new state of orientation.

as i look at matrices and quaternions, what i see is a mechanism for applying rotation.. turn my radian data (tait-bryan angles, or incorrectly "euler angles") into a matrix i can use to calculate the new location of objects.. multiply two for successive rotations.. ..but i don't see anything about giving me back radians, which is what i want.

i've been reading.. a whole mess of stuff... sten melax's pdf is fair, the colorado school of mines rotation pdf is also fair.. but for all the information there is, i'm not able to apply it to the scope of the task i'd like to address...

eg. i only recently understood (col. mines pdf) that 3x3 matrices can be used to apply successive rotations with one transformation "just as well as quaternions" ?? which would be nice because having happily rudimentary aesthetics, i eschew matrices as bulk and therefore struggle every time something is presented in terms of such concepts... if someone says "multiply these two matrices to get the result," i know i can do it, but i know i'm going to be using reference material when implementing it.

i have sort of a trauma complex from reading too much lol. instead of continuing to dig through things hoping to someday get somewhere i can start doing things, i thought i'd simply ask: what's the fastest way to get my simple brain into returning compounded rotation as radians?

neither a follower nor a leader behttp://www.xoxos.net
Advertisement
You were almost there: Convert the rotations to either matrix or quaternion form, multiply them and convert back. Google for "matrix to Euler" or "quaternion to Euler".

thank you.. i'd about realised it and you've said it exactly.

neither a follower nor a leader behttp://www.xoxos.net


Convert the rotations to either matrix or quaternion form, multiply them and convert back.

Or, you could just add the radians together...


Convert the rotations to either matrix or quaternion form, multiply them and convert back.

Or, you could just add the radians together...

That only works in 2D. In 3D, rotations are quite a bit more complicated.

My current game project Platform RPG

i know this question may seem banally dysfunctional, but this is the part that is challenging me :)

i reference matrix multiplication as:

given two matrices -
012 abc
345 def
678 ghi

0*a+1*d+2*g, 0*b+1*e+2*h, 0*c+1*f+2*i
3*a+4*d+5*g, 3*b+4*e+5*h, 3*c+4*f+5*i
6*a+7*d+8*g, 6*b+7*e+8*h, 6*c+7*f+8*i

..but references for flight systems present this:
ch*ca, -ch*sa*cb + sh*sb, ch*sa*sb + sh*cb
sa, ca*cb, -ca*sb
-sh*ca, sh*sa*cb + ch*sb, -sh*sa*sb + ch*cb

if one assumes
sa = sin(attitude)
ca = cos(attitude)
sb = sin(bank)
cb = cos(bank)
sh = sin(heading)
ch = cos(heading)

i admit my cretinous nature from not taking the time to calculate multiplying the separate axis rotations together to verify that result and see if it does corroborate the referenced method,

..but i would expect a much lengthier solution from that method (i have yet to find a reference on 3d rotations that doesn't say "matrix multiplication is documented everywhere, so we can skip it").

is there a special case for performing matrix multiplication in this circumstance, or is my reference correct? is there an award for especially lazy posters?

neither a follower nor a leader behttp://www.xoxos.net
i admit my cretinous nature from not taking the time to calculate multiplying the separate axis rotations together to verify that result and see if it does corroborate the referenced method,

..but i would expect a much lengthier solution from that method (i have yet to find a reference on 3d rotations that doesn't say "matrix multiplication is documented everywhere, so we can skip it").

is there a special case for performing matrix multiplication in this circumstance, or is my reference correct? is there an award for especially lazy posters?

Your generic matrix multiplication is correct, and so is probably the final result of the A/B/H matrix you showed (depends on how the rotations are combined, but it does look reasonable). The individual attitude, bank and heading matrices are axis-aligned rotations and thus contains plenty of zero-valued elements. An axis aligned rotation matrix has 5 zero-valued elements and 4 non-zero valued elements. If you insert that many zero-valued elements into your matrix multiplication, many of the individual products disappear. The product of the three axis aligned matrices isn't any more complex than that when all zero-valued terms are eliminated from the equation.

ty, it's nice to simply know i have the correct method referenced! i can now apply myself with energy reserved for intentful achievement.. :)

neither a follower nor a leader behttp://www.xoxos.net


is there an award for especially lazy posters?

If there is, sign me up. :)

lol okay, this is making me wonder why i'm alive so let's do this piece by piece.. just the basics first, if this is all straight i can address rotation order..

my game loop worked fine with the non-concatenating rotations as illustrated in first post, it ought to be solid so that no data is being accidentally overwritten -

// game loop
    tetra shape1 = shape0; // create real instance of ideal, predefined tetrahedron form
    shape1.location += (0,0,5); // move real object to a fixed location
    shape1.rotate(place0.r); // rotate by player-world orientation
..so i'm not overwriting any location or rotation data that could cause unanticipated results. that would have evinced itself with my naive rotation, which worked perfectly.

to perform my clumsy, first matrix rotation implementation i created a "matrix3x3" class. matrix data is stored in variables "a" through "i", and clumsy functions are used to populate the variables. at least, this is the way to do it before grace sets in and i have a better idea of where and how to write it.

my matrix multiplication looks alright to me!

        matrix3x3& operator * (matrix3x3 param) {
            float temp0, temp1, temp3, temp4, temp6, temp7;            
            temp0 = a * param.a + b * param.d + c * param.g;
            temp1 = a * param.b + b * param.e + c * param.h;
            c = a * param.c + b * param.f + c * param.i;  
            temp3 = d * param.a + e * param.d + f * param.g;
            temp4 = d * param.b + e * param.e + f * param.h;
            f = d * param.c + e * param.f + f * param.i;  
            temp6 = g * param.a + h * param.d + i * param.g;
            temp7 = g * param.b + h * param.e + i * param.h;
            i = g * param.c + h * param.f + i * param.i;
            a = temp0;    b = temp1;
            d = temp3;    e = temp4;
            g = temp6;    h = temp7;            
            return *this;
        }

..after the previously noted game loop, my rotation vector place0.r is updated by my rotating vector, place0.w -

        matrix3x3 tempmat0, tempmat1;
        tempmat0 = tempmat0.make(place0.r);
        tempmat1 = tempmat1.make(place0.w);
        tempmat0 = tempmat0 * tempmat1;
        place0.r = tempmat0.angles(); // convert matrix to angle vector

i know that's all basic and ugly to look at, but let's confirm it's correct before the travesty of rotations begins. i've been using POVray for almost two decades and so i want to go in the "wrong" direction and make a left handed implementation. i've rewritten it four times now, finally adopting the right handed system from euclideanspace.com and i'm still getting useless results with that.. so, first.. the matrix is correct.. then on to order of rotations and the matrix coefficients...

..one of the things that is making me seriously wonder about my method is that place0.r is a set of three angles from 0 to 2*pi.. place0.w is another set of three angles created by player input.. eg. turn left or right, place0.w.y is modified.. ..when the player is not holding a button to move left, place0.w (all three values..) glide back to 0, so that rotation will slow instead of abruptly stop. however,

(all must be forgiven because trying to fenangle the matrix-to-euler conversion for an arbitrary rotation system is not fun)

however, what i found is that my place0.r value was being modulated back to (0,0,0) in the same glide time applied to releasing the place0.w.. i'm having to hold the key down and fight to make it *stay* facing anywhere (and the rotations all have ganky, curved paths.. which we all know means a bug is somewhere). i have no idea why it's doing that but i don't think it should be :)

so, next, rotation order..

neither a follower nor a leader behttp://www.xoxos.net

This topic is closed to new replies.

Advertisement