0
\$\begingroup\$

I have a rotation 4x4 matrix to generate a model matrix, but I would like to be able to control it like cinema4D or 3ds Max with three separate angles that are always perpendicular to each other, and so far I've had no luck...

Currently, every time I change one of the angles, I call a function containing the following code:

self->rot_matrix = mat4();
self->rot_matrix = mat4_rotate(self->rot_matrix, 1, 0, 0,
    rot.x);
self->rot_matrix = mat4_rotate(self->rot_matrix, 0, 0, 1,
    rot.z);
self->rot_matrix = mat4_rotate(self->rot_matrix, 0, 1, 0,
    rot.y);

This doesn't work though, because when I rotate around z or x, the y axis should change, but not the y angle... I'm terrible at this sort of mathematics, and would appreciate a simple explanation of what to do.

One idea I've had would be to have two vectors define the rotation system, and then use rodrigues rotation to update them, this I can do with ease, but I have no idea how to transform those two vectors back to a rotation matrix.

Thanks in advance!

\$\endgroup\$
1
  • \$\begingroup\$ "when I rotate around z or x, the y axis should change, but not the y angle" it sounds a little like you might be bumping against this common quirk of compounding rotations. The x y z rotation gizmos you see in these 3D tools, with always-perpendicular axes, and the x y z Euler/Tait-Bryan angles they show in the numeric fields, aren't actually the same transformation system - which can confound our intuition about how each of the two different rotation representations should work. \$\endgroup\$
    – DMGregory
    Feb 10, 2018 at 3:27

1 Answer 1

0
\$\begingroup\$

One idea I've had would be to have two vectors define the rotation system, and then use rodrigues rotation to update them, this I can do with ease, but I have no idea how to transform those two vectors back to a rotation matrix.

You're in luck! This part ends up being simpler than you might expect.

Let's say you're keeping track of a vector called X pointing along the object's local x axis, and a vector Y pointing along the object's local y axis, and you're carefully keeping them perpendicular and unit length after each transformation.

Now we can form the third vector Z along the object's local z axis using the cross product:

$$Z = X \times Y$$

Now we have an orthonormal basis for the rotated coordinate system, and your rotation matrix is simply these three vectors, stacked side-by-side as columns to make the top-left 3x3 block of the matrix.

$$R = \begin{bmatrix} X.x & Y.x & Z.x & 0 \\ X.y & Y.y & Z.y & 0 \\ X.z & Y.z & Z.z & 0 \\ 0 & 0 & 0 & 1 \\ \end{bmatrix}$$

(Assuming your multiplication convention puts the vector to the right of the matrix. Otherwise, take the transpose of the matrix above, so each of your basis vectors is a row.)

\$\endgroup\$
2
  • \$\begingroup\$ Thank you so much, I will try it out tomorrow and accept it if it works :) \$\endgroup\$ Feb 10, 2018 at 3:51
  • 1
    \$\begingroup\$ Works perfectly! \$\endgroup\$ Feb 10, 2018 at 4:22

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .