简体   繁体   English

旋转层魔方

[英]Rotate layer Rubik's Cube

I'm programming a rubik cube in c with SDL and OpenGl.我正在使用 SDL 和 OpenGl 在 c 中编写一个魔方。 I have done all the implementation, except the rotation of a layer move (now if i press 'r' or 'f', for example, right or front layers change its colours).我已经完成了所有的实现,除了层移动的旋转(现在,如果我按 'r' 或 'f',例如,右或前层会改变它的颜色)。 I don't really know how to implement the rotation of a layer.我真的不知道如何实现图层的旋转。

Here is my render implementation which draws the cube.这是我绘制立方体的渲染实现。

Note: mov is 7 if i want to rotate clockwise right layer, 8 if i want to rotate left layer etc, **s is an array with the rgb color of each sticker of the cube注意:mov 是 7 如果我想顺时针旋转右层,8 如果我想旋转左层等等,**s 是一个数组,其中包含立方体每个贴纸的 rgb 颜色

static void
Render(int mov, double **s)
{
    static float color[8][3] = {
        {1.0, 1.0, 0.0},
        {1.0, 0.0, 0.0},
        {0.0, 0.0, 0.0},
        {0.0, 1.0, 0.0},
        {0.0, 1.0, 1.0},
        {1.0, 1.0, 1.0},
        {1.0, 0.0, 1.0},
        {0.0, 0.0, 1.0}
    };

    static float cube[56][3] = {
        // Cara 1
        {0.6, 0.6, 0.6},
        {0.6, 0.6, 0.2},
        {0.6, 0.6, -0.2},
        {0.6, 0.6, -0.6},
        {0.6, 0.2, -0.6},
        {0.6, -0.2, -0.6},
        {0.6, -0.6, -0.6},
        {0.6, -0.6, -0.2},
        {0.6, -0.6, 0.2},
        {0.6, -0.6, 0.6},
        {0.6, -0.2, 0.6},
        {0.6, 0.2, 0.6},
        {0.6, 0.2, 0.2},
        {0.6, 0.2, -0.2},
        {0.6, -0.2, -0.2},
        {0.6, -0.2, 0.2},

        // Cara 2
        {0.2, 0.6, 0.6},
        {-0.2, 0.6, 0.6},
        {-0.6, 0.6, 0.6},
        {-0.6, 0.6, 0.2},
        {-0.6, 0.6, -0.2},
        {-0.6, 0.6, -0.6},
        {-0.2, 0.6, -0.6},              // 22
        {0.2, 0.6, -0.6},
        {0.2, 0.6, -0.2},
        {0.2, 0.6, 0.2},
        {-0.2, 0.6, 0.2},
        {-0.2, 0.6, -0.2},              // 27

        // Cara 3
        {-0.6, 0.2, 0.6},
        {-0.6, 0.2, 0.2},
        {-0.6, 0.2, -0.2},
        {-0.6, 0.2, -0.6},
        {-0.6, -0.2, -0.6},
        {-0.6, -0.6, -0.6},             // 33
        {-0.6, -0.6, -0.2},
        {-0.6, -0.6, 0.2},
        {-0.6, -0.6, 0.6},
        {-0.6, -0.2, 0.6},
        {-0.6, -0.2, 0.2},
        {-0.6, -0.2, -0.2},             // 39

        // Cara 4
        {-0.2, -0.6, 0.6},
        {-0.2, -0.6, 0.2},
        {-0.2, -0.6, -0.2},
        {-0.2, -0.6, -0.6},
        {0.2, -0.6, -0.6},              // 44
        {0.2, -0.6, -0.2},
        {0.2, -0.6, 0.2},
        {0.2, -0.6, 0.6},               // 47

        // Cara 5
        {0.2, 0.2, 0.6},
        {0.2, -0.2, 0.6},
        {-0.2, -0.2, 0.6},
        {-0.2, 0.2, 0.6},

        // Cara 6
        {0.2, 0.2, -0.6},
        {0.2, -0.2, -0.6},
        {-0.2, -0.2, -0.6},
        {-0.2, 0.2, -0.6}

    };

    glClearColor(0.0, 0.0, 0.0, 1.0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glBegin(GL_QUADS);

    // Cara 1

    glColor3f(s[2][0], s[2][1], s[2][2]);
    glVertex3fv(cube[8]);
    glVertex3fv(cube[9]);
    glVertex3fv(cube[10]);
    glVertex3fv(cube[15]);

    glColor3f(s[5][0], s[5][1], s[5][2]);
    glVertex3fv(cube[10]);
    glVertex3fv(cube[11]);
    glVertex3fv(cube[12]);
    glVertex3fv(cube[15]);

    glColor3f(s[8][0], s[8][1], s[8][2]);
    glVertex3fv(cube[0]);
    glVertex3fv(cube[1]);
    glVertex3fv(cube[12]);
    glVertex3fv(cube[11]);              // ST2

    glColor3f(s[1][0], s[1][1], s[1][2]);
    glVertex3fv(cube[7]);
    glVertex3fv(cube[8]);
    glVertex3fv(cube[15]);
    glVertex3fv(cube[14]);

    glColor3f(s[4][0], s[4][1], s[4][2]);
    glVertex3fv(cube[12]);
    glVertex3fv(cube[13]);
    glVertex3fv(cube[14]);
    glVertex3fv(cube[15]);

    glColor3f(s[7][0], s[7][1], s[7][2]);
    glVertex3fv(cube[1]);
    glVertex3fv(cube[2]);
    glVertex3fv(cube[13]);
    glVertex3fv(cube[12]);

    glColor3f(s[0][0], s[0][1], s[0][2]);
    glVertex3fv(cube[5]);
    glVertex3fv(cube[6]);
    glVertex3fv(cube[7]);
    glVertex3fv(cube[14]);

    glColor3f(s[3][0], s[3][1], s[3][2]);
    glVertex3fv(cube[4]);
    glVertex3fv(cube[5]);
    glVertex3fv(cube[14]);
    glVertex3fv(cube[13]);

    glColor3f(s[6][0], s[6][1], s[6][2]);
    glVertex3fv(cube[2]);
    glVertex3fv(cube[3]);
    glVertex3fv(cube[4]);
    glVertex3fv(cube[13]);

    // Cara 2
    glColor3f(s[11][0], s[11][1], s[11][2]);
    glVertex3fv(cube[0]);
    glVertex3fv(cube[1]);
    glVertex3fv(cube[25]);
    glVertex3fv(cube[16]);

    glColor3f(s[10][0], s[10][1], s[10][2]);
    glVertex3fv(cube[1]);
    glVertex3fv(cube[2]);
    glVertex3fv(cube[24]);
    glVertex3fv(cube[25]);

    glColor3f(s[9][0], s[9][1], s[9][2]);
    glVertex3fv(cube[2]);
    glVertex3fv(cube[3]);
    glVertex3fv(cube[23]);
    glVertex3fv(cube[24]);

    glColor3f(s[12][0], s[12][1], s[12][2]);
    glVertex3fv(cube[23]);
    glVertex3fv(cube[24]);
    glVertex3fv(cube[27]);
    glVertex3fv(cube[22]);

    glColor3f(s[15][0], s[15][1], s[15][2]);
    glVertex3fv(cube[22]);
    glVertex3fv(cube[27]);
    glVertex3fv(cube[20]);
    glVertex3fv(cube[21]);

    glColor3f(s[16][0], s[16][1], s[16][2]);
    glVertex3fv(cube[27]);
    glVertex3fv(cube[26]);
    glVertex3fv(cube[19]);
    glVertex3fv(cube[20]);

    glColor3f(s[17][0], s[17][1], s[17][2]);
    glVertex3fv(cube[26]);
    glVertex3fv(cube[17]);
    glVertex3fv(cube[18]);
    glVertex3fv(cube[19]);

    glColor3f(s[14][0], s[14][1], s[14][2]);
    glVertex3fv(cube[25]);
    glVertex3fv(cube[16]);
    glVertex3fv(cube[17]);
    glVertex3fv(cube[26]);

    glColor3f(s[13][0], s[13][1], s[13][2]);
    glVertex3fv(cube[24]);
    glVertex3fv(cube[25]);
    glVertex3fv(cube[26]);
    glVertex3fv(cube[27]);

    // Cara 3

    glColor3f(s[47][0], s[47][1], s[47][2]);
    glVertex3fv(cube[18]);
    glVertex3fv(cube[19]);
    glVertex3fv(cube[29]);
    glVertex3fv(cube[28]);

    glColor3f(s[46][0], s[46][1], s[46][2]);
    glVertex3fv(cube[19]);
    glVertex3fv(cube[20]);
    glVertex3fv(cube[30]);
    glVertex3fv(cube[29]);

    glColor3f(s[45][0], s[45][1], s[45][2]);
    glVertex3fv(cube[20]);
    glVertex3fv(cube[21]);
    glVertex3fv(cube[31]);
    glVertex3fv(cube[30]);

    glColor3f(s[48][0], s[48][1], s[48][2]);
    glVertex3fv(cube[31]);
    glVertex3fv(cube[30]);
    glVertex3fv(cube[39]);
    glVertex3fv(cube[32]);

    glColor3f(s[51][0], s[51][1], s[51][2]);
    glVertex3fv(cube[32]);
    glVertex3fv(cube[39]);
    glVertex3fv(cube[34]);
    glVertex3fv(cube[33]);

    glColor3f(s[52][0], s[52][1], s[52][2]);
    glVertex3fv(cube[39]);
    glVertex3fv(cube[38]);
    glVertex3fv(cube[35]);
    glVertex3fv(cube[34]);

    glColor3f(s[53][0], s[53][1], s[53][2]);
    glVertex3fv(cube[38]);
    glVertex3fv(cube[37]);
    glVertex3fv(cube[36]);
    glVertex3fv(cube[35]);

    glColor3f(s[50][0], s[50][1], s[50][2]);
    glVertex3fv(cube[29]);
    glVertex3fv(cube[28]);
    glVertex3fv(cube[37]);
    glVertex3fv(cube[38]);

    glColor3f(s[49][0], s[49][1], s[49][2]);
    glVertex3fv(cube[30]);
    glVertex3fv(cube[29]);
    glVertex3fv(cube[38]);
    glVertex3fv(cube[39]);

    // Cara 4
    glColor3f(s[33][0], s[33][1], s[33][2]);
    glVertex3fv(cube[35]);
    glVertex3fv(cube[36]);
    glVertex3fv(cube[40]);
    glVertex3fv(cube[41]);

    glColor3f(s[34][0], s[34][1], s[34][2]);
    glVertex3fv(cube[34]);
    glVertex3fv(cube[35]);
    glVertex3fv(cube[41]);
    glVertex3fv(cube[42]);

    glColor3f(s[35][0], s[35][1], s[35][2]);
    glVertex3fv(cube[33]);
    glVertex3fv(cube[34]);
    glVertex3fv(cube[42]);
    glVertex3fv(cube[43]);

    glColor3f(s[32][0], s[32][1], s[32][2]);
    glVertex3fv(cube[43]);
    glVertex3fv(cube[42]);
    glVertex3fv(cube[45]);
    glVertex3fv(cube[44]);

    glColor3f(s[29][0], s[29][1], s[29][2]);
    glVertex3fv(cube[44]);
    glVertex3fv(cube[45]);
    glVertex3fv(cube[7]);
    glVertex3fv(cube[6]);

    glColor3f(s[28][0], s[28][1], s[28][2]);
    glVertex3fv(cube[45]);
    glVertex3fv(cube[46]);
    glVertex3fv(cube[8]);
    glVertex3fv(cube[7]);

    glColor3f(s[27][0], s[27][1], s[27][2]);
    glVertex3fv(cube[46]);
    glVertex3fv(cube[47]);
    glVertex3fv(cube[9]);
    glVertex3fv(cube[8]);

    glColor3f(s[30][0], s[30][1], s[30][2]);
    glVertex3fv(cube[41]);
    glVertex3fv(cube[40]);
    glVertex3fv(cube[47]);
    glVertex3fv(cube[46]);

    glColor3f(s[31][0], s[31][1], s[31][2]);
    glVertex3fv(cube[42]);
    glVertex3fv(cube[41]);
    glVertex3fv(cube[46]);
    glVertex3fv(cube[45]);

    // Cara 5
    glColor3f(s[18][0], s[18][1], s[18][2]);
    glVertex3fv(cube[11]);
    glVertex3fv(cube[48]);
    glVertex3fv(cube[16]);
    glVertex3fv(cube[0]);

    glColor3f(s[21][0], s[21][1], s[21][2]);
    glVertex3fv(cube[48]);
    glVertex3fv(cube[51]);
    glVertex3fv(cube[17]);
    glVertex3fv(cube[16]);

    glColor3f(s[24][0], s[24][1], s[24][2]);
    glVertex3fv(cube[51]);
    glVertex3fv(cube[28]);
    glVertex3fv(cube[18]);
    glVertex3fv(cube[17]);

    glColor3f(s[25][0], s[25][1], s[25][2]);
    glVertex3fv(cube[50]);
    glVertex3fv(cube[37]);
    glVertex3fv(cube[28]);
    glVertex3fv(cube[51]);

    glColor3f(s[26][0], s[26][1], s[26][2]);
    glVertex3fv(cube[40]);
    glVertex3fv(cube[36]);
    glVertex3fv(cube[37]);
    glVertex3fv(cube[50]);

    glColor3f(s[23][0], s[23][1], s[23][2]);
    glVertex3fv(cube[47]);
    glVertex3fv(cube[40]);
    glVertex3fv(cube[50]);
    glVertex3fv(cube[49]);

    glColor3f(s[20][0], s[20][1], s[20][2]);
    glVertex3fv(cube[9]);
    glVertex3fv(cube[47]);
    glVertex3fv(cube[49]);
    glVertex3fv(cube[10]);

    glColor3f(s[19][0], s[19][1], s[19][2]);
    glVertex3fv(cube[10]);
    glVertex3fv(cube[49]);
    glVertex3fv(cube[48]);
    glVertex3fv(cube[11]);

    glColor3f(s[22][0], s[22][1], s[22][2]);
    glVertex3fv(cube[51]);
    glVertex3fv(cube[50]);
    glVertex3fv(cube[49]);
    glVertex3fv(cube[48]);

    // Cara 6
    glColor3f(s[36][0], s[36][1], s[36][2]);
    glVertex3fv(cube[44]);
    glVertex3fv(cube[6]);
    glVertex3fv(cube[5]);
    glVertex3fv(cube[53]);

    glColor3f(s[39][0], s[39][1], s[39][2]);
    glVertex3fv(cube[43]);
    glVertex3fv(cube[44]);
    glVertex3fv(cube[53]);
    glVertex3fv(cube[54]);

    glColor3f(s[42][0], s[42][1], s[42][2]);
    glVertex3fv(cube[33]);
    glVertex3fv(cube[43]);
    glVertex3fv(cube[54]);
    glVertex3fv(cube[32]);

    glColor3f(s[43][0], s[43][1], s[43][2]);
    glVertex3fv(cube[32]);
    glVertex3fv(cube[54]);
    glVertex3fv(cube[55]);
    glVertex3fv(cube[31]);

    glColor3f(s[44][0], s[44][1], s[44][2]);
    glVertex3fv(cube[31]);
    glVertex3fv(cube[55]);
    glVertex3fv(cube[22]);
    glVertex3fv(cube[21]);

    glColor3f(s[41][0], s[41][1], s[41][2]);
    glVertex3fv(cube[55]);
    glVertex3fv(cube[52]);
    glVertex3fv(cube[23]);
    glVertex3fv(cube[22]);

    glColor3f(s[38][0], s[38][1], s[38][2]);
    glVertex3fv(cube[52]);
    glVertex3fv(cube[4]);
    glVertex3fv(cube[3]);
    glVertex3fv(cube[23]);

    glColor3f(s[37][0], s[37][1], s[37][2]);
    glVertex3fv(cube[53]);
    glVertex3fv(cube[5]);
    glVertex3fv(cube[4]);
    glVertex3fv(cube[52]);

    glColor3f(s[40][0], s[40][1], s[40][2]);
    glVertex3fv(cube[53]);
    glVertex3fv(cube[54]);
    glVertex3fv(cube[55]);
    glVertex3fv(cube[52]);

    glEnd();

    glMatrixMode(GL_MODELVIEW);
    if (mov == 1) {
        glRotatef(2.0, 0, 0, 0);
    }
    else if (mov == 2) {
        glRotatef(2.0, 1.0, 0, 0);
    }
    else if (mov == 3) {
        glRotatef(2.0, 0, 1.0, 0);
    }
    else if (mov == 4) {
        glRotatef(2.0, 0, 0, 1.0);
    }
    else
        glRotatef(1.0, 0, 0, 0);
}

Rotation is going to be too hard to keep track of unless you refactor your code into some sort of "Block" class, whereby a 3x3 array of blocks will make your Rubik's cube.除非您将代码重构为某种“块”类,否则 3x3 块数组将构成魔方,否则很难跟踪旋转。 each block will be exactly the same: white bottom, yellow top, blue left, etc... and when stacked 3x3 on screen will hide the other faces.每个块都将完全相同:白色底部,黄色顶部,蓝色左侧等......并且在屏幕上堆叠 3x3 时将隐藏其他面。 This is a much easier simplification than keeping track of an array of faces to an array of colors.这比跟踪一组面部到一组颜色要容易得多。

Then you will want to make a clear distinction between the code model of your Rubik's cube, and the drawn model of your Rubik's cube.然后,您需要明确区分魔方的代码模型和魔方的绘制模型。 This is important in being able to apply multiply rotations successively.这对于能够连续应用多次旋转很重要。

So in code you will want to have a model of your cube.因此,在代码中,您将需要一个多维数据集模型。 a 3x3 array is easy, where each row is a face.一个 3x3 的数组很容易,其中每一行都是一张脸。 Then looking at a face, for example:然后看一张脸,例如:

1 2 3 1 2 3

4 5 6 4 5 6

7 8 9 7 8 9

you will want access to a function that rotates this face (look at something that does the equivalent as numpy.rot90), such that when rotated around the axis that is pointing out of the screen, will produce:您将需要访问一个旋转这个面的函数(看看与 numpy.rot90 等效的东西),这样当围绕指向屏幕外的轴旋转时,将产生:

3 6 9 3 6 9

2 5 8 2 5 8

1 4 7 1 4 7

But be careful here.但是这里要小心。 This only changed the layout of the object in memory and hasn't done anything to the drawn model on screen.这只改变了内存中对象的布局,并没有对屏幕上绘制的模型做任何事情。 So you will need to apply the corresponding rotation in OpenGL.所以你需要在 OpenGL 中应用相应的旋转。 After this is done, your code model will now match the drawn model, and you can perform as many successive rotations as you want.完成此操作后,您的代码模型现在将匹配绘制的模型,您可以根据需要执行任意数量的连续旋转。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM