glRotatef - Wie ermittle ich die Koordinaten?



  • Liebe Forumsgemeinde!

    Hier schreibt ein angehender Informatiker (3. Semester) der vor einem, für die meisten sicher kleinem, Problem steht.

    Ich bin drauf und dran ein kleines OpenGL Spiel zu programmieren. Ein Roboter (zusammengesetzt aus skalierten Spheren) mit einer Kugel als Finger (hat nur einen Finger) soll eine andere Kugel aufheben können.

    Die Kollisionsabfrage hierzu habe ich bereits geschrieben und getestet. Solange ich die Koordinate der Kugeln kenne ist alles in Ordnung.

    Da ich die Bewegungen des Roboters mit glRotatef ermögliche, stehe ich vor folgendem Problem: Wie ermittle ich die Koordinaten des Fingers? Folgend das Codeschnipsel. Zu Beginn hat der Finger(die Kugel) die Koordinaten (0.0, 8.75, 0.0).

    /* Rotieren des gesamten Roboters */
    	glRotatef(robz, 0,0,1);			
    	glRotatef(roby, 0,1,0);
    
    	/* Roboter wird gezeichnet */
    	glPushMatrix();
    	Functions::zeichneSeg(5.0);
    
    	glTranslatef(0.0, 5.0, 0.0);
    	glRotatef(robz2, 0,0,1);
    	Functions::zeichneSeg(2.5);
    
    	glTranslatef(0.0, 2.5, 0.0);
    	glRotatef(robz3, 0,0,1);
    	Functions::zeichneSeg(1.25);
    	glTranslatef(0.0, 1.25, 0.0);
    	glutSolidSphere(0.25, 40, 40);		//der Finger
    	glPopMatrix();
    

    Meine Vermutung ist, dass der Vektor (0/8.75/0) mit einer Matrix multipliziert werden muss. Nur mit welcher? Vielen vielen Dank für eure Mühen!

    Euer pop



  • Du könntest die Transformation mit gluProject nachahmen. Die Matrizen bekommst du aus dem Kontext durch glGetDoublev.
    Andernseits könntest du die Matrix nachbauen mit GLM und auf den Punkt anwenden.



  • Die gesuchte Matrix findet sich bereits in deinem Code, hier die relevanten Teile:

    glTranslatef(0.0, 5.0, 0.0);
    glRotatef(robz2, 0,0,1);
    
    glTranslatef(0.0, 2.5, 0.0);
    glRotatef(robz3, 0,0,1);
    
    glTranslatef(0.0, 1.25, 0.0);
    

    😉



  • Vielen dank für die schnelle Antwort. Ich setze mich nun mal daran die Vorschläge umzusetzen.

    Edit: Habe mich für GLM entschieden. Nur wurde der Hinweis gegeben, dass sich die gesuchte Matrix in meinem Code befindet. Doch ich bin verwirrt,
    da ich keine Matrix finde, die mit dem Vektor (0, 8.75, 0) multipliziert auch nur annähernd sinnvolle Werte ergibt.
    Für einen weiteren Hinweis wäre ich euch sehr verbunden!



  • Nach vielem vielem Rumprobieren bin ich ... kein Stück weiter :(.

    Die Idee (mein Dozent hat mich darauf hingewiesen) ist nun folgende

    /* Matrix bekommen VORHER*/
    	glGetDoublev(GL_MODELVIEW_MATRIX, matrix1);
    
    	/* Bewegung des gesamten Roboters */
    	glTranslatef(robMoveX, 0.0, robMoveZ);	
    
    	/* Rotieren des gesamten Roboters */
    	glRotatef(robz, 0,0,1);			
    	glRotatef(roby, 0,1,0);
    
    	/* Roboter wird gezeichnet */
    	glPushMatrix();
    
    	zeichneSeg(5.0);
    
    	glTranslatef(0.0, 5.0, 0.0);
    	glRotatef(robz2, 0,0,1);
    	zeichneSeg(2.5);
    
    	glTranslatef(0.0, 2.5, 0.0);
    	glRotatef(robz3, 0,0,1);
    	zeichneSeg(1.25);
    	glTranslatef(0.0, 1.25, 0.0);
    	glutSolidSphere(0.25, 40, 40);		//der Finger
    
    	/* Matrix bekommen NACHHER*/
    	glGetDoublev(GL_MODELVIEW_MATRIX, matrix2);
    	glPopMatrix();
    

    Ich soll die Model(oder Projection, dass weiß ich nicht mehr genau) Matrix mittels glGetDoublev extrahieren.

    Dann soll ich folgende Operation durchführen:

    gesuchteMatrix = matrix2 * matrix1(invers)

    neuePositionDesFingers = gesuchteMatrix * finger(vektor)

    Leider stimmen die Koordinaten nicht ganz.

    glm::mat4x4 m1Invers = glm::inverse(glm::mat4x4(m1));
    
    	glm::mat4x4 dieGesuchte = m2 * m1Invers;
    	glm::vec4 finger = glm::vec4(0.0, 8.75, 0.0, 0.0);
    
    	glm::vec4 newPosition = dieGesuchte * finger;
    

    Bin ich auf der richtigen Fährte? Ich sehe langsam nur noch Brett.

    Vielen Dank für eure Mühen.



  • Folgendermassen geht es vielleicht ein bischen einfacher weil Du Dich nicht um irgendwelche Inversen kuemmern musst:

    // lokale transformationen ausfuehren und resultierende matrix auslesen:
        glPushMatrix();
        glLoadIdentity();
        glTranslatef(0.0, 2.5, 0.0);
        glRotatef(robz3, 0,0,1);
        glTranslatef(0.0, 1.25, 0.0);
        glGetDoublev(GL_MODELVIEW_MATRIX, matrix);
        glPopMatrix();
    
        // matrix anwenden
        glMultMatrixd(matrix);
        glutSolidSphere(0.25, 40, 40);
    


  • Danke für die Antwort. Ich habe dann die Matrix, die ich hieraus bekomme

    glMultMatrixd(matrix);
    

    mit dem Finger multipliziert. Leider stimmen die Werte nur dann, wenn sich der gesamte Roboter bewegt. Lasse ich ein Gelenk abknicken, stimmen die Positionswerte des Fingers überhaupt nicht mehr. Wenn mich nicht alles täuscht, sind die errechneten Koordinaten die Selben wie vorher.

    Für weitere Hilfe wäre ich euch sehr verbunden.



  • Nochmals vielen Dank an die Helfenden. Die Lösung ist gefunden. Alles wie im Post vom 19:10:18 14.06.2013, nur der Vektor muss (natürlich 😉 ) 0,0,0,1 heißen.



  • Hi Leute!

    Eine Frage hätte ich da noch: Wie implemeniert man eine dauerhafte Drehung eines gezeichneten Objekes?

    /*Zeichne Bodenfläche */
    	glPushMatrix();
    	glTranslatef(0.0, -2.0, 0.0);
    	glScalef(20.0, 20.0, 20.0);
    	glmDraw(b, GLM_SMOOTH | GLM_TEXTURE);
    	glPopMatrix();
    

    Hier wird eine Bodenfläche gezeichnet. Nun möchte ich, dass sich diese Fläche um die eigene Achse dauerhaft dreht. Mit rotatef kann ich umgehen (auf Tatstendruck eine Drehung vollziehen). Bislang endeten die Versuche in einer Endlosschleife 😞 .

    Vielen vielen Dank!



  • Keine Ahnung, wie du dort eine Endlosschleife auslöst, aber normalerweise wird einfach der Tastendruck ausgewertet und eine Variable aktualisiert, welche die Drehung angibt und bei jedem Paint-Durchgang für glRotate verwendet wird.



  • Richtig. Nur soll die Drehung nicht auf Tastendruck, sondern automatisch und permanent vollzogen werden - ohne das eine Taste gedrückt wird.


Anmelden zum Antworten