I am learning OpenGL (namely TAO fraemwork ) in C #, and I have this question:

There is, let's say a cube, and I want to always rotate it along the same coordinate system, how to implement it correctly? Functions like glRotate() or rotation by multiplying matrices directly rotates the axis of the object (cube), and after rotation, say, on the Y axis, the X and Z axes for the object will no longer be the same.

So how do you implement rotation so that the axes do not rotate with the object? Both direct answers and indirect answers are welcome: links to books or tutorials where you can dig up information, but such so that you can find the answer there.

    2 answers 2

    I advise you to read about quaternions , more precisely about how they are used in computer graphics and robotics.

    In short, this is an alternative to the usual (Euler angles) rotation option based on axis and angle rotation.

    Like matrices, they can accumulate rotations, that is, you can make chains of them, without fear of getting an axle lock (gimbal lock) as is the case with Euler angles. And at the same time, unlike matrices, they can interpolate well from one position to another.

    It may seem very difficult, however, in order to use the properties, it is not necessary to understand the inner kitchen of the quaternions.

    UPD: here is a good article

    • Good day! Thank you for your answer, @Stranger in the Q. In search of an answer in Google, I ran across the fact that it is worth using quaternions to this problem, and even on some tutorials I bungled the quaternion class. Code by reference: github.com/Despairon/SimpleRubicsCube/blob/… But the result of its use is the same rotation, like glRotate() - Maxim Rybalsky
    • here's an interesting article: habrahabr.ru/post/255005 - Stranger in the Q
    • Could you tell me about the article you threw? It says the following: "Pictures depicting a turn and signed as a" global "show turns relative to fixed XYZ axes. We will get this result if we use the turn quaternions separately." This is exactly what I need. A quaternion, as I understand it, contains vector coordinates — axes. But what does it mean to use quaternions separately, what is it like? Thanks - Maxim Rybalsky
    • meaning that to calculate the superposition with the sum of several rotations, the quaternions simply multiply - Stranger in the Q
    • But the multiplication of quaternions gives the result - rotation relative to the local coordinate system of the object, and it is written there. And I need a rotation relatively global - Maxim Rybalsky

    So how do you implement rotation so that the axes do not rotate with the object?

    It is not clear what you want to do when you rotate (and just do with any affine transformation) you move from one coordinate system to another, for example, turning the cube around its center around the X axis the local coordinate system of the cube will also be rotated, it is important to understand that any transformation is performed relative to which - then the selected coordinate system, in your case relative to the world.

    Let Rx(alpha), Ry(betta), Rz(gamma) be the rotation matrices around the corresponding axes at the angles alpha, betta, gamma .

    And T(v) the transfer matrix, where v is the positional transfer vector.

    Then the coordinates of the vertices of the cube rotated relative to the vector v around the selected axes will be calculated by the formula

    transformedVector = T(v)*Rz(gamma)*Ry(betta)*Rx(alpha)*T(-v)

    or if using old openGL functions like this:

     glPushMatrix(); // сохраняем в стек текущую модельную матрицу чтобы последующие пребразования затронули только куб glTranslatef(x, y, z); glRotate(alpha, ...); glTranslatef(-x, -y, -z); glPopMatrix()` 

    in both cases we move to the origin, rotate, and go back to our place.

    And locking axes is another matter, and in the case of Euler rotation it can naturally arise.

    But in order to use quaternions it is necessary to understand the transformations first.

    • In short, you can not do without pictures) See: commentator @StrangerInTheQ has advised the article: habrahabr.ru/post/255005 . At the end of the article there are signed pictures: the rotation of the plane is signed by global and the rotation is signed by local. If two glRotate(...) executed consecutively in openGL, then the object will rotate exactly as shown in the pictures labeled local. And I want to rotate as in the pictures with the signature global, and I have no idea how to do this, as soon as I have not tried. Thank! - Maxim Rybalsky