1

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)

KiraHoneybee
  • 495
  • 3
  • 12
  • Don't do a lot of rotations. Start from a fresh matrix and do the whole rotation from scratch every time. Rotation matrices will *always* accumulate numerical error. – user253751 Jan 06 '23 at 21:50
  • No other option? The function I have to write accepts a starting orientation matrix, and positions for the weights and pivot, and is expected to return a matrix that the original orientation matrix can be multiplied by to produce the new tilted matrix (I'm just one person in a big team). It gets called repeatedly across frames to slowly tilt the platform visually to accommodate the weight. As long as I limit it to one axis it's always perfect. It's when I involve the second, perpendicular axis that it begins to accumulate error. – KiraHoneybee Jan 06 '23 at 21:55
  • 1
    By the way it might not just be an error. If you rotate on X axis, rotate on Y axis, rotate backwards on X axis and rotate backwards on Y axis, this accumulates a Z-axis rotation *even with no error* because that is just how rotations work. (You can try it yourself with a cube-shaped object) – user253751 Jan 06 '23 at 22:01
  • I believe that IS the issue (in your second reply) sort of like the opposite of Gimbal Lock, this is Gimbal UNLOCK!... is there no way to correct for this and keep the Z axis completely locked, no trick or secret? – KiraHoneybee Jan 06 '23 at 22:04
  • I think the answer is: Don't accumulate rotations - unless you really want to. Most computer games do not accumulate rotations - they always reset based on a particular direction that is "down", but some spaceship games do accumulate rotations because there is no down in space. The result is that moving the mouse in circles can make you rotate on the third axis. – user253751 Jan 06 '23 at 22:06
  • Why do you need to rotate around TWO axes? Sounds like X and Y define the plane of your platform, then the platform would rotate only around the `Z = cross(X,Y)` axis. So there's only one rotation that you need to apply. – Yakov Galka Jan 06 '23 at 22:10
  • 1
    I think for your use case, you do not want two separate rotations. For small rotations it might be a good enough lazy approximation as the "error" is small. However I think what you actually want to do is calculate one axis (probably cross(Z, normalize(weightPos - pivotPos))), and rotate around that axis. – user253751 Jan 06 '23 at 22:13
  • @user253751, I'm not extremely sophisticated with matrix math. If I needed to rotate ang1 around axis1, and ang2 around axis2, what ang would I rotate around the new computed vector? You are correct that small errors in precision would not matter so much here, as the effect is only visual and not a part of any kind of strong computation. – KiraHoneybee Jan 06 '23 at 22:52
  • see [Understanding 4x4 homogenous transform matrices](https://stackoverflow.com/a/28084380/2521214) and look for difference between global and local rotations ... – Spektre Jan 07 '23 at 08:36

1 Answers1

1

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
G. Putnam
  • 1,262
  • 5
  • 10