Combine multiple rotation matrixes in 3D
Asked Answered
S

5

9

I have calculated an axis angle rotations for each axis. If I only apply one of the three rotations, the objects rotates as expected.

If I multiply the rotation matrixes, as you would normally do it if you combine rotations I don't get the desired result, cause the first rotation affects the others and therefore the end result is not what I'm looking for.

I want to apply each rotation to the object as if it wasn't rotated before.

I guess this is a simple task, but it seems that I'm not searching for the right keywords. (Also the title is not perfect ... (open for suggestions))

Thanks for every hint / help.

Shanan answered 3/4, 2017 at 16:25 Comment(0)
A
4

You're experiencing gimbal lock. It's not a maths problem, it's a logical fallacy. Try it with, for the sake of description, your phone:

  1. put it on your desk face up, with the charging connector at the bottom.
  2. rotate clockwise around z by 90 degrees. So the charging connector is now to the left.
  3. rotate around x (which will be the longer axis of the phone assuming the charging port is on the top or bottom) by 180 degrees.
  4. the phone is now upside down, with the charging port on the left.

But:

  1. put it on your desk face up, with the charging connector at the bottom.
  2. rotate around x by 180 degrees. So the charging connector is now at the top.
  3. rotate clockwise around z by 90 degrees.
  4. the phone is now upside down, with the charging port on the right.

Which of those is incorrect if the instruction was to rotate 180 degrees around x and 90 degrees clockwise around z? Neither is incorrect. The instructions were ambiguous.

The order of individual rotations always matters, because the second affects the work done in the first, the third affects the work done in the first and second, etc. Shuffling the order just changes which affects which.

Orientation is normally stored directly as a matrix or as a quaternion because it's unambiguous and because it keeps the order of actions properly ordered.

Agricola answered 3/4, 2017 at 16:37 Comment(9)
I know that order matters and my current problem is not gimbal lock. I know that I can't directly use the three rotations I have. The question is how to modify it, so that I can use them.Shanan
As per my answer: if all you have is "rotate x degrees around x, y around y, and z around z" then there is no one "correct" final orientation. Whether you you can recognise it or not, this is exactly the problem described as gimbal lock.Agricola
But there has to be one that is describing what I,m looking for. And there has to be a way to transform my current values.Shanan
@Agricola This is not an answer to the posed question.Exorcise
@LadislavOndris it is exactly an answer to the posed question. Question: "If I multiply the rotation matrixes, as you would normally do it if you combine rotations I don't get the desired result... I want to apply each rotation to the object as if it wasn't rotated before."; answer: "You're experiencing gimbal lock. It's not a maths problem, it's a logical fallacy. ... The order of individual rotations always matters, "Agricola
@Agricola Of course, we know the order matters. The question asks the following: We have two rotation matrices that determine the desired rotation from the initial state along two different axes. But the rotations must be applied sequentially. The first rotation changes the initial state to some other state, so the second rotation is no longer valid. How to account for the change by the first rotation? Or are you saying that this is not solvable? Let's hear practical answers.Exorcise
@LadislavOndris then your problem is that you haven’t understood the question. The question asks about (i) three; (ii) “axis angle rotation” and shows that the author thinks a consistent solution can be found on that premise. Not sure why you’ve plucked a completely distinct question from thin air. The word/number two isn’t anywhere in the question ans I don’t see how you’re finding ambiguity in “the order of individual rotations always matters” or why you consider “Orientation is normally stored directly as a matrix or as a quaternion” not to be practical advice.Agricola
@Agricola I am sorry if I made the case more specific to the problem that I had. I see this conversation does not seem to yield anything useful, so I will probably create my own question. Anyway, thanks for answering.Exorcise
@LadislavOndris if nothing helpful came out then the problem is probably mine; such as it may help there is no way to apply two separate matrices such that one doesn’t affect the other. But probably best to pose the question separately and hopefully attract some more temperate answerers.Agricola
B
2

Just stumbled into this question searching for something slightly different. Long story short, you are likely multiplying your matrices in reversed order.

Chaining rotations is a little counter-intuitive. If you have a chain of rotations R1*R2*R3*R4 then you have two ways to conceptualize what is happening: intrinsic and extrinsic.

The intrinsic view works from right to left. You start with R4 and work your way to R1. R4 takes the initial frame and produces a new frame that is rotated around R4's rotation axis. R4's axis is specified in the initial frame. R3 takes this rotated frame and rotates it around R3's rotation axis. Here, R3's axis is specified in R4's rotated frame. This continues down the chain, each time changing the frame in which the rotation axis is expressed.

The extrinsic view works from left to right. You start with R1 and work your way to R4. The output frame of R1 is rotated around R1's axis. R1's axis is expressed in the initial frame. R2 then takes both, R1's output frame and R2's output frame and rotates both around R2's axis. R2's axis is again expressed in the initial frame. This continues up the chain, each time rotating all the previous frames around some axis expressed in the initial frame.

Confused already? What's even better is that both ways are exactly equivalent. They are just two ways of looking at the same thing. As I said, chaining rotations are a little counter-intuitive.

The bottom line of it is though if you have a bunch of rotation matrices expressed in the initial reference frame, then the extrinsic view makes the most sense. If you want to first rotate around R1 then R2, etc. then your left-most matrix is the one that you want to rotate around last, i.e., you'd compute Rn*Rn-1*...*R3*R2*R1

Beers answered 14/8, 2021 at 20:48 Comment(2)
I do not understand how this solved the original question. If I have rotations expressed in the initial reference frame and stack rotations one after another, this doesn't work since the second rotation is not applied to the initial state (only the first one).Exorcise
@LadislavOndris For every extrinsic Euler rotation you can find an equivalent intrinsic Euler rotation by simply reversing the order. For the sequence R1, R2, R3 the multiplication R1*R2*R3 would be intrinsic and R2 would rotate around R1's frame. R3*R2*R1 is extrinsic (for that order) and rotates R2 around the initial frame; at the same time, R3*R2*R1 is also intrinsic for the order R3, R2, R1 and rotates R2 around R3's frame, which is just different, equivalent, ways of expressing the same quantity.Beers
H
0

Rather than applying the rotations separately, you can create a transformation from three initial base vectors to three destination base vectors.

For example:

    // Transform the base vectors.
    transform := BaseVecTrans(
        [3]mgl32.Vec3{
            {1, 0, 0},
            {0, 1, 0},
            {0, 0, 1}},
        [3]mgl32.Vec3{
            {longitudinal.X, longitudinal.Y, longitudinal.Z},
            {upward.X, upward.Y, upward.Z},
            {normal.X, normal.Y, normal.Z},
        },
    )

The returned transform variable is a 4x4 transformation matrix.

The implementation in Go is:

func BaseVecTrans(initVecs, destVecs [3]mgl32.Vec3) mgl32.Mat4 {
    // Create a 3x3 matrix from the initial vectors and its inverse.
    A := mgl32.Mat3FromCols(initVecs[0], initVecs[1], initVecs[2])
    AInv := A.Inv()

    // Create a 3x3 matrix from the destination vectors.
    B := mgl32.Mat3FromCols(destVecs[0], destVecs[1], destVecs[2])

    // Compute the rotation matrix that transforms A to B.
    R := B.Mul3(AInv)

    // Create a 4x4 transformation matrix from the rotation matrix and a translation vector.
    transform := mgl32.Ident4()
    transform.SetRow(0, mgl32.Vec4{R.At(0, 0), R.At(0, 1), R.At(0, 2), 0})
    transform.SetRow(1, mgl32.Vec4{R.At(1, 0), R.At(1, 1), R.At(1, 2), 0})
    transform.SetRow(2, mgl32.Vec4{R.At(2, 0), R.At(2, 1), R.At(2, 2), 0})
    transform.SetRow(3, mgl32.Vec4{0, 0, 0, 1})

    return transform
}
Heterophyte answered 8/5, 2023 at 17:10 Comment(0)
T
0

There is a code solution for rotating around global axes when use multiple rotation matrix.

When we have rotation matrix C= A*B, the later rotation B will influence previous rotation A's result.

Therefore, in order to avoid the influence, we can split the entire rotation C=A(45°)*B(45°) into micro clip C=a(0.1°) * b(0.1°) * a(0.1°) * b(0.1°)...

In this way, we can minimize the interference between A and B.

Tinea answered 10/5 at 10:36 Comment(2)
It would be good add formatting to formulas hereNorthernmost
I add a code style for the math part, as I don't know how to add Latex in stackoverflow...Tinea
C
-2

Composition of rotation matrix isn't something trivial. I would recommend expressing your rotation matrix as quaternions. Quaternions have very useful properties. Multiplying two quaternions will give a 3rd quaternion which, put back into matrix form, is the exact composition of both input matrix. I think Boost libraries have code for that, but I haven't used it personally.

edit: you can get a rot matrix from (normalized) axis vector and rotation angle. look at this article on wikipedia

Caffeine answered 3/4, 2017 at 16:35 Comment(4)
The library I'm using offers quaternions. So that part is done ;). So I have to use the cross product on three vectors to get the quaternion representation of what I'm looking for? I thought that would be the same as multiplying the rotation matrixes?Shanan
@Shanan you should be able to initialize a rotation for each of your axis. Usually an axis vector and a rotation angle is enough to get a rotation matrix. once you have your 3 matrix you can express them as quaternions, multiply them together then express that result into another rotation matrix. You might as well look at Tommy 's answer.Caffeine
Multiplication of quaternions is the same as applying rotation matrices one after another, which is not what was asked.Exorcise
@LadislavOndris Re-reading the second and third paragraph 5 years later after my initial response, I still believe it is exactly what is asked here. If you can read minds, feel free to share your thoughts.Caffeine

© 2022 - 2024 — McMap. All rights reserved.