3D rotation with wrong rotation axises

89 views Asked by At

i am having a small problem using 3d rotation matrices to implement a rubiks cube simulator. my problem is that, when trying to rotate my cube around the global x and y axis (in 3d), i end up rotating around the global x axis and cube's y axis. for example, take the next picture as the starting point: the original position

take the next picture as an example for what happens when i try to rotate around the y axis by moving mouse to the left: incorrectly rotating around the cube's y axis instead of the global y axis

and the next picture as an example for what happens when i try to rotate around the x axis by moving mouse down: correctly rotating around the global x axis

here you can see the code that i have used to perform the rotation:

from math import cos,sin
import numpy as np
def rotate(mat,xangle,yangle,zangle):  #these angles are by how much i want to rotate around a certain                   axis (in radians)
    xrotation_matrix = np.matrix([[1,0,0],
                                  [0,cos(xangle),-sin(xangle)],
                                  [0,sin(xangle),cos(xangle)]])
    yrotation_matrix = np.matrix([[cos(yangle),0,sin(yangle)],
                                  [0,1,0],
                                  [-sin(yangle),0,cos(yangle)]])
    zrotation_matrix = np.matrix([[cos(zangle),-sin(zangle),0],
                                  [sin(zangle),cos(zangle),0],
                                  [0,0,1]])
    rotated3d = np.dot(zrotation_matrix,mat.reshape((3,1)))  #mat is a point in the form np.matrix([x,y,z])
    rotated3d = np.dot(yrotation_matrix,rotated3d)
    rotated3d = np.dot(xrotation_matrix,rotated3d)
    return rotated3d

for extra context (although slightly unnecessary) on how the code works, here is how i calculate how to get the rotation angles:

def get_full_turn(self,mousepos):
    xchange = mousepos[0]-self.startdrag[0]
    ychange = mousepos[1]-self.startdrag[1]
    self.xangle -= self.xadding
    self.yangle -= self.yadding
    self.xadding = ychange/100
    self.yadding = xchange/100
    self.xangle += self.xadding
    self.yangle += self.yadding

How can i make the cube rotate around the global x and global y axis so i can properly rotate it? (pls explain very simply as i am just a passionate, but very new A-level student)

so far i have tried reversing the order of multiplicaiton with rotation matrices (some website showed something similar as a solution), but very similar results show (only 1 axis is rotated around a global axis, yet the others around the current axis).

for extra info if my wording is confusing, i have been searching for the type of rotation, and it seems to be known as an ‘extrinsic’ rotation (if i am not worngly midtaken)

also, the question that i am suppososed to be duplicating has 1 answer. and that answer does not go over how these matrices work and does not go over the way to rotate the FULL cube, as well as the smaller parts, which i have already done.

1

There are 1 answers

3
magnificentcritter22 On

Second image is not so informative, but I think that the problem is that you have your cube's center not in the (0, 0, 0) position. Rotation matrices rotate vetrices relative to (0, 0, 0) vertex.

More informative example from wolfram alpha (but only for 2D).

If it is a problem, the solution is shift matrix. First of all, you shift your cube to the position with matrix M_shify, where it has it's center in (0, 0, 0). Then rotate with matrices. And after that use reverse shift matrix (shift parameters multiplied by -1)

Also, it is prefered to use matmul operator @ for matrix multiplying.

For 2D matrices numpy.dot is equivalent for matmul operator:

rotated3d = np.dot(zrotation_matrix,mat.reshape((3,1)))
    rotated3d = np.dot(yrotation_matrix,rotated3d)
    rotated3d = np.dot(xrotation_matrix,rotated3d)

is equivalent to

rotated3d = zrotation_matrix @ yrotation_matrix @ xrotation_matrix @ rotated3d