Box rotieren

Fragen zu Grafik- & Soundproblemen und zur Spieleprogrammierung haben hier ihren Platz.
Benutzeravatar
jacdelad
Beiträge: 404
Registriert: 03.02.2021 13:39
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).
Guten Morgen, das ist ein schöner Tnetennba!

PureBasic 6.21/Windows 11 x64/Ryzen 7900X/32GB RAM/3 TB SSD
Synology DS1821+/DX517, 130.9TB+50.8TB+2TB SSD
Benutzeravatar
#NULL
Beiträge: 2237
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: 404
Registriert: 03.02.2021 13:39
Wohnort: Riesa
Kontaktdaten:

Re: Box rotieren

Beitrag von jacdelad »

Ah vielen Dank! ich war schon kurz davor, das kriege ich bestimmt hin.
Guten Morgen, das ist ein schöner Tnetennba!

PureBasic 6.21/Windows 11 x64/Ryzen 7900X/32GB RAM/3 TB SSD
Synology DS1821+/DX517, 130.9TB+50.8TB+2TB SSD
SMaag
Beiträge: 184
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