Box rotieren

Fragen zu Grafik- & Soundproblemen und zur Spieleprogrammierung haben hier ihren Platz.
Benutzeravatar
jacdelad
Beiträge: 341
Registriert: 03.02.2021 13:39
Computerausstattung: Ryzen 5800X, 108TB Festplatte, 32GB RAM, Radeon 7770OC
Wohnort: Riesa
Kontaktdaten:

Box rotieren

Beitrag von jacdelad »

Hallo,
hat jemand vielleicht schon einen vorgefertigten Code mit dem ich eine Box rotieren kann? Ich kenne de Mittelpunkt, Breite und Höhe (und berechne damit die Box), und natürlich den Drehwinkel.

Die Formel (x*cosθ−y*sinθ ,x*sinθ+y*cosθ) und LineXY funktioniert im Prinzip für die einzelnen Punkte, aber ich bekomme das mit dem Drehpunkt nicht hin (der nicht zwingend der Mittelpunkt der Box ist).
PureBasic 6.04/XProfan X4a/Embarcadero RAD Studio 11/Perl 5.2/Python 3.10
Windows 11/Ryzen 5800X/32GB RAM/Radeon 7770 OC/3TB SSD/11TB HDD
Synology DS1821+/36GB RAM/130TB
Synology DS920+/20GB RAM/54TB
Synology DS916+ii/8GB RAM/12TB
Benutzeravatar
#NULL
Beiträge: 2235
Registriert: 20.04.2006 09:50

Re: Box rotieren

Beitrag von #NULL »

Jeder der Punkte, minus den Mittelpunkt, dann hast du die Punkte relativ zum Mittelpunkt. Die musst du dann drehen, und zum Zeichnen jeweils wieder den Mittelpunkt draufrechnen.
my pb stuff..
Bild..jedenfalls war das mal so.
Benutzeravatar
Mijikai
Beiträge: 754
Registriert: 25.09.2016 01:42

Re: Box rotieren

Beitrag von Mijikai »

Hier ein Beispiel.
Allerdings habe ich hier die Koordinaten der einzelnen Eckpunkte im Speicher.

Code: Alles auswählen

EnableExplicit

;ROTATE RECT EXAMPLE
;Author: Mijikai

Structure POINT_STRUCT
  x.f
  y.f
EndStructure

Structure RECT_STRUCT
  a.POINT_STRUCT
  b.POINT_STRUCT
  c.POINT_STRUCT
  d.POINT_STRUCT
EndStructure

