Skip to content
Advertisement

How to rotate slices of a Rubik’s Cube in python PyOpenGL?

I’m attempting to create a Rubik’s Cube in Python, i have gotten as far as visually representing the cube. Struggling a bit with how to implement rotation.

I guess i’m asking for feedback as to how to go about doing this. I thought at first of, rotating each cubes set of vertices’s, without much luck.

I basically want to select a slice from an array of cube objects (of varying size), perform a rotation and a translation on each object.

JavaScript

I’m hoping someone who knows much more about this can give me some guidance as to how to proceed.

Advertisement

Answer

A rubik’s cube can be organized by an 3 dimensional array of 3x3x3 cubes. It seems to be easy to rotate a slice of the cube, but note if on slice is rotated the positions of the cube change and have to be reorganized. Not only the position changes, also the orientation of the (rotated) single cubes changes.

First of all remove the PyGame and OpenGL initialization form the constructor of the class Cube. That is the wrong place for this. In the following will generate 27 objects of type Cube.

Each cube has to know where it is initially located (self.init_i) and where it is current located after some rotations (self.current_i). This information is encoded in a list with 3 elements, one for each axis. The values are indices of cube in the NxNxN rubik’s cube in range [0, N[.
The orientation of a single cube is encoded in 3 dimensional Rotation matrix (self.rot). The rotation matrix has to be initialized by the identity matrix.

JavaScript

Create a list of the 27 cubes

JavaScript

If a slice of the rubik’s cube is rotated, then it has to be checked which of the single cubes is affected. This can be done by checking if the slice matches the entry of the rotation axis of the current position.

JavaScript

To rotate a cube, the position and the orientation has to be rotated by 90° around an axis. A 3 dimension rotation matrix consists of 3 direction vectors. A d dimensional vector can be rotated by swapping the coordinates of the vector and inverting the x coordinate of the result for a right rotation and inverting the y coordinate of the result for a left rotation:

JavaScript

Since all the vectors of the rotation matrix are in an axis aligned plane this algorithm can be used to change the orientation and the position of the cube. axis the rotation axis (x=0, y=1, z=2) and dir is the rotation direction (1 is right and -1 left) To rotate the axis vector, 2 components of the vector have to be swapped and one of them inverted.

e.g rotate left around the Y-axis:

JavaScript

When the position is rotated, then the indices have to be swapped. Inverting an index means to map the index i to the index N-1-i:

e.g rotate left around the Y-axis:

JavaScript

Rotation of a single cube:

JavaScript

When the cube has to be drawn, then the current position of the cube (self.current_i) and the orientation self.rot can be used to set up 4×4 transformation matrix:

JavaScript

With glPushMatrix respectively glPushMatrix. By glMultMatrix a matrix can be multiplied to the current matrix.
The following function draws a single cube. The parameters angle, axis, slice, dir and it can even apply an animation to the cube, by setting animate=True and setting parameters angle, axis, slice, dir:

JavaScript

To draw the cubes, it is sufficient to call the method draw in a loop:

JavaScript

The implementation of the class Cube works for any NxNxN Rubik’s cube.

See the example program for a 3x3x3 cube. The slices of the cube are rotated to the right by the keys 1 to 9 and to the left by the keys F1 to F9:

Of course the code uses the Legacy OpenGL in regard to your original code. But the method Cube.transformMat sets a general 4×4 model matrix for a single partial cube. Thus it is possible to port this code to modern OpenGL with ease.

JavaScript
User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement