OpenGl Rubiks Cube Rotationsproblem



  • 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


Anmelden zum Antworten