Bild um Mittelpunkt drehen



  • Hallo,

    ich will eine Animation erstellen. Dabei soll sich ein Bild um seinen Mittelpunkt drehen. Ich mach das mit gdiplus

    Zunächst das Drehen um einen Winkel, der in Edit1 eingegeben ist:

    Image1->Canvas->Brush->Color = clWhite;
    Image1->Canvas->FillRect(Image1->ClientRect);
    
    Gdiplus::Graphics graphics(Image1->Canvas->Handle);
    
    double dValue = StrToFloat(Edit1->Text);
    
    Gdiplus::Image image(L"bild.jpg");
    graphics.DrawImage(&image,0,100);
    graphics.TranslateTransform(260.0f,80.0f);
    graphics.RotateTransform(dValue);
    graphics.DrawImage(&image,0,0);
    

    Hier veruche ich das mit dem Mittelpunkt zu integrieren:

    static float winkel=0.0f;
    static float radius=1.0f;
    
    int x = Image1->Width / 2;
    int y = Image1->Height / 2;
    
    Image1->Canvas->Brush->Color = clWhite;
    Image1->Canvas->FillRect(Image1->ClientRect);
    
    Gdiplus::Graphics graphics(Image1->Canvas->Handle);
    
    double dValue = StrToFloat(Edit1->Text);
    
    Gdiplus::Image image(L"bild.jpg");
    graphics.DrawImage(&image,0,100);
    graphics.TranslateTransform(260.0f,80.0f);
    graphics.RotateTransform(dValue);
    
    winkel = dValue;
    int xNew=x+sin(winkel)*radius;
    int yNew=y+cos(winkel)*radius;
    
    graphics.DrawImage(&image,xNew,yNew);
    

    Gelingt nur nicht 😞 Vielleicht hat jemand einen Tip ? Danke !



  • graphics.TranslateTransform(-mx, -my);
    graphics.RotateTransform(dValue);
    graphics.TranslateTransform(mx, my);
    


  • Hallo,

    erstma danke, hab's eigebaut, er zeigt jetzt aber gar nix an.

    Gdiplus::Image image(L"bild.jpg");
    winkel = dValue;
    double xNew=x+sin(winkel)*radius;
    double yNew=y+cos(winkel)*radius;
    
    graphics.TranslateTransform(-xNew, -yNew);
    graphics.RotateTransform(dValue);
    graphics.TranslateTransform(xNew, yNew);
    
    graphics.DrawImage(&image,0,0);
    


  • mx und my sind die Mittelpunktkoordinaten (bei dir x und y).
    Und bei RotateTransform wird der Winkel in Radians angegeben (d.h. von 0 - 2*PI).
    Die eigene Winkelberechnung mit sin und cos brauchst du dann nicht.

    Und du solltest zuerst das Bild zeichnen, bevor es rotiert wird 😉



  • Hallo,

    danke für die vielen Hinweise ! Hab in Translate die Mittelpunkte x/y eingefügt, Bild wird normal angezeigt, ohne Drehung. Ich versuch nachher mal mathematisch zu begreifen was Du da schreibst. Und dann vielleicht auch ne Drehung hinzubekommen.

    Gdiplus::Image image(L"bild.jpg");
    graphics.DrawImage(&image,0,0);
    
    graphics.TranslateTransform(-x, -y);
    graphics.RotateTransform(dValue);
    graphics.TranslateTransform(x, y);
    
    graphics.DrawImage(&image,0,0);
    


  • Sorry, einmal noch nerven. Hab die Radiant Umrechnung gemacht und mit dem Wert Rotate aufgerufen. Mein Bild wird aber immer nur durch den ersten DrawImage normal angezeigt.

    Gdiplus::Image image(L"bild.jpg");
    graphics.DrawImage(&image,0,0);
    
    double dRadiant = atan(dValue) * 360 / (2 * M_PI);
    
    graphics.TranslateTransform(-x, -y);
    graphics.RotateTransform(dRadiant);
    graphics.TranslateTransform(x, y);
    
    graphics.DrawImage(&image,0,0);
    


  • Ich musste bei TranslateTansform erst mit positiven, danach mit negativen Werten arbeiten. So macht er es:

    graphics.TranslateTransform(x, y);
    		graphics.RotateTransform(dValue);
    		graphics.TranslateTransform(-x, -y);
    

    Nur in einer Schleife will das bekloppte Bild sich nicht drehen. Wenn ich in der Schleife Application->ProcessMessages() einbaue - ich will die Drehung ja sehen - passiert gar nix. Ruf ich das Drehen als Funktion auf ist das Bild am Ende normal ohne Drehung. Das geht nur, wenn ich das jeweils gedrehte Bild speichere und dieses dann wieder drehe. Sehe aber auch dann die Drehung nicht sondern nur das Endbild, dass natürlich unscharf ist. Wenn ich da noch nen Tip bekomme freu ich mich und kann es bei mir einbauen 😉



  • Vergiß Application->ProcessMessages()!!!
    Für eine Animation benötigst du einen Timer und mußt dort dann deine Funktion für das Image-Control aufrufen (und im Timer dann den Rotationswinkel erhöhen).

    Du solltest die Rotation dann immer vom Originalbild aus machen (und nicht Step by Step), da sonst die Image immer ungenauer wird.

    PS: Wenn dValue den Rotationswinkel in Grad (d.h. 0- 360) angibt, dann sollte die Umrechnung nach Radiant so lauten:

    double dRadiant = dValue (2 * M_PI) / 360;
    // bzw.
    double dRadiant = dValue * M_PI / 180;
    

    Edit: Habe aber gerade bei GDI+ Rotate rectangle about its center gesehen, daß der Winkel wohl doch in Grad angegeben wird - mea culpa.

    Und bei TransformTranslate wird wohl doch zum Mittelpunkt verschoben (anstatt den Mittelpunkt zum Nullpunkt zu verschieben und dann zu rotieren und wieder zurückzuverschieben).



  • So,

    vor jedem Aufruf mit neuem Winkel muss noch

    Image1->Canvas->Brush->Color = clWhite;
    	Image1->Canvas->FillRect(Image1->ClientRect);
    

    mit rein, nun geht es.

    Vielen Dank an Th69 für den Einsatz !


Anmelden zum Antworten