Procedure.i RotateRect(*Rect.RECT_STRUCT,*Ancor.POINT_STRUCT,Angle.f,*Center.POINT_STRUCT = #Null)
  Protected rot_sin.f
  Protected rot_cos.f
  Protected *pos.POINT_STRUCT
  Protected rot.POINT_STRUCT
  Protected index.i
  Angle = Radian(Angle)
  rot_sin = Sin(Angle)
  rot_cos = Cos(Angle)
  *pos = *Rect
  For index = 0 To 3
    rot\x = *pos\x - *Ancor\x
    rot\y = *pos\y - *Ancor\y
    *pos\x = (rot\x * rot_cos - rot\y * rot_sin) + *Ancor\x
    *pos\y = (rot\x * rot_sin + rot\y * rot_cos) + *Ancor\y
    *pos + 8
  Next
  If *Center
    *Center\x = (*Rect\a\x + *Rect\b\x + *Rect\c\x + *Rect\d\x) / 4
    *Center\y = (*Rect\a\y + *Rect\b\y + *Rect\c\y + *Rect\d\y) / 4
  EndIf 
  ProcedureReturn
EndProcedure

Procedure.i DrawRect(*Rect.RECT_STRUCT)
  LineXY(*Rect\a\x,*Rect\a\y,*Rect\b\x,*Rect\b\y,#White)
  LineXY(*Rect\b\x,*Rect\b\y,*Rect\c\x,*Rect\c\y,#White)
  LineXY(*Rect\c\x,*Rect\c\y,*Rect\d\x,*Rect\d\y,#White)
  LineXY(*Rect\d\x,*Rect\d\y,*Rect\a\x,*Rect\a\y,#White)
  ProcedureReturn
EndProcedure

Procedure.i Main()
  Protected exit.i
  Protected dummy.RECT_STRUCT
  Protected ancor.POINT_STRUCT
  Protected center.POINT_STRUCT
  If InitSprite()
    If OpenWindow(0,0,0,960,600,#Null$,#PB_Window_SystemMenu|#PB_Window_ScreenCentered|#PB_Window_MinimizeGadget)
      If OpenWindowedScreen(WindowID(0),0,0,960,600)
        SetFrameRate(10)
        dummy\a\x = 400:dummy\a\y = 250
        dummy\b\x = 600:dummy\b\y = 250
        dummy\c\x = 600:dummy\c\y = 400
        dummy\d\x = 400:dummy\d\y = 400
        ancor\x = 480:ancor\y = 300
        Repeat
          Repeat
            Select WindowEvent()
              Case #PB_Event_CloseWindow
                exit = #True
              Case #Null
                Break
            EndSelect
          ForEver
          ClearScreen($0)
          If StartDrawing(ScreenOutput())
            Circle(ancor\x,ancor\y,10,#White);<- rotations punkt
            RotateRect(@dummy,@ancor,45,@center)
            Circle(center\x,center\y,10,#Red);<- rect zentral punkt
            DrawRect(@dummy)
            StopDrawing()
          EndIf
          FlipBuffers()
        Until exit
      EndIf
      CloseWindow(0)  
    EndIf  
  EndIf
  ProcedureReturn #Null
EndProcedure

Main()

End
Hoffe es hilft :)
Benutzeravatar
jacdelad
Beiträge: 341
Registriert: 03.02.2021 13:39
Computerausstattung: Ryzen 5800X, 108TB Festplatte, 32GB RAM, Radeon 7770OC
Wohnort: Riesa
Kontaktdaten:

Re: Box rotieren

Beitrag von jacdelad »

Ah vielen Dank! ich war schon kurz davor, das kriege ich bestimmt hin.
PureBasic 6.04/XProfan X4a/Embarcadero RAD Studio 11/Perl 5.2/Python 3.10
Windows 11/Ryzen 5800X/32GB RAM/Radeon 7770 OC/3TB SSD/11TB HDD
Synology DS1821+/36GB RAM/130TB
Synology DS920+/20GB RAM/54TB
Synology DS916+ii/8GB RAM/12TB
SMaag
Beiträge: 150
Registriert: 08.05.2022 12:58

Re: Box rotieren

Beitrag von SMaag »

Die Koordinaten der 4 Eckpunkte müssen zum Drehen relativ zum Drehpunkt angeben werden.

Ich arbeite an ähnlichem, hab es aber auch noch nicht fertig.

Das Prinzip hab ich aber, glaube ich, verstanden.

1. Gib die Koordinaten des Rechtecks nicht absolut an, sondern relativ zum Drehpunkt!

2. Nimm die Transformations Matrix, trag dort den Drehwinkel ein und gib eine Translation (Verschiebung) an.
Der Verschiebungsvektor ist der Punkt auf dem Bildschirm an welchem der Drehpunkt sein soll

3. Lass über die Matrix Multiplikation alle 4 Punkte berechnen, damit bekommst du die Eckpunkte der Koordinaten auf dem Bildschirm
Die Vector-Matrix Multiplikation liefert dir alles auf einmal. Die Drehung und die Verschiebung, wenn es sein muss auch noch einen
Zoom!

4. Es macht eigentlich keinen Sinn mehr, das als 2D Point zu machen, da mit den MMX Einheiten, das als Vector4-Typ in einem
einzigen Schritt berechnet werden kann! Ich stelle gerade um und mache auch 2D-Koordinaten mit den Vector-Typen.

Genau dazu hab ich das Vector-Modul geschrieben. Dann kannst du die Formeln mit dem Sinus- Cosinus eigentlich vergessen, da das
von den Vector Matrix Funktionen übernommen wird!
Das Modul ist aber noch nicht komplett getestet. Siehe dazu meinen Beitrag hier im Forum.
Antworten