Rechteck drehen - Koordinaten?



  • Ich habe ein Rechteck mit den Eck-Koordinaten a.x, a.y, b.x, b.y, c.x, c.y, d.x, d.y. Nun möchte ich das Rechteck um α Grad im Uhrzeigersinn drehen und die neuen Eck-Koordinaten bekommen.

    Um das Ganze leichter verständlich zu machen, habe ich es unter folgendem Link nochmal zusammengefasst:
    http://www.capuzza.com/mathe.htm

    Bin für jede Hilfe dankbar!

    Zeek



  • Rotation um den Nullpunkt funktioniert folgendermaßen:

    Schreibe die Punkte als Vektoren:

    (x)
    (y)
    

    und multipliziere dann mit der Matrix

    (cos [e]alpha[/e]  -sin [e]alpha[/e])
    (sin [e]alpha[/e]   cos [e]alpha[/e])
    

    Zur Rotation um beliebige Punkte mußt Du zuerst so verschieben, daß der fragliche Punkt im Ursprung liegt, dann wie oben rotieren. Anschließend den Verschiebungsvektor mitrotieren und zurückverschieben.

    MfG Jester



  • Ich möchte um den Mittelpunkt drehen und habe es wie folgt versucht:

    a.x = B/2 - cos(arctan(B/A)+alpha) * sqrt( (A/2) ^2 + (B/2)^2)
    a.y = A/2 - sin(arctan(B/A)+alpha) * sqrt( (A/2) ^2 + (B/2)^2)
    b.x = B/2 + cos(-arctan(B/A)-alpha) * sqrt( (A/2) ^2 + (B/2)^2)
    b.y = A/2 - sin(-arctan(B/A)-alpha) * sqrt( (A/2) ^2 + (B/2)^2)
    c.x = B/2 - cos(-arctan(B/A)-alpha) * sqrt( (A/2) ^2 + (B/2)^2)
    c.y = A/2 + sin(-arctan(B/A)-alpha) * sqrt( (A/2) ^2 + (B/2)^2)
    d.x = B/2 + cos(arctan(B/A)+alpha) * sqrt( (A/2) ^2 + (B/2)^2)
    d.y = A/2 + sin(arctan(B/A)+alpha) * sqrt( (A/2) ^2 + (B/2)^2)
    

    Das scheint für a und d prima zu funktionieren, bei b und c stimmt irgendwas nicht...

    Bitte evtl. mal den Link anschauen, da habe ich auch eine kleine Zeichnung gemacht.

    zeek



  • was genau verstehst Du an meiner Erklärung nicht?



  • Ich weiß nicht wie ich das in eine Formel umsetzen kann...



  • (a b)   (x)   ( a*x + b*y )
    (c d) * (y) = ( c*x + d*y )
    

    So ist die Matrixmultiplikation definiert.
    Hab grad keine Zeit, werde wenn nötig später noch genauer.

    MfG Jester



  • Hab den ersten Beitrag nochmal editiert.
    Schreib doch erstmal ne Funktion, die um den Nullpunkt rotiert.
    Wenn Du das hast ist alles ganz einfach.

    MfG Jester



  • Ich komme da echt nicht weiter... Bin kein Mathematiker.. 🙂

    (a b)   (x)   ( a*x + b*y )
    (c d) * (y) = ( c*x + d*y )
    

    Das verstehe ich schon nicht. Wie kann man a, b, c oder d mit irgendwas multiplizieren wenn es eine Koordinate mit x- und y-Wert ist?

    Zeek



  • Nein: a,b,c,d,x,y sind einfach Zahlen. Den Punkt schreibe ich als Tupel

    (x,y) oder halt senkrecht so wie oben. Eine Matrix ist einfach nur ein rechteckiges Zahlenschema. Die angegebene Formel zeigt, wie man eine Matrix mit einem solchen Tupel multiplizieren kann. Wenn Du für die Matrix die noch weiter oben engegebene mit dem sin/cos nimmst, dann ist das eine Rotationsmatrix, die dreht den Punkt um den Ursprung.

    Formel zur Drehung des Punkts (x,y) um den Ursprung ist demnach also:

    x' = cos α * x - sin α * y
    y' = sin α * x + cos α * y

    wenn Du damit mehr anfangen kannst.
    Damit kannst Du jetzt schonmal Punkte um den Ursprung rotieren.

    Willst Du jetzt den Punkt x,y um den Punkt (px,py) rotieren, dann mußt Du folgendes machen:

    Bilde Verschiebungsvektor (x-px, y-py) rotiere diesen um den Ursprung und addiere anschließend (px,py) wieder dazu.
    MfG Jester



  • Bestens, so kann selbst ich das verstehen.. 🙂

    Meine Formeln für die Eckpunkte lauten nun wie folgt:

    a.x = (Cos([e]alpha[/e]) * -(A / 2)) - (Sin([e]alpha[/e]) * -(B / 2)) + A / 2
        a.y = (Sin([e]alpha[/e]) * -(A / 2)) + (Cos([e]alpha[/e]) * -(B / 2)) + B / 2
        b.x = (Cos([e]alpha[/e]) * (A / 2)) - (Sin([e]alpha[/e]) * -(B / 2)) + A / 2
        b.y = (Sin([e]alpha[/e]) * (A / 2)) + (Cos([e]alpha[/e]) * -(B / 2)) + B / 2
        c.x = (Cos([e]alpha[/e]) * -(A / 2)) - (Sin([e]alpha[/e]) * (B / 2)) + A / 2
        c.y = (Sin([e]alpha[/e]) * -(A / 2)) + (Cos([e]alpha[/e]) * (B / 2)) + B / 2
        d.x = (Cos([e]alpha[/e]) * (A / 2)) - (Sin([e]alpha[/e]) * (B / 2)) + A / 2
        d.y = (Sin([e]alpha[/e]) * (A / 2)) + (Cos([e]alpha[/e]) * (B / 2)) + B / 2
    

    A = Breite des Rechtecks, B = Höhe des Rechtecks.

    Vielen Dank für Deine Hilfe!

    Das war übrigens mein Programm um es auszuprobieren:
    🙂 http://www.capuzza.com/scrnsave.exe 🙂

    Zeek



  • Geile Idee, nur leider verbraucht das tierisch Systemresourcen. Vielleicht schaust du nochmal, was du noch verbessern kannst. Außerdem musste ich die EXE abschießen per Task-Manager. Danach war die Task-Leiste wech... 🙄



  • Hi ZeekOnline wie kriegst du das denn hin mit dem bildschirmschoner würd mich auch interessieren... Proggst du in visual c++? Wenn ja wie machst du den bildschirmschoner dann.

    Danke

    MFG

    Hansi



    1. Ja, das Programm verbraucht tierisch viel Resourcen, da alles vom Prozessor berechnet wird und das ganze in einer Endlosschleife läuft. Anstehende Events werden allerdings weiterhin mir höherer Priorität ausgeführt. Um die große Last zu verhindern müsste man, zumindest bei dieser Geschwindigkeit, DirectX oder OpenGL benutzen. Die jetzige Funktion sollte eigentlich nicht dazu dienen, eine ständige Rotation zu zeigen, sondern um ein vorhandenes Bild im Speicher einmalig in einem bestimmten Winkel um den Mittelpunkt zu drehen. Also so, wie es die bekannten Bildbearbeitungprogramme machen.

    2. Das Programm lässt sich beenden indem man einmalig mit der linken Maustaste klickt. Dann wird auch die Taskbar wieder gezeigt. Man könnte, und das wäre für einen Bildschirmschoner sinnvoll, auf Mausbewegung oder Tastaturbenutzung reagieren.

    3. Ich habe dieses Beispiel jetzt in VB programmiert, dürfte allerdings in (Visual) C++ ähnlich funktionieren, da ich fast nur API-Funktionen benutze. Um Windows ein Programm als Bildschirmschoner erkennen zu lassen, muss der Programmname "SCRNSAVE" lauten. Damit meine ich natürlich den Projektnamen, nicht den Dateinamen selbst. Dann sollte man noch verhindern, dass zwei Instanzen des Programmes gleichzeitig laufen, denn Windows startet den Bildschirmschoner gerne mehrmals. Anhand der übergebenen Parameter zum Programmstart kann man übrigens noch feststellen, ob der Bildschirmschoner selbst, die Einstellungen oder sonstiges aufgerufen wurde. Hierzu werde ich gerne noch genauer wenn gewünscht.

    Die Funktion für die Drehung brauchte ich für die PlgBlt-Funktion aus der gdi32.dll.

    The PlgBlt function performs a bit-block transfer of the bits of color data from the specified rectangle in the source device context to the specified parallelogram in the destination device context. If the given bitmask handle identifies a valid monochrome bitmap, the function uses this bitmap to mask the bits of color data from the source rectangle.

    Ich brauche also die Koordinaten a, b und c um das Ziel-Parallelogramm anzugeben.

    Hier noch die allgemeine Deklaration:

    Declare Function PlgBlt Lib "gdi32" Alias "PlgBlt" (ByVal hdcDest As Long, lpPoint As POINTAPI, ByVal hdcSrc As Long, ByVal nXSrc As Long, ByVal nYSrc As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hbmMask As Long, ByVal xMask As Long, ByVal yMask As Long) As Long
    

    Parameter:

    · hdcDest
    Identifies the destination device context.
    
    · lpPoint
    Points to an array of three points in logical space that identify three corners of the destination parallelogram. The upper-left corner of the source rectangle is mapped to the first point in this array, the upper-right corner to the second point in this array, and the lower-left corner to the third point. The lower-right corner of the source rectangle is mapped to the implicit fourth point in the parallelogram.
    
    · hdcSrc
    Identifies the source device context.
    
    · nXSrc
    Specifies the x-coordinate, in logical units, of the upper-left corner of the source rectangle.
    
    · nYSrc
    Specifies the y-coordinate, in logical units, of the upper-left corner of the source rectangle.
    
    · nWidth
    Specifies the width, in logical units, of the source rectangle.
    
    · nHeight
    Specifies the height, in logical units, of the source rectangle.
    
    · hbmMask
    Identifies an optional monochrome bitmap that is used to mask the colors of the source rectangle.
    
    · xMask
    Specifies the x-coordinate of the upper-left corner of the the monochrome bitmap.
    
    · yMask
    Specifies the y-coordinate of the upper-left corner of the the monochrome bitmap.
    

    Rückgabe:

    If the function succeeds, the return value is nonzero.
    
    If the function fails, the return value is zero. To get extended error information, call GetLastError.
    

    Zeek



  • Aber wieso muss das programm dann SCRNSAVE haeißen wenn ich doch sowieso alles in den code schreiben muss. Aber normal müssete sich doch dann auch das icon zu diesem bilschirmschoner-ding ändern. DAs is aber bei mir nich der fall. Achso du weißt nicht zufällig wie man das in die systemsteuerung reinkriegen kann?

    DANKE schonmal bis hier hin

    MFG

    Hansi



  • Hi,

    den Bildschirmschoner bekommst du in die Auswahl in der Systemsteuerung, indem du die .src-Datei in das Windows-Verzeichnis kopierst.



  • OK das hab ich jetz ma gemacht. Ich hab den linker auf .src umgestellt und hat diese .src datei dann ins windows verzeichnis reinkopiert,. aber es tut sich nicks. Wie kann ich denn bei windows xp exe dateien in src dateien ändern?

    Danke

    HAnsi



  • Ups ich hatte das programm nich in ne scr sondern in src gelinkt das war falsch. DAnke trotzdem

    Hansi



  • Mein Programm hat die Endung .exe.. um als Bildschirmschoner zu gelten braucht es die Eundung *.scr.

    In der Registry kannste dann noch den Standard-Schoner bestimmen, inkl. aller Einstellungen. 🤡


Anmelden zum Antworten