Home > Mobile >  Converting a massive into a 3 dimensional bitmap
Converting a massive into a 3 dimensional bitmap

Time:01-10

Introduction

Say we have a massive such that: massive = [[] for each in range(8)]

Each list in massive describes a 8x8 bitmap such that:

And each element in the list describes whether or not a given "square" is black. For example, list = [0, 63] would indicate that only first and last "squares" are black.

The massive defined in the beginning is supposed to describe a 8x8x8 cube, where each list is a "layer" and thus 8 layers form a 3-dimensional cube. Therefore the index of each element in the massive (which indicates to a particular list in the massive) tells us the layer that the particular bitmap is on.

Now, consider the following massive:

massive = [[63, 62, 61, 60, 59, 58, 57, 56, 48, 40, 32, 24, 16, 8, 0, 1, 2, 3, 4, 5, 6, 7, 15, 23, 31, 39, 47, 55], 
           [63, 56, 0, 7], 
           [63, 56, 0, 7], 
           [35, 36, 27, 56, 28, 0, 7, 63], 
           [63, 56, 0, 7, 36, 35, 27, 28], 
           [63, 7, 56, 0], 
           [7, 0, 56, 63], 
           [7, 6, 5, 4, 3, 2, 1, 0, 8, 16, 32, 24, 40, 48, 56, 57, 58, 59, 60, 61, 62, 63, 55, 39, 47, 31, 23, 15]]

Here is a visualisation of all unique bitmaps in this massive:

Bitmap #1

Notice massive[0] and massive[7] - first and last layers

Bitmap #2

Notice massive[3] and massive[4]

Bitmap #3

Notice: massive[1], massive[2], massive[5], massive[6]

Mention that elements in those lists might not be in order, nevertheless its negligible since each element can only state whether that particular position is active and there can be no duplicates in the list. Thus, absence of other numbers (from 0-63) in the list would simply mean that the position is "inactive".

3D Massive representation

This is how the massive would visualize in 3D


Problem

I need this massive to serve as an input (for C based arduino).

This is our massive from the example above in the required format:

const byte bitmap[8][8] = {
    {0xFF, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0xFF},
    {0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81},
    {0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81},
    {0x81, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x81},
    {0x81, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x81},
    {0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81},
    {0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81},
    {0xFF, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0xFF},
};

As you can see the above massive uses hex, for example 0xFF in binary is 0b11111111

Which makes sense: imagine bits coming out of your monitor through z axis forming a full line of 8 squares.

If you break up the byte into bits and imagine those bits forming layers (with parallel bits) then you can see that this massive represents the 3D cube (shown above in itroduction). *Alternatively you could visualize it as whole bytes through z axis - you would end up with the 3D cube from introduction either way.

I need a function that would convert the massive such that:

Input:

       [[63, 62, 61, 60, 59, 58, 57, 56, 48, 40, 32, 24, 16, 8, 0, 1, 2, 3, 4, 5, 6, 7, 15, 23, 31, 39, 47, 55], 
       [63, 56, 0, 7], 
       [63, 56, 0, 7], 
       [35, 36, 27, 56, 28, 0, 7, 63], 
       [63, 56, 0, 7, 36, 35, 27, 28], 
       [63, 7, 56, 0], 
       [7, 0, 56, 63], 
       [7, 6, 5, 4, 3, 2, 1, 0, 8, 16, 32, 24, 40, 48, 56, 57, 58, 59, 60, 61, 62, 63, 55, 39, 47, 31, 23, 15]]

Output:

{
    {0xFF, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0xFF},
    {0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81},
    {0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81},
    {0x81, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x81},
    {0x81, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x81},
    {0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81},
    {0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81},
    {0xFF, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0xFF},
};

Attempt

Below is my attempt:

massive = [[63, 62, 61, 60, 59, 58, 57, 56, 48, 40, 32, 24, 16, 8, 0, 1, 2, 3, 4, 5, 6, 7, 15, 23, 31, 39, 47, 55], 
           [63, 56, 0, 7], 
           [63, 56, 0, 7], 
           [35, 36, 27, 56, 28, 0, 7, 63], 
           [63, 56, 0, 7, 36, 35, 27, 28], 
           [63, 7, 56, 0], 
           [7, 0, 56, 63], 
           [7, 6, 5, 4, 3, 2, 1, 0, 8, 16, 32, 24, 40, 48, 56, 57, 58, 59, 60, 61, 62, 63, 55, 39, 47, 31, 23, 15]]


rows, cols = (8, 8)
arr = [['' for i in range(cols)] for j in range(rows)]
arr[0][0] = ''

for row in arr:
  print(row)


