mathmatrixopenglmatrix-multiplicationopengl-3

How to rotate a matrix along two axis without affecting the third axis at all?


I have an object, which needs to be rotate by two axis (for simplicity, let's call them the X and Y axis, but understand that they can be completely arbitrary).

So, something like this:

Matrix aMat;
aMat.RotateAroundAxis(Vector(1,0,0),45.0f);
aMat.RotateAroundAxis(Vector(0,1,0),25.8f);

When doing this, I get unwanted rotation around the cross product of the two axis I do rotate around (for example, in the example above, I will get some (small) amount of rotation around the z axis, or 0,0,1). It's a very small amount of rotation, but it's enough to be visible, especially if I do a lot of rotations, it seems to accumulate error.

Is there a way I can suppress that?

(Edit: In case there is a better solution to what I'm doing, I have a platform with a weight on it. I want the platform to rotate depending on where the weight is, as if it were balanced on a point. I am doing this by accumulating rotation around two orthogonal axis perpendicular to the platform's up direction, depending on where the "weight" is relative to the center of the platform)


Solution

  • If I understand your problem setup, you have a situation like the following:

    The short answer to your question (starting from flat) is:

    Note: If you actually have a platform like this with physics, and the marble shown wanders left or right, the platform will actually precess unless there's some physical mechanism to stop the rotation.

    The general reason is from Wikipedia: Rotation "Rotations in three dimensions are generally not commutative, so the order in which rotations are applied is important even about the same point."

    Consider independent rotation matrices in 3D (taken from Wikipedia: Rotation Matrix)

    R_x(α) = 
    1      0      0
    0      cos(α) -sin(α)
    0      sin(α)  cos(α)
    
    R_y(β) = 
     cos(β)  0      sin(β)
     0       1      0
    -sin(β)  0      cos(β)
    
    R_z(γ) = 
     cos(γ) -sin(γ) 0
     sin(γ)  cos(γ) 0
     0       0      1  
    

    However, if you put them all together, you get a bunch of combination terms.

    R = R_z(γ), R_y(β), R_x(α) =
    cos(β)cos(γ)    sin(α)sin(β)cos(γ)-cos(α)sin(γ)   cos(α)sin(β)cos(γ)+sin(α)sin(γ)
    cos(β)sin(γ)    sin(α)sin(β)sin(γ)+cos(α)cos(γ)   cos(α)sin(β)sin(γ)-sin(α)cos(γ)
    -sin(β)         sin(α)cos(β)                      cos(α)cos(β)
    

    If your only alternative is "must start from a certain orientation, and then change to a new orientation without inducing any z-rotation" then:

    The effect would look kind of like this process (Red: desired path, blue: actual path)