2

宿題の一部として機能するルービック キューブを設計する必要があります。私はopenGLを直接使用していませんが、提供されたフレームワークを使用しています。( openGL に属さず、ここに本体がリストされていないすべての関数は、正しいと推定されます)

機能: キーを押して選択した場合、すべての面を回転する必要があります。立方体全体が回転する必要があります。

立方体全体の回転は正しく、この質問の主題にはなりません。

これを行うために、27 個の小さな立方体 (立方体のサイズは 3) からルービック キューブを作成し、同時に 3 次元配列を作成しました。小さなキューブ インデックスを含むキューブのレプリカ。これをよりよく理解するために:

最初の 1 つの面が次の場合:

0 1 2
3 4 5
6 7 8 

回転後は次のようになります。

6 3 0
7 4 1
8 5 2

X 軸または Y 軸に対してキューブを無期限に回転させることができ、完全に機能します。ただし、回転を組み合わせると (X 回転と Y 回転をランダムに交互に)、立方体が変形する場合があります。これは一貫性がなく発生するため、原因を特定するのは困難です。

これは私がキューブを作成する方法です:

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++;
        }

関数 drawCube() は、中心が原点に配置されたサイズ 4 の立方体を効果的に描画します。CubIndici は、立方体の位置を格納するために使用する 3D 配列です。

これは、3D 配列で行列を回転させるために使用している関数です。(私はそれを再確認したので正しいはずですが、おそらく何かが欠けています)。

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]);
                 }
    }
}

CubIndici 3d 配列はグローバルであるため、実行する回転の種類 (X、Y、または Z に対して) を決定するには、軸パラメーターが必要です。

wキーを押すと、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);

CubIndici 1 1には、面 CubIndici[*][*] 1の中心にある立方体が常に含まれている必要があります。

同様に、

        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);

Y 軸を中心に回転します。

1.57079633 は、90 度に相当するラジアンです。

理解を深めるために、左の面を X 軸で回転させ、上から下へ Y 軸で回転させる詳細表示を追加します。

画像

座標の最初のブロックは、最初の立方体面です。(CubIndici インデックス マトリックスは変更されていません)

pre rotatie - 面の立方体ごとの座標とインデックス。post rotatie - オブジェクトを回転させた後の座標とインデックス。(マトリックスは触れられていませんでした)ポスト回転マトリックス - マトリックスも回転させた後。「pre rotatie」と「post rotatie matrix」のインデックスを比較すると、90 度回転していることがわかります。

これは最初の回転 (X を中心に左面を回転させる) であり、完全に正しいです。

ただし、次の回転では、上から下の面 (および左側の面) に含まれる立方体は 2、5、8 である必要があります。ただし、それらは 2,5,6 として表示されます。最初の「post rotatie マトリックス」を見ると、2,5,8 が実際に一番上の行です。

これは立方体が変形する問題で、何が原因かわかりません。

不明な点があればお知らせください。投稿を編集するか、コメントに返信します。

4

1 に答える 1

1

<x;y>立方体のスライス内の位置にあるセルの時計回りの PI/2 回転の式は次のとおりです。

  x' = 2 - y
  y' = x

同様に、反時計回りの回転の場合:

  x' = y
  y' = 2 - x

ただし、これらはローテーションであり、配列のインプレース変更を行いたいと考えています。回転は、2 つのミラー対称性の組み合わせで置き換えることができます。

時計回り:

  <x;y>  ->  <y;x> 
  <x;y>  ->  <2-x;y>

反時計回りは、これらの関数の反対の構成です。

これらの式を考えると、回転関数は次のように記述できます。

 void rotateMatrix_X_CW(int face_index) {
     int i,j;  
     for ( i = 0; i < 2; i++)
         for( j = i; j < 3; j++) 
         {
             swap(CubIndici[i][j][face_index],CubIndici[2-i][j][face_index]);
         }
     for ( i = 0; i < 2; i++)
         for( j = i; j < 3; j++) 
         {
             swap(CubIndici[i][j][face_index],CubIndici[j][i][face_index]);
         }
 }

 void rotateMatrix_X_CCW(int face_index) {
     int i,j;  
     for ( i = 0; i < 2; i++)
         for( j = i; j < 3; j++) 
         {
             swap(CubIndici[i][j][face_index],CubIndici[j][i][face_index]);
         }
     for ( i = 0; i < 2; i++)
         for( j = i; j < 3; j++) 
         {
             swap(CubIndici[i][j][face_index],CubIndici[2-i][j][face_index]);
         }
 }

そこから他の軸を実装できるはずです。

于 2012-11-10T00:29:59.293 に答える