宿題の一部として機能するルービック キューブを設計する必要があります。私は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 が実際に一番上の行です。
これは立方体が変形する問題で、何が原因かわかりません。
不明な点があればお知らせください。投稿を編集するか、コメントに返信します。