def convert():
  for i in range(0, 64):
    for n in range(0,64):
      for each in massive:
        if i == massive[massive.index(each)][n]:
          arr[massive.index(each)][n] = '1'
        else:
          arr[massive.index(each)][n] = '0'

convert()

for row in arr:
  print(row)

Output:

['', '', '', '', '', '', '', '']
['', '', '', '', '', '', '', '']
['', '', '', '', '', '', '', '']
['', '', '', '', '', '', '', '']
['', '', '', '', '', '', '', '']
['', '', '', '', '', '', '', '']
['', '', '', '', '', '', '', '']
['', '', '', '', '', '', '', '']
Traceback (most recent call last):
  File "main.py", line 28, in <module>
    convert()
  File "main.py", line 23, in convert
    if i == massive[massive.index(each)][n]:
IndexError: list index out of range

I do understand my mistake here, but I am stuck and cannot think of a neat way to get the desired output.

CodePudding user response:

Here's a solution using bitwise operations and then converting integers to hex representation:

massive = [[63, 62, 61, 60, 59, 58, 57, 56, 48, 40, 32, 24, 16, 8, 0, 1, 2, 3, 4, 5, 6, 7, 15, 23, 31, 39, 47, 55],
           [63, 56, 0, 7],
           [63, 56, 0, 7],
           [35, 36, 27, 56, 28, 0, 7, 63],
           [63, 56, 0, 7, 36, 35, 27, 28],
           [63, 7, 56, 0],
           [7, 0, 56, 63],
           [7, 6, 5, 4, 3, 2, 1, 0, 8, 16, 32, 24, 40, 48, 56, 57, 58, 59, 60, 61, 62, 63, 55, 39, 47, 31, 23, 15]]


rows, cols = (8, 8)
arr = [[0 for i in range(cols)] for j in range(rows)]

for layer in massive:
    # Shift each bitmask by one bit
    for x in range(rows):
        for y in range(cols):
            arr[x][y] <<= 1
    # Write current layer to the last bit of arr[x][y]
    for val in layer:
        x, y = val % cols, val // cols
        arr[x][y] |= 1

for row in arr:
    print(', '.join('0x{0:0{1}X}'.format(x, 2) for x in row))

will output

0xFF, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0xFF
0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81
0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81
0x81, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x81
0x81, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x81
0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81
0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81
0xFF, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0xFF

From your question it's unclear what's the direction of the layers though. If lower bits go first in massive then you have to slightly modify one line of the code above and iterate massive in reverse order:

...
for layer in massive[::-1]:
...

PS: I suggest you use 4 spaces per indentation level instead of 2 (see PEP8 indentation guidline).

CodePudding user response:

Pure python solution

massive = [[63, 62, 61, 60, 59, 58, 57, 56, 48, 40, 32, 24, 16, 8, 0, 1, 2, 3, 4, 5, 6, 7, 15, 23, 31, 39, 47, 55],
           [63, 56, 0, 7],
           [63, 56, 0, 7],
           [35, 36, 27, 56, 28, 0, 7, 63],
           [63, 56, 0, 7, 36, 35, 27, 28],
           [63, 7, 56, 0],
           [7, 0, 56, 63],
           [7, 6, 5, 4, 3, 2, 1, 0, 8, 16, 32, 24, 40, 48, 56, 57, 58, 59, 60, 61, 62, 63, 55, 39, 47, 31, 23, 15]]


cube = [[[0] * 8 for _ in range(8)] for _ in range(8)]

for i, row in enumerate(massive):
    for cell in row:
        cell_y = cell % 8
        cell_x = cell // 8
        cube[i][cell_x][cell_y] = 1

result = [[''] * 8 for _ in range(8)]
for x in range(8):
    for y in range(8):
        binary = ''
        for z in range(8):
            binary  = str(cube[x][y][z])
        result[x][y] = hex(int(binary, 2))

for row in result:
    print(row)

output

['0xff', '0x81', '0x81', '0x81', '0x81', '0x81', '0x81', '0xff']
['0x81', '0x0', '0x0', '0x0', '0x0', '0x0', '0x0', '0x81']
['0x81', '0x0', '0x0', '0x0', '0x0', '0x0', '0x0', '0x81']
['0x81', '0x0', '0x0', '0x18', '0x18', '0x0', '0x0', '0x81']
['0x81', '0x0', '0x0', '0x18', '0x18', '0x0', '0x0', '0x81']
['0x81', '0x0', '0x0', '0x0', '0x0', '0x0', '0x0', '0x81']
['0x81', '0x0', '0x0', '0x0', '0x0', '0x0', '0x0', '0x81']
['0xff', '0x81', '0x81', '0x81', '0x81', '0x81', '0x81', '0xff']
  • Related