T
Hallo,
ich versuche gerade, wie so viele OpenGlEinsteiger, einen Rubiks Cube zu rendern. Leider ist das Ergebnis noch nicht ganz zufriedenstellend. Scheinbar habe ich einen kleinen Fehler im Algorithmus um die Cubes nach dem Drehen wieder richtig anzuordnen.
Vorgehensweise:
1. eine "Zeile" (9 Würfelteile) des Cubes wird um 90 Grad rotiert(zeitgestuert)
2. sobald 90 grad erreicht sind werden die betreffenden Cubes in der 3x3x3 Matrix neu angeordnet. Also die Cubes positionieren sich immer 2 Cubes weiter nach vorne oben unten usw.
3. Anschließend wird der Rotationswinkel der einzelnen Zeile wieder auf 0 Grad gesetzt und stattdessen wird jeder Cube in der Zeile, um 90 Grad gedreht beim nächsten Rendern( nach dem der Cube "translatet" wurde).
Das Verfahren funktioniert soweit recht gut solange ein Cube nicht um 2 Achsen gedreht wurde. Dann passieren seltsame Dinge. Zum Verdeutlichen habe ich meine Renderfunktion -und die Rotatefunktion angehängt.Den kompletten SourceCode als Download gibt es hier. Es handelt sich um ein Visual Studio 2008 Projekt welches auf der SDL aufgebaut ist.
Würde mich freuen wenn mir jemand helfen könnte den Fehler zu finden.
void RubiksCube::Render()
{
// Rotation
glRotatef(m_rotWholeCube[0], 1.0f, 0.0f, 0.0f);
glRotatef(m_rotWholeCube[1], 0.0f, 1.0f, 0.0f);
glRotatef(m_rotWholeCube[2], 0.0f, 0.0f, 1.0f);
// Startposition for drawing
for(int i=0; i<3; i++) { // X_AXIS
glRotatef(m_rotx[i], 1.0f, 0.0f, 0.0f);
for(int j=0; j<3; j++) { // Y_AXIS
glRotatef(m_roty[j], 0.0f, 1.0f, 0.0f);
for(int k=0; k<3; k++) { // Z_AXIS
glRotatef(m_rotz[k], 0.0f, 0.0f, 1.0f);
glTranslatef(i-1.0f, 1.0f-j, k-1.0f);
// rotate cubelet itself when it has changed position
glRotatef(m_cubes[i][j][k].GetRotAngleX(), 1.0f, 0.0f, 0.0f);
glRotatef(m_cubes[i][j][k].GetRotAngleY(), 0.0f, 1.0f, 0.0f);
glRotatef(m_cubes[i][j][k].GetRotAngleZ(), 0.0f, 0.0f, 1.0f);
m_cubes[i][j][k].Render();
// (UN)rotate cubelet itself when it has changed position
glRotatef(-m_cubes[i][j][k].GetRotAngleZ(), 0.0f, 0.0f, 1.0f);
glRotatef(-m_cubes[i][j][k].GetRotAngleY(), 0.0f, 1.0f, 0.0f);
glRotatef(-m_cubes[i][j][k].GetRotAngleX(), 1.0f, 0.0f, 0.0f);
glTranslatef(1.0f-i, -1.0f+j, 1.0f-k);
glRotatef(-m_rotz[k], 0.0f, 0.0f, 1.0f);
}
glRotatef(-m_roty[j], 0.0f, 1.0f, 0.0f);
}
glRotatef(-m_rotx[i], 1.0f, 0.0f, 0.0f);
}
glRotatef(-m_rotWholeCube[0], 1.0f, 0.0f, 0.0f);
glRotatef(-m_rotWholeCube[1], 0.0f, 1.0f, 0.0f);
glRotatef(-m_rotWholeCube[2], 0.0f, 0.0f, 1.0f);
}
int RubiksCube::RotateX(int which, int count)
{
m_rotx[which] += m_rotAmount*1;
if(m_rotx[which] >= 90.0f) {
// change cube postion in matrix !!!
// corner cublets [uneven] ( 1, 3, 7, 9)
CubeLet tmpCube;
tmpCube = m_cubes[which][0][0];
m_cubes[which][0][0] = m_cubes[which][2][0];
m_cubes[which][2][0] = m_cubes[which][2][2];
m_cubes[which][2][2] = m_cubes[which][0][2];
m_cubes[which][0][2] = tmpCube;
// middle cublets [even] (2, 4, 6, 8)
tmpCube = m_cubes[which][0][1];
m_cubes[which][0][1] = m_cubes[which][1][0];
m_cubes[which][1][0] = m_cubes[which][2][1];
m_cubes[which][2][1] = m_cubes[which][1][2];
m_cubes[which][1][2] = tmpCube;
m_cubes[which][0][0].Rotate(0);
m_cubes[which][2][0].Rotate(0);
m_cubes[which][2][2].Rotate(0);
m_cubes[which][0][2].Rotate(0);
m_cubes[which][0][1].Rotate(0);
m_cubes[which][1][0].Rotate(0);
m_cubes[which][2][1].Rotate(0);
m_cubes[which][1][2].Rotate(0);
m_cubes[which][1][1].Rotate(0);
m_rotx[which] = 0;
return 1; // finish rotation !
}
return 0;
}
Vielen Dank schonmal.
SOURCE-Download