Matrizen & Drehen



  • Hallo, kennst ich wer mit Matrizen und drehen aus. Hab die seite gefunden: http://lufgi9.informatik.rwth-aachen.de/projekte/schule_hochschule/rotation.htm
    aber das klappt nicht bei mir.

    Hab Punkt:
    x: 200
    y: 400

    und Dreh-Punkt:
    x: 250
    y: 450

    wie kann ich den Punkt anhand der Forml um den Dreh-Punkt drehen, so wie das in diesem Applet ist?



  • Naja, Du schiebst dir halt erst mal deinen Drehpunkt in den Nullpunkt deines Koordinatensystems rein, drehst wie verlinkt und dann schiebst Du wieder zurück.



  • Du benutzt einfach die Drehmatrix, die so aussieht:

    \begin{math}\begin{pmatrix} cos(\alpha) & -sin(\alpha) \\ sin(\alpha) & cos(\alpha) \end{pmatrix}\end{math}

    Wenn Du eine Herleitung brauchst, dann sag Bescheid 😉

    lg, freakC++



  • Ich weiß nicht welche x (px oder rotieren-x) ich da (und wo) einsetzen soll, hab schon alles vesucht.

    Gehe aber jetzt arbeiten.



  • Alpha ist der Winkel, um den du den Punkt drehen willst. Den setzt Du in die Drehmatrix ein. Dann multiplizierst Du die Matrix mit deinem Punkt! Dazu musst Du halt Matrixenmultiplikation können.

    lg, freakC++



  • So sieht das bei mir aus, hab jetzt alles zurückgestellt, hab schon alle Varianten ausprobiert, aber kommt nur blödis raus:

    float xc = 250;	// dreh-punkt x
    	float yc = 450;	// dreh-punkt y
    	float x = 200.f; // punkt x
    	float y = 400.f; // punkt y
    	float _x1 = 200; // neue x
    	float _y1 = 400; // neue y
    
    	// matrix rotations berechnung ???
    	_x1 = xc * std::cos(alpha*PI/180) - yc * std::sin(alpha*PI/180);
    	_y1 = xc * std::sin(alpha*PI/180) + yc * std::cos(alpha*PI/180);
    


  • Das Applet von dem Link im ersten Post dreht etwas um den Nullpunkt. Genauso wie die Dreh-Matrix aus dem Link (die ja hier im Thread auch nochmal hingeschrieben wurde).
    Wie Daniel E. schon geschrieben hat: Wenn du um einen anderen Punkt als den Nullpunkt drehen willst musst du zuerst verschieben, dann drehen, dann zurückschieben.
    Da eigentlich schon alles erklärt wurde, hier mal ein Beispiel:
    Du möchtest Punkt (x,y)=(2,2) um 45 Grad um Punkt (xm,ym)=(1,1) drehen.

    1. Mittelpunkt der Drehung in den Mittelpunkt des Koordinatensystems schieben:
      (x',y')=(x-xm,y-ym)=(1,1).
    2. Drehung um den Ursprung (xm',ym')=(0,0), also kannst du die Matrix brauchen
      (xNew',yNew')=(cos(45)*x'-sin(45)*y', sin(45)*x'+cos(45)*y')
      =(0,sqrt(2))
    3. Zurückschieben
      (xNew,yNew)=(xNew'+xm,yNew'+ym)=(1,1+sqrt(2))

    Wenn du diesem "Rezept" folgst, sollte es klappen :). Am besten du rechnest selbst ein Beispiel von hand durch und zeichnest alles auf. Dann sollte es klar werden.



  • Jawol hat geklappt, danke 🙂
    (was soll das ' Zeichen bedeuten)


  • Mod

    ghostboss schrieb:

    Jawol hat geklappt, danke 🙂
    (was soll das ' Zeichen bedeuten)

    Das ist eine Markierung, um x und x' zu unterscheiden.



  • Das Zeichen bedeutet nicht wirklich etwas. Es dient nur dazu, die Variablen im verschobenen System von den Variablen im Ursprungssystem zu unterscheiden.
    x' ist x im verschobenen Koordinatensystem, ich hätte aber genausogut eine neue Bezeichnung wählen können z.B. $$xOriginal,xVerschobenx_{Original}, x_{Verschoben}$$, nur wollte ich nicht so viel tippen.
    Edit: Zu langsam



  • lustig schrieb:

    Das Applet von dem Link im ersten Post dreht etwas um den Nullpunkt. Genauso wie die Dreh-Matrix aus dem Link (die ja hier im Thread auch nochmal hingeschrieben wurde).
    Wie Daniel E. schon geschrieben hat: Wenn du um einen anderen Punkt als den Nullpunkt drehen willst musst du zuerst verschieben, dann drehen, dann zurückschieben.
    Da eigentlich schon alles erklärt wurde, hier mal ein Beispiel:
    Du möchtest Punkt (x,y)=(2,2) um 45 Grad um Punkt (xm,ym)=(1,1) drehen.

    1. Mittelpunkt der Drehung in den Mittelpunkt des Koordinatensystems schieben:
      (x',y')=(x-xm,y-ym)=(1,1).
    2. Drehung um den Ursprung (xm',ym')=(0,0), also kannst du die Matrix brauchen
      (xNew',yNew')=(cos(45)*x'-sin(45)*y', sin(45)*x'+cos(45)*y')
      =(0,sqrt(2))
    3. Zurückschieben
      (xNew,yNew)=(xNew'+xm,yNew'+ym)=(1,1+sqrt(2))

    Wenn du diesem "Rezept" folgst, sollte es klappen :). Am besten du rechnest selbst ein Beispiel von hand durch und zeichnest alles auf. Dann sollte es klar werden.

    Danke für den Beitrag, der kam mir grade recht, da ich auch meine Rotationen bastel derzeit. Aber ich hab Probleme bei der Umsetzung:

    for ( int i=0; i < 6; i++ )
    {
        f32 x_origin = m_vertices[i].x - m_size.x / 2;
        f32 y_origin = m_vertices[i].y - m_size.y / 2;
    
        f32 x = (m_vertices[i].x * std::cos(angle)) -  (m_vertices[i].y * std::sin(angle) );
        f32 y = (m_vertices[i].y * std::cos(angle)) +  (m_vertices[i].x * std::sin(angle) );
    
        m_vertices[i].x = x + x_origin;
        m_vertices[i].y = y + y_origin;
    }
    

    Es passiert einfach nichts. Das Sprite rotiert nicht.
    Man muss dazu sagen, dass ich das ausführe bevor die Projektionsmatrix hinzugefügt wird. (orthographisch, OpenGL):
    Hab ich was übersehen?

    edit: Ich sehe grade dass ich negative Werte bekomme. Die Position ist gerade 10, die halbe Größe 32. Klar, das gibt -22. Und die Endkoordinaten sind dann völlig aus den Fugen.



  • Ich sehe nicht genau, was du im Quellcode versuchst...
    Was ist x_origin? Die Verschiebung?
    Dann ist aber

    f32 x = (m_vertices[i].x * std::cos(angle)) -  (m_vertices[i].y * std::sin(angle) );
    

    falsch, denn du musst ja zuerst verschieben, dann rotieren (also m_vertrices[i].x durch das verschobene ersetzen).

    Wenn x_origin der verschobene Punkt ist (das was ich x' genannt habe), dann stimmt es auch nicht. In dem Fall solltest du x_origin statt m_vertrices[i].x verwenden um zu rotieren.



  • So hab ich es gemacht:

    void RotatePoint(float angle, sf::Vector2f &point){
            // myRotationPoint ist der Punkt um den rotiert wird
    
    		float x = point.x - myRotationPoint.x; 		
            float y = point.y - myRotationPoint.y;
    
    		point.x = x * std::cos(angle*PI/180) - y * std::sin(angle*PI/180);
    		point.y = x * std::sin(angle*PI/180) + y * std::cos(angle*PI/180);
    
    		point.x += myRotationPoint.x;
    		point.y += myRotationPoint.y;
    	}
    

Anmelden zum Antworten