You can rotate an array {solved 2 ways}

Just starting out? Need help? Post your questions and find answers here.
User avatar
Rook Zimbabwe
Addict
Addict
Posts: 4322
Joined: Tue Jan 02, 2007 8:16 pm
Location: Cypress TX
Contact:

You can rotate an array {solved 2 ways}

Post by Rook Zimbabwe »

Lets say you have an array SHIP(2) and it looks like this:

0,0,0
0,1,1
0,0,0

Is it possible to rotate the array 90 degrees so it would look like this?

0,1,0
0,1,0
0,0,0

I think we did this in tetris but I am not sure how it was done?

:D
Last edited by Rook Zimbabwe on Wed Sep 23, 2009 10:07 pm, edited 1 time in total.
Binarily speaking... it takes 10 to Tango!!!

Image
http://www.bluemesapc.com/
User avatar
blueznl
PureBasic Expert
PureBasic Expert
Posts: 6166
Joined: Sat May 17, 2003 11:31 am
Contact:

Re: Can you rotate an array?

Post by blueznl »

Rook Zimbabwe wrote: Is it possible to rotate the array 90 degrees so it would look like this?
Yes. It is possible. I hope that answers your question.
( PB6.00 LTS Win11 x64 Asrock AB350 Pro4 Ryzen 5 3600 32GB GTX1060 6GB)
( The path to enlightenment and the PureBasic Survival Guide right here... )
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: Can you rotate an array?

Post by netmaestro »

Can you rotate an array?
I'm not sure if I can or not :? Lemme check...

Code: Select all

; Define piece arrays
Global Dim piece.b(4,4)
Global Dim tmp.b(4,4)

; Create a piece
For i=0 To 4
  piece(2,i)=1
Next
piece(3,4)=1:piece(4,4)=1

; Make a 'cleared' pixel
CreateImage(0, 6, 6, 24)
StartDrawing(ImageOutput(0))
  Box(0,0,6,6,GetSysColor_(#COLOR_BTNFACE))
StopDrawing()

; Make a 'set' pixel
CreateImage(1, 6, 6, 24)
StartDrawing(ImageOutput(1))
  Box(0,0,6,6,#Black)
StopDrawing()

Procedure DrawPiece()
  For j = 0 To 4
    For i = 0 To 4
      StartDrawing(WindowOutput(0))
        If piece(i,j)
          DrawImage(ImageID(1), 40+7*i,10+7*j)
        Else
          DrawImage(ImageID(0), 40+7*i,10+7*j)
        EndIf
      StopDrawing()
    Next
  Next
EndProcedure  

Procedure RotateLeft90()
  For j=0 To 4
    For i=0 To 4
      If piece(j,i):tmp(i,4-j)=1:Else:tmp(i,4-j)=0:EndIf
    Next
  Next
  Swap tmp(),piece()
EndProcedure

Procedure RotateRight90()
  For j=0 To 4 
    For i=0 To 4
      If piece(j,i):tmp(4-i,j)=1:Else:tmp(4-i,j)=0:EndIf
    Next
  Next
  Swap tmp(),piece()
EndProcedure

OpenWindow(0,0,0,120,120,"",#PB_Window_ScreenCentered|#PB_Window_SystemMenu)
ButtonGadget(0,10,75,100,20,"Flip Left 90")
ButtonGadget(1,10,96,100,20,"Flip Right 90")
DrawPiece()

Repeat
  EventID = WaitWindowEvent()
  Select EventID
    Case #PB_Event_Repaint
      DrawPiece()
    Case #PB_Event_Gadget
      Select EventGadget()
        Case 0
          RotateLeft90()
          DrawPiece()
        Case 1
          RotateRight90()
          DrawPiece()
      EndSelect
  EndSelect
Until EventID = #PB_Event_CloseWindow
...Yup! :mrgreen:
BERESHEIT
User avatar
Rook Zimbabwe
Addict
Addict
Posts: 4322
Joined: Tue Jan 02, 2007 8:16 pm
Location: Cypress TX
Contact:

Re: Can you rotate an array?

Post by Rook Zimbabwe »

That is SOOOOOO cool!!! :mrgreen:

I have MANY uses for this!
Binarily speaking... it takes 10 to Tango!!!

Image
http://www.bluemesapc.com/
User avatar
Deeem2031
Enthusiast
Enthusiast
Posts: 216
Joined: Sat Sep 20, 2003 3:57 pm
Location: Germany
Contact:

Re: Can you rotate an array?

Post by Deeem2031 »

Not exactly what you asked for, but "rotating" an array is faster by simply calculating the indexes differently:

Code: Select all

; Define piece arrays
Global Dim piece.b(4,4)
Global r

Macro piece_0(x,y)
  piece(x,y)
EndMacro

Macro piece_90(x,y)
  piece(y,4-x)
EndMacro

Macro piece_180(x,y)
  piece(4-x,4-y)
EndMacro

Macro piece_270(x,y)
  piece(4-y,x)
EndMacro

; Create a piece
For i=0 To 4
  piece(2,i)=1
Next
piece(3,4)=1:piece(4,4)=1

; Make a 'cleared' pixel
CreateImage(0, 6, 6, 24)
StartDrawing(ImageOutput(0))
  Box(0,0,6,6,GetSysColor_(#COLOR_BTNFACE))
StopDrawing()

; Make a 'set' pixel
CreateImage(1, 6, 6, 24)
StartDrawing(ImageOutput(1))
  Box(0,0,6,6,#Black)
StopDrawing()

Procedure DrawPiece()
  For j = 0 To 4
    For i = 0 To 4
      StartDrawing(WindowOutput(0))
        Select r
          Case 0
            p = piece_0(i,j)
          Case 1
            p = piece_90(i,j)
          Case 2
            p = piece_180(i,j)
          Case 3
            p = piece_270(i,j)
        EndSelect
        If p
          DrawImage(ImageID(1), 40+7*i,10+7*j)
        Else
          DrawImage(ImageID(0), 40+7*i,10+7*j)
        EndIf
      StopDrawing()
    Next
  Next
EndProcedure  

Procedure RotateLeft90()
  r - 1
  While r < 0: r + 4:Wend
EndProcedure

Procedure RotateRight90()
  r + 1
  While r >= 4: r - 4:Wend
EndProcedure

OpenWindow(0,0,0,120,120,"",#PB_Window_ScreenCentered|#PB_Window_SystemMenu)
ButtonGadget(0,10,75,100,20,"Flip Left 90")
ButtonGadget(1,10,96,100,20,"Flip Right 90")
DrawPiece()

Repeat
  EventID = WaitWindowEvent()
  Select EventID
    Case #PB_Event_Repaint
      DrawPiece()
    Case #PB_Event_Gadget
      Select EventGadget()
        Case 0
          RotateLeft90()
          DrawPiece()
        Case 1
          RotateRight90()
          DrawPiece()
      EndSelect
  EndSelect
Until EventID = #PB_Event_CloseWindow
irc://irc.freenode.org/#purebasic
User avatar
Rook Zimbabwe
Addict
Addict
Posts: 4322
Joined: Tue Jan 02, 2007 8:16 pm
Location: Cypress TX
Contact:

Re: Can you rotate an array?

Post by Rook Zimbabwe »

That is also interesting... but I was going to rotate an array of sections of a gameboard...
Binarily speaking... it takes 10 to Tango!!!

Image
http://www.bluemesapc.com/
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: You can rotate an array {solved 2 ways}

Post by netmaestro »

This is actually fun to play with! Give the following snippet a try as we get a bit more ambitious with the arrays we're rotating, where w<>h anymore. Also, it shows off the new speed of Point/Plot, as the whole image is traversed with Point/Plot twice with each rotation, yet it flips very fast:

Code: Select all

#Left  = 1 
#Right = 2

UseJPEGImageDecoder()
Global Dim tmp.l(0,0)

Procedure RotateImage(img, direction=#Left)
  w=ImageHeight(img):h=ImageWidth(img) ; <--- yes, it's right ;)
  Dim tmp(w,h)
  StartDrawing(ImageOutput(img))
  For j=0 To h-1
    For i=0 To w-1
      If direction = #Right
        tmp(w-i-1,j)= Point(j,i)
      Else
        tmp(i,h-j-1) = Point(j,i)
      EndIf
    Next
  Next
  StopDrawing()
  ResizeImage(img,w,h,#PB_Image_Raw)
  StartDrawing(ImageOutput(img))
  For j=0 To h-1
    For i=0 To w-1
      Plot(i,j,tmp(i,j))
    Next
  Next
  StopDrawing()
EndProcedure

OpenWindow(0,0,0,700,700,"",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
If FileSize(GetTemporaryDirectory()+"redhead.jpg") = -1
  StartDrawing(WindowOutput(0))
    DrawingFont(GetStockObject_(#DEFAULT_GUI_FONT))
    DrawText(250,300,"Downloading image, please wait...",0,GetSysColor_(#COLOR_BTNFACE))
  StopDrawing()
  InitNetwork()
  If Not ReceiveHTTPFile("http://www.lloydsplace.com/redhead.jpg", GetTemporaryDirectory()+"redhead.jpg")
    MessageRequester("oops!", "Can't get the picture... Ending",#MB_ICONERROR)
    End
  EndIf
EndIf

LoadImage(1, GetTemporaryDirectory()+"redhead.jpg")

ImageGadget(0,WindowWidth(0)/2-ImageWidth(1)/2,WindowHeight(0)/2-ImageHeight(1)/2,ImageWidth(1),ImageHeight(1),ImageID(1))
ButtonGadget(1,300,655,100,20,"Flip Left 90")
ButtonGadget(2,300,677,100,20,"Flip Right 90")

Repeat
  EventID = WaitWindowEvent()
  Select EventID
    Case #PB_Event_Gadget
      Select EventGadget()
        Case 1,2
          RotateImage(1, EventGadget())
          ResizeGadget(0, WindowWidth(0)/2-ImageWidth(1)/2,WindowHeight(0)/2-ImageHeight(1)/2,ImageWidth(1),ImageHeight(1))
          SetGadgetState(0, ImageID(1))
      EndSelect
  EndSelect
Until EventID = #PB_Event_CloseWindow
BERESHEIT
Post Reply