Rotating a 2d matrix.

Hi.
I am doing a Conway's game of life implementations and I am working with four 8x8 LED matrices. I represent each one as an array of bytes. Like this:

// Data for the upper left LED matrix.
byte displayUpLeft[8]={ B00000000,
                        B00000000,
                        B00100000,
                        B00000000,
                        B00000000,
                        B00000000,
                        B00000010,
                        B00000000};

I realize that this is a one dimensional array. I still need to rotate the contents 180 degrees. Storing the contents like this makes it very easy to update the display.
I have not implemented the calculations needed for the generations. I just found out when I tried the displays that this is going to be a problem later on. That is why I am asking here.
For two of the matrices (upper left and lower left) the values get displayed like they are represented but I have to rotate two (upper right and lower right) of the displays 180 degrees.

My question is if there is a simple way to rotate a byte array on an Arduino?

Cheers!

simmisj:
Hi.
I am doing a Conway’s game of life implementations and I am working with four 8x8 LED matrices. I represent each one as an array of bytes. Like this:

// Data for the upper left LED matrix.

byte displayUpLeft[8]={ B00000000,
                       B00000000,
                       B00100000,
                       B00000000,
                       B00000000,
                       B00000000,
                       B00000010,
                       B00000000};




I realize that this is a one dimensional array. I still need to rotate the contents 180 degrees. Storing the contents like this makes it very easy to update the display.
I have not implemented the calculations needed for the generations. I just found out when I tried the displays that this is going to be a problem later on. That is why I am asking here.
For two of the matrices (upper left and lower left) the values get displayed like they are represented but I have to rotate two (upper right and lower right) of the displays 180 degrees.

My question is if there is a simple way to rotate a byte array on an Arduino?

Cheers!

This code will rotate an 8 x 8 array (bitmap) 90 degrees clockwise. Run it twice to do a 180 or 3 times for a 270 (same as 90 counter-clockwise).

char inArray[8];
char outArray[8];

void rotate (void)
{
    int i, j, val;

    for (i = 0; i < 8; i++) {
        outArray[i] = 0;
    }

    //rotate 90* clockwise
    for (i = 0; i < 8; i++) {
        for (j = 0; j < 8; j++) {
            val = ((inArray[i] >> j) & 1); //extract the j-th bit of the i-th element
            outArray[7-j] |= (val << i); //set the newJ-th bit of the newI-th element
        }
    }
}

I use this function to rotate character font bitmaps 90 degrees clockwise to use on a KS-108 style graphic display, but it should work for what you want.

Yes. That seems to work.
But I have just started experimenting with using a 16x16 array to hold the data of the display like this:

// Data for the whole display.
unsigned int wholeDisplay[16]={ 0b1000000011011111,
                                0b1111111100000010,
                                0b0010000011111111,
                                0b1111111100001000,
                                0b0000100011111111,
                                0b1111111100100000,
                                0b0000001011111111,
                                0b1111111110000000,
                                0b0001000111101111,
                                0b1111111101000000,
                                0b0000010011111111,
                                0b1111111100010000,
                                0b0001000011111111,
                                0b1111111100000100,
                                0b0100000011111111,
                                0b1111111100000001};

It is much easier when calculating the generations to have the data in a single array.

Can your algorithm be adapted towards the right side of this array? Run through every row but skip 0-7th element at each row and treat the right side like two 8 by 8 arrays.

This is what I have adapted from your code:

char rotate2 ()
{
    int i, j, val;

    for (i = 0; i < 16; i++) {
        outArray[i] = 0;
    }

    //rotate 90* clockwise
    for (i = 0; i < 8; i++) {
        for (j = 8; j < 16; j++) {
            val = ((wholeDisplay[i] >> j) & 1); //extract the j-th bit of the i-th element
            outArray[7-j] |= (val << i); //set the newJ-th bit of the newI-th element
        }
    }
    //rotate 90* clockwise
    for (i = 8; i < 16; i++) {
        for (j = 8; j < 16; j++) {
            val = ((wholeDisplay[i] >> j) & 1); //extract the j-th bit of the i-th element
            outArray[7-j] |= (val << i); //set the newJ-th bit of the newI-th element
        }
    }
}[\code]

This shows only zeros after I use it on the 16 by 16 array and then print out the new array.

Appreciate the help.

