Seite 1 von 1

Muster drehen

Verfasst: 07.02.2014 20:15
von Purebasium
Hallo allerseits,
ich habe eine Frage:
Wie kann man eine Ansammlung von Sprites drehen?
Ich habe die Positionen der sprites in einer map gespeichert.
(in einem Quadrat von 10 * 10 Feldern wird jeweils gespeichert ob ein grünes oder ein rotes Feld angezeigt wird)

Wie kann ich ich dieses gesamte Muster nun um 90 bzw. 180 oder 270 grad drehen?

Re: Muster drehen

Verfasst: 14.02.2014 17:38
von _sivizius
Möglichkeit
1. Nutze die 3D-Engine und drehe damit dein Bild,
2. Nutze die Vektorrechnung. Jedes Pixel lässt sich als x,y-Paar darstellen und mit einer festen http://de.wikipedia.org/wiki/Drehmatrix berechnest du für jedes x,y-Paar die neue x',y'-Position:
/ x' \ _ / +cos(a) -sin(a) \ / x \
\ y '/ ‾ \ +sin(a) +cos(a) / \ y /

Code: Alles auswählen

Procedure YawImage(image, a)
  dXa.d = Cos(a)  ;a ist der Winkel,
  dXb.d = -Sin(a) ;um den das Bild gedreht werden soll
  dYa.d = -dXb    ;in Radiant. (180° =^= pi)
  dYb.d = dXa     ;Für Grad nutze Radian(a).
  Debug ImageWidth(image)*dXa+ImageHeight(image)*dXb
  Debug ImageWidth(image)*dYa+ImageHeight(image)*dYb
  new = CreateImage(#PB_Any, ImageWidth(image)*dXa+ImageHeight(image)*dXb, ImageWidth(image)*dYa+ImageHeight(image)*dYb)
  For x=0 To ImageWidth(image)-1
    For y=0 To ImageHeight(image)-1
      StartDrawing(ImageOutput(image))
      c.l = Point(x,y)
      StopDrawing()
      x_ = x*dXa+y*dXb
      y_ = x*dYa+y*dYb
      Debug x_
      Debug y_
      If x_<ImageWidth(new)-1 And y_<ImageHeight(new)-1 And x_>0 And y_>0
        StartDrawing(ImageOutput(new))
        Plot(x_,y_,c)
        StopDrawing()
      EndIf
    Next
  Next
  ProcedureReturn new
EndProcedure
image = CreateImage(#PB_Any,100,100,24,RGB(0,255,0))
UsePNGImageEncoder()
SaveImage(image, GetTemporaryDirectory()+"so.png", #PB_ImagePlugin_PNG)
image = YawImage(image, Radian(90))
SaveImage(image, GetTemporaryDirectory()+"yaw.png", #PB_ImagePlugin_PNG)
so ähnlich zumindestens, irgendwo ist bei mir ein fehler, oder mehr. Bin aber nicht gut in Matrizenrechnung.

Re: Muster drehen

Verfasst: 14.02.2014 18:15
von Lothar Schirm
So sieht die Matrizenmultiplikation, d.h. die Rotation, in einfachen Gleichungen aus:
x' = cos(a) * x - sin(a) * y
y' = sin(a) * x + cos(a) * y
Damit muesste es gehen.

Re: Muster drehen

Verfasst: 15.02.2014 05:25
von Demivec
Verzeihen Sie die Englisch Kommentare.

Code: Alles auswählen

Procedure rotateGrid(Array grid(2), quarterTurns = 0) ;1 quarterTurns = 90 degrees clockwise, -1 quarterTurns = -90 degrees clockwise
  Protected Dim gridCopy(0, 0), i, j, x = ArraySize(grid(), 1), y = ArraySize(grid(), 2)
  
  If x <> y: ProcedureReturn: EndIf ;grid is not square
  CopyArray(grid(), gridCopy())
  
  Select quarterTurns % 4
    Case 0 ; no change
      ProcedureReturn
    Case 1, -3 ;90 degree clockwise (also 270 degree counter-clockwise)
      For i = 0 To x
        For j = 0 To x
          grid(i, j) = gridCopy(j, x - i)
        Next
      Next
    Case 2, -2 ;180 degree clockwise (also 180 degree counter-clockwise)
      For i = 0 To x
        For j = 0 To x
          grid(i, j) = gridCopy(x - i, x - j)
        Next
      Next
    Case 3, -1 ;270 degree clockwise (also 90 degree counter-clockwise)
      For i = 0 To x
        For j = 0 To x
          grid(i, j) = gridCopy(x - j, i)
        Next
      Next
  EndSelect
  
EndProcedure


InitSprite()
OpenWindow(0, 0, 0, 500, 200, "Rotate", #PB_Window_SystemMenu)
OpenWindowedScreen(WindowID(0), 0, 0, 200, 200)

ButtonGadget(0, 250, 20, 220, 20, "Rotate 90 degrees clockwise")
ButtonGadget(1, 250, 60, 220, 20, "Rotate 90 degrees counter-clockwise")
ButtonGadget(2, 250, 100, 220, 20, "Rotate 180 degrees")

rot = CreateSprite(#PB_Any, 20, 20)
gruen = CreateSprite(#PB_Any, 20, 20)

StartDrawing(SpriteOutput(rot))
Box(0, 0, 20, 20, RGB(255, 0, 0))
StopDrawing()

StartDrawing(SpriteOutput(gruen))
Box(0, 0, 20, 20, RGB(0, 255, 0))
StopDrawing()

Dim spritePos(9, 9)
For y = 0 To 9
  For x = 0 To 9
    If Random(1)
      spritePos(x, y) = rot
    Else
      spritePos(x, y) = gruen
    EndIf
  Next
Next

Repeat
  Repeat
    event = WindowEvent()
    If event = #PB_Event_Gadget
      Select EventGadget()
        Case 0 ;rotate clockwise 90 degrees
          rotateGrid(spritePos(), 1)
        Case 1 ;rotate counter-clockwise 90 degrees
          rotateGrid(spritePos(), -1)
        Case 2 ;rotate 180 degrees
          rotateGrid(spritePos(), 2)
      EndSelect
    EndIf
    
      
  Until event = 0 Or event = #PB_Event_CloseWindow
      
  ClearScreen(0)
  For y = 0 To 9
    For x = 0 To 9
      DisplaySprite(spritePos(x, y), x * 20, y * 20)
    Next
  Next
  FlipBuffers()
  Delay(10)
  
Until event = #PB_Event_CloseWindow

(Übersetzung via Google.)

Re: Muster drehen

Verfasst: 21.02.2014 19:26
von Purebasium
Vielen Dank