Home > Back-end >  How to rotate a matrix along two axis without affecting the third axis at all?
How to rotate a matrix along two axis without affecting the third axis at all?

Time:01-10

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)

CodePudding user response:

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

  • Weight On Platform
  • Own Work

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

  • Find the vector to the weight location
  • Find the vector that's perpendicular to this vector and the Z-axis
    • Cross-product of found vector and Z-axis
  • Rotate around perpendicular vector
  • This is especially true if you're "mostly" ignoring physics and just applying some rotation based on the position.
  • Just start from flat each time and then rotate based on the above approach.

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:

  • Find the vector and rotation that would have resulted in your current orientation
  • Rotate back to a flat orientation
  • Then rotate to the new orientation using the method described above.
  • Walking back exactly along the same vector out cancels out the rotation effect.

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

  • Object Moving
  • Own Work
  • Related