I have to design functional rubik cube as part of my homework. I am not using openGL directly, but a framework that was provided. ( All functions that do not belong to openGL and do not have their body listed here will be presumed correct)
Functionalities: all faces need to be rotated if selected by pressing a key. The whole cube must rotate.
The rotation of the whole cube is correct and does not make the subject of this question.
In order to do this, I created the rubik cube from 27 smaller cubes(cube size is 3) and, at the same time, a tridimensional array. A replica of the cube that contains small cubes indexes. In order to better understand this :
if initially one face was:
0 1 2
3 4 5
6 7 8
after a rotation it should be:
6 3 0
7 4 1
8 5 2
I can rotate the cubes relative to axis X or Y an indefinite number of times and it works perfectly. However, if I combine the rotations( alternate X rotations with Y rotations in a random way) there appear cases when the cube deforms. As this happens inconsistently, it is difficult for me to find the cause.
This is how I am creating the cube :
int count = 0;
for (int i = -1; i < 2; i++)
for(int j = -1; j < 2; j++)
for(int k = -1; k < 2; k++) {
RubikCube.push_back(drawCube());
RubikCube.at(count)->translate(4*i,4*j,4*k);
CubIndici[j+1][k+1][i+1] = count;
count++;
}
The function drawCube() effectively draws a cube of size 4 with the center positioned in origin. CubIndici is the 3D array that I use to store the positions of the cube.
This is the function that I am using to rotate a matrix in the 3D array. (I have double checked it so it should be correct, but perhaps I am missing something).
void rotateMatrix(int face_index, int axis) {
if (axis == 0 )
{
for ( int i = 0; i < 3; i++)
for( int j = i; j < 3; j++)
{
swap(&CubIndici[i][j][face_index],&CubIndici[j][i][face_index]);
}
for (int i = 0; i < 3; i++)
for(int j = i; j < 3; j++)
{
swap(&CubIndici[i][j][face_index],&CubIndici[2-i][j][face_index]);
}
}
if (axis == 1 )
{
for ( int i = 0; i < 3; i++)
for( int j = i; j < 3; j++)
{
swap(&CubIndici[face_index][i][j],&CubIndici[face_index][j][i]);
}
for (int i = 0; i < 3; i++)
for(int j = i; j < 3; j++)
{
swap(&CubIndici[face_index][i][j],&CubIndici[face_index][2-i][j]);
}
}
}
The CubIndici 3d array is global, so I need the axis parameter to determine what kind of rotation to performe( relative to X, Y or Z)
on pressing w key I should rotate a( hardcoded, for now) face around axis X
for (int i = 0; i < 3; i++)
for(int j = 0; j < 3; j++)
RubikCube.at(CubIndici[i][j][1])->rotateXRelativeToPoint(
RubikCube.at(CubIndici[1][1][1])->axiscenter, 1.57079633);
rotateMatrix(1,0);
CubIndici11 should always contain the cube that is in the center of the face CubIndici[*][*]1.
Similarly,
for (int i = 0; i < 3; i++)
for(int j = 0; j < 3; j++)
RubikCube.at(CubIndici[2][i][j])->rotateYRelativeToPoint(
RubikCube.at(CubIndici[2][1][1])->axiscenter, 1.57079633);
rotateMatrix(2,1);
for rotating on axis Y.
1.57079633 is the radian equivalent of 90 degrees
For a better understanding I add the detailed display of rotating the left face on X axis and the top down one on Y axis.
The first block of coordinates is the initial cube face. ( The CubIndici index matrix is unmodified)
pre rotatie - coordinates and indexes for each of the cubes of the face. post rotatie - coordiantes and indexes after rotating the objects. ( The matrix was not touched ) post rotatie matrice - after rotating the matrix aswell. If you compare the indexes of "pre rotatie" with "post rotatie matrice" you will notice 90 degrees turn.
This is the first rotation ( rotate the left face around X) and it is entirely correct.
On the next rotation however, the cubes that should be contained in the top down face ( as well as in the left one) should be 2,5,8. However, they appear as 2,5,6. If you look at the first "post rotatie matrice" 2,5,8 are indeed the top row.
This is the issue that deforms the cube and I don't know what causes it.
If anything is unclear please let me know and I will edit the post or reply to the comment!