【问题标题】:Rotate layer Rubik's Cube旋转层魔方
【发布时间】:2020-11-04 23:23:14
【问题描述】:

我正在使用 SDL 和 OpenGL 用 C 语言编写一个魔方。我已经完成了所有的实现,除了层移动的旋转(现在如果我按下'r'或'f',例如,右层或前层会改变它的颜色)。我真的不知道如何实现图层的旋转。

这是我绘制立方体的渲染实现。

注意:如果我想顺时针向右旋转图层,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);
}

【问题讨论】:

  • 这里有大量的硬编码值和重复代码,基本上是 6 个面分为 9 个四边形。难怪你很难用它做任何事情。
  • 请将您的问题标题更新为Need help to implement the rotation of a rubiks layer,然后分享代码 sn-p 和 Makefile 以帮助重现错误。我将工单标记为需要改进,请编辑并添加详细信息。
  • 您需要将立方体的内部表示从硬编码更改为变量...using tables+for loops 将大大简化您的代码...对于魔方的立方体层旋转,请参阅:Quaternion rotation does not work as excepted

标签: c opengl sdl rubiks-cube


【解决方案1】:

除非您将代码重构为某种“块”类,否则旋转将很难跟踪,这样一个 3x3 的块数组将构成您的魔方。每个块将完全相同:白色底部,黄色顶部,蓝色左侧等......当在屏幕上堆叠 3x3 时,将隐藏其他面。这比跟踪一组面到一组颜色要简单得多。

然后,您需要明确区分魔方的代码模型和魔方的绘制模型。这对于能够连续应用多重旋转很重要。

所以在代码中你会想要一个你的立方体的模型。 3x3 数组很简单,其中每一行都是一张脸。然后看一张脸,例如:

1 2 3

4 5 6

7 8 9

您将需要访问一个旋转此面的函数(查看与 numpy.rot90 等效的函数),这样当围绕指向屏幕外的轴旋转时,将产生:

3 6 9

2 5 8

1 4 7

但是这里要小心。这只是改变了对象在内存中的布局,并没有对屏幕上的绘制模型做任何事情。因此,您需要在 OpenGL 中应用相应的旋转。完成此操作后,您的代码模型现在将与绘制的模型匹配,并且您可以执行任意次数的连续旋转。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-28
    • 2011-07-06
    相关资源
    最近更新 更多