Rotating an Array

Previous topic - Next topic

spicypixel

I am looking at rotating the contents of a squarely dimensioned array. So for example if I had the contents shown (as below) for a 4x4 array, how can I go about writing a function to rotate the array clockwise and anti-clockwise. Thoughts?

Code (glbasic) Select

normal
1000
1000
0000
0001

anti-clockwise
0001
0000
0000
1100

or clockwise
0011
0000
0000
1000


I kinda have the code to display my array in rotated positions (untested but think it's right), but can't get my head around taking my existing array and affecting the contents rather than just how it's depicted lol.

Code (glbasic) Select

FOR Y = 0 TO 7
    FOR X = 0 TO 7
        DRAW [X][Y].FRAME

FOR  X = 0 TO 7
    FOR Y = 7 TO 0
        DRAW[X][Y].FRAME

etc....


but as I say can't get my head around the rotating of the actual array values. I do realise I need a temporary store but even so my head is imploding, HELP! :D
http://www.spicypixel.net | http://www.facebook.com/SpicyPixel.NET

Comps Owned - ZX.81, ZX.48K, ZX.128K+2, Vic20, C64, Atari-ST, A500.600.1200, PC, Apple Mini-Mac.

Moru

#1
You have two choices:

1. Rotate the array by swapping the content around with a temp variable. (takes long to rotate but when the array is rotated, there is no slowdown for accessing any more)

2. Create interface that just swaps the coordinates for accessing the array invisibly. (takes no time to rotate but slows each access a tiny bit)

I'm too rusty in GLBasic at the moment to write it but I'm sure this is possible to do in a TYPE :-)

#1 is good if you plan on only rotating once
#2 is good if you plan to rotate/flip/mirror the array now and then.

spicypixel

Thanks Moru, I'm looking at rotating the array lots, but will only be rotating an array of 64 values'ish 8x8 array most likely so I was thinking this....

[pseudo-code as-in untested.]
Code (glbasic) Select

// Anti-Clockwise
FOR Y = 0 TO 7
    FOR X = 0 TO 7
        COPY[Y][7-X] = SOURCE[X][Y]
    NEXT
NEXT

// Clockwise
FOR Y = 0 TO 7
    FOR X = 0 TO 7
        COPY[7-Y][X] = SOURCE[X][Y]
    NEXT
NEXT

// Copy Back to Array
FOR Y = 0 TO 7
    FOR X = 0 TO 7
        SOURCE[X][Y] = COPY[X][Y]
    NEXT
NEXT


Reckon this will be quick enough??? I'm thinking yes, but wanted to post incase anyone else wanted to see a solution or to add their input. Could be handy for a Tetris game although I'm presuming pre-rotated arrays of shapes would be used for that.
http://www.spicypixel.net | http://www.facebook.com/SpicyPixel.NET

Comps Owned - ZX.81, ZX.48K, ZX.128K+2, Vic20, C64, Atari-ST, A500.600.1200, PC, Apple Mini-Mac.

Moru

That is certainly fast enough.

To rotate an array in place, do this:

+90 degrees:
1. transpose
2. reverse every row

-90 degrees:
1. transpose
2. reverse every col

+180 degrees:
1. Reverse rows
2. Reverse cols


With in-place I mean you do
Code (glbasic) Select
temp = array[x][y]
array[x][y] = array[y][x]
array[y][x] = temp


Transpose is diagonal mirror from top left to bottom right.
Reverse is a mirror vertical or horizontal.

This means you don't need a copy of the whole array but since you are working with such a small array that doesn't matter really.