I have managed to rotate the two quarters of the 16 by 16 matrix.
I will post the code here if, by some chance, someone else is looking to do the same.
This code can probably be optimized in some way.
I timed it and it takes about 1 millisecond to execute, more than enough for my purposes.

// This method takes the upper corner of the 16 by 16 
// array and rotates it 180 degrees.
// Takes about 1 millisecond.
// "wholeDisplay" is an array: unsigned int wholeDisplay[16];
// It holds 16 unsigned integers in this form: 0b0101010101010101
void rotateUpperRight180Degrees()
{
  int row,column,i,j,val;
  byte temp1[8];
  byte temp2[8];
  byte temp3[8];
  
  for(row = 0; row < 8; row++)
  {
    temp1[row] = 0;
  }
  for(row = 0; row < 8; row++)
  {
    temp2[row] = 0;
  }
  for(row = 0; row < 8; row++)
  {
    temp3[row] = 0;
  }
  for(int row = 0; row < 8; row++)
  {
    temp1[row] = lowByte(wholeDisplay[row]);
  }
  
  //rotate 90* clockwise
  for (i = 0; i < 8; i++) {
    for (j = 0; j < 8; j++) {
      val = ((temp1[i] >> j) & 1); //extract the j-th bit of the i-th element
      temp2[7-j] |= (val << i); //set the newJ-th bit of the newI-th element
    }
  }

  //rotate 90* clockwise
  for (i = 0; i < 8; i++) {
    for (j = 0; j < 8; j++) {
      val = ((temp2[i] >> j) & 1); //extract the j-th bit of the i-th element
      temp3[7-j] |= (val << i); //set the newJ-th bit of the newI-th element
    }
  }
 
  byte bito;
  for(row = 0; row < 8; row++)
  {
    for(column = 0; column < 8; column++)
    {
      bito = bitRead(temp3[row],column);
      if(bito == 1){
        bitWrite(wholeDisplay[row],column,1);
      }
      else
      {
        bitWrite(wholeDisplay[row],column,0);
      }

    }

  }
}

Thanks Krupski for your 90 degree rotate code.

If someone can see a possible optimization I would love to hear about it.

simmisj:
This code can probably be optimized in some way.
I timed it and it takes about 1 millisecond to execute, more than enough for my purposes.

Thanks Krupski for your 90 degree rotate code.

If someone can see a possible optimization I would love to hear about it.

You are most welcomed. My code isn't optimized in any way, but for what I use it for, it doesn't matter. I take 8x8 or 8x16 bitmap fonts and rotate them once to convert them into KS-108 compatible font bitmaps.

They are only rotated once, then I convert the resulting binary into a header file:

// ibm_8x8.h

#ifndef _IBM_8X8_H
#define _IBM_8X8_H

static const uint8_t ibm_8x8[] PROGMEM = {

    0x08, // width (base + 0)
    0x08, // height (base + 1)
    0x00, // horizontal gap (base + 2)
    0x00, // vertical gap (base + 3)
    0x00, // first char (base + 4)
    0x08, // bytes per char (base + 5)

    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x7e, 0x81, 0x95, 0xb1, 0xb1, 0x95, 0x81, 0x7e,
    0x7e, 0xff, 0xeb, 0xcf, 0xcf, 0xeb, 0xff, 0x7e,
    0x0e, 0x1f, 0x3f, 0x7e, 0x3f, 0x1f, 0x0e, 0x00,

// lots more deleted for clarity

    0x00, 0x1f, 0x1f, 0x01, 0x1f, 0x1e, 0x00, 0x00,
    0x00, 0x19, 0x1d, 0x17, 0x12, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00,
    0x08, 0x00, 0x40, 0x60, 0x74, 0x5c, 0x48, 0x00,
};

#endif

So you see it doesn't matter to me if the code is fast or not, because I only run it once.

Again, glad I could help you.

-- Roger

I’ve seen something like this before:

x = ((x & B10101010) >> 1) | ((x & B01010101) << 1);
x = ((x & B11001100) >> 2) | ((x & B00110011) << 2);
x = ((x & B11110000) >> 4) | ((x & B00001111) << 4);

Odometer, I am not sure where that fits into the method.
Care to elaborate?

My code reverses the bits in the byte stored in the variable “x”.

It’s not my invention; I’ve seen it elsewhere.

It is easy to extend to 16 or 32 bits.