#### Howdy, Stranger!

We are about to switch to a new forum software. Until then we have removed the registration on this forum.

# Visualizing three dimensional arrays

edited September 2017

To a computer, arrays don't have any kind of a shape or dimension, they are just blocks of space where a value can be stored and retrieved. But most humans don't really think like this, it's usually easier to understand something if we can SEE it.

So, how do we "SEE" arrays?

Well, a regular, one dimensional array can be imagined like a numbered list of values stacked on top of eachother, and a two dimensional array might be seen as a chess board with numbered rows and numbered squares in each row...... but how do you imagine a three dimensional array? How about a four dimensional one?

This is a sketch I made to show how three dimensional arrays can be visualized in the real world. The idea is that there is a cube (which represents a three dimensional array) that has x layers, inside each layer are x rows, and in each row there are x values. In this particular sketch, I used a cube with four layers that have four rows and four values in those rows, so in all there are 64 unique values.

In this sketch, you use the number keys to choose a layer, row, or value, and you use BACKSPACE to go back a level:

## Code:

``````// A three dimensional array (The cube)
// The fist "[]" represents the layer, while the second "[]" is the row in that layer and the
// third is the value in that row
String[][][] dim = {

{{"0a", "0b", "0c", "0d"},
{"0e", "0f", "0g", "0h"}, // Layer 0
{"0i", "0j", "0k", "0L"},
{"0m", "0n", "0o", "0p"}},

{{"1a", "1b", "1c", "1d"},
{"1e", "1f", "1g", "1h"}, // Layer 1
{"1i", "1j", "1k", "1L"},
{"1m", "1n", "1o", "1p"}},

{{"2a", "2b", "2c", "2d"},
{"2e", "2f", "2g", "2h"}, // Layer 2
{"2i", "2j", "2k", "2L"},
{"2m", "2n", "2o", "2p"}},

{{"3a", "3b", "3c", "3d"},
{"3e", "3f", "3g", "3h"}, // Layer 3
{"3i", "3j", "3k", "3L"},
{"3m", "3n", "3o", "3p"}}

};

int lay = -1; // The layer of the cube (cube 0)
int row = -1; // The row in that layer
int val = -1; // The value in that row

boolean show_startScreen = true;

void setup() {
size(500, 500);
rectMode(CENTER);
textAlign(CENTER, CENTER);
stroke(255);
textSize(30);
noFill();
noLoop(); // I don't need the program to run more than once unless a key is pressed
//and something is changed (so redraw will be run in "void keyPressed()")
}

void draw() {
background(0);

if (show_startScreen) {   //if the start screen is still being shown, draw it!
text("Multidimensional Array\nVisualization Tool", 250, 100);
rect(250, 255, 350, 50);
text("Press any key to begin", 250, 250);
textSize(20);
text("Cyber_Agent\n:)", 250, 400); //The totally awesome guy who made it
textSize(30);
} else {
if (lay == -1) {  // if a layer has not been chosen
text("Cube 0:", 250, 30);
text("Choose a layer", 250, 460);
rect(175, 175, 200, 200);
text("0", 250, 95);
rect(225, 225, 200, 200);
text("1", 300, 145);
rect(275, 275, 200, 200);
text("2", 350, 195);
rect(325, 325, 200, 200);
text("3", 400, 245);
} else if (row == -1) {  // if a row has not been chosen
rect(250, 250, 400, 400);
text("Layer " + lay + ":", 250, 20);
text("Choose a row", 250, 475);
rect(250, 105, 350, 50);
text("0", 100, 100);
rect(250, 200, 350, 50);
text("1", 100, 195);
rect(250, 300, 350, 50);
text("2", 100, 295);
rect(250, 400, 350, 50);
text("3", 100, 395);
} else if (val == -1) {  // if a value has not been chosen
text("Row " + row + ":", 250, 100);
text("Choose a value", 250, 400);
rect(100, 250, 100, 100);
text("0", 100, 250);
rect(200, 250, 100, 100);
text("1", 200, 250);
rect(300, 250, 100, 100);
text("2", 300, 250);
rect(400, 250, 100, 100);
text("3", 400, 250);
} else {  //show a value
text("Value " + val + ":", 250, 100);
rect(250, 250, 100, 100);
text(dim[lay][row][val], 250, 250);
text("[" + lay + "]" + "[" + row + "]" + "[" + val + "]", 250, 400);  //show the actual location/ address of your chosen value
}
}
}

void keyPressed() {
if (!show_startScreen) {  // If the start screen has been passed
if (keyCode == BACKSPACE) {  // go back a level
if (val != -1) {
val = -1;
} else if (row != -1) {
row = -1;
} else if (lay != -1) {
lay = -1;
}
} else if (key == '0' || key == '1'|| key == '2'|| key == '3') { //make sure that the pressed key was a 0, 1, 2, or 3
if (lay == -1) { // if layer has not been set, set it!
lay = Integer.parseInt(str(key)); //covert the pressed key to an int, and store it
} else if (row == -1) {  // if layer has not been set, set it!
row = Integer.parseInt(str(key)); //covert the pressed key to an int, and store it
} else if (val == -1) {  // if layer has not been set, set it!
val = Integer.parseInt(str(key)); //covert the pressed key to an int, and store it
}
}
} else {
show_startScreen = false;
}
key = 'q'; // This gets rid of some loopholes
redraw(); // Run the code in "draw()" once more
}
``````

end of code

Honestly, this is so random and I don't think that this has any practical uses, but I am going to keep it handy just in case I suddenly forget how to wrap my head around three dimensional arrays.

P.S. A four dimensional array could be imagined as x cubes, each with x layers, and x rows in those layers, and x values in those rows. Perhaps a five dimensional array would be x groups of x cubes with x layers with x rows with x values. And so on....

Tagged:

• Man, the code looked fine when I pasted it in, but it got all compressed after I posted it..... anyone know how I can fix that?

• Edit post, highlight code, press ctrl-o

• Oh! Thanks so much!

• edited September 2017
``````void setup() {
String a[][][][];
a = new String[][][][]{{{
{"This"},
{"is", "a"},
{"four", "dimensional", "array"}},
{{",even", "though"},
{"it's", "not"},
{"a"}}},
{{{"cube."}}}};
for (int w=0; w   <a.length; w++) {
for (int z=0; z<a[w].length; z++) {
for (int y=0; y<a[w][z].length; y++) {
for (int x=0; x<a[w][z][y].length; x++) {
print( a[w][z][y][x] + " ");
}
}
}
}
}
``````
• The fourth component can also be time.

E.g. the different moves in a 3D chess cube

• here is a 3D cube with letters

``````// States:
// consts / numbers must be unique
final int HELP   = 0; // help
final int GAME   = 1; // standard: selecting Cells with the mouse
int state = GAME;   // current

// Cells
CellClass[][][] Cells = new CellClass;

// rotation and Scale
float currentAngle1;
float zoomScale1=1.7;
boolean rotateFlag=true;

// Misc
PFont font1;

// --------------------------------------------------------
// main funcs

void setup() {
size(1400, 800, P3D);
background(111);

defineCells();

font1 = createFont("Arial", 32);
textFont(font1);
textAlign(CENTER, CENTER);

currentAngle1=0;
} // func ---

void draw() {
switch (state) {

case HELP:
// to do
background(111);
text("Help\n\nThis is the help..."
+"\n\npress any key.",
32, 344);
break;

case GAME:
playTheGame();
break;
} // switch
} // func draw()

// ----------------------------------------------------

void playTheGame() {

background(111);
lights();

camera(0, 0, 510,
0, 0, 0,
0, 1, 0);

pushMatrix();
scale (zoomScale1);

showTheGrid();

popMatrix();

strokeWeight(1);

//stroke(255, 0, 0);
//line (0, -100, 0,
//  0, height+100, 0);
//line (width/2, -100,
//  width/2, height+100 );

// rotation
if (keyPressed&&key=='r')
currentAngle1++;
if (keyPressed&&key=='l')
currentAngle1--;

if (rotateFlag)
currentAngle1++;

// 2D part / HUD  ---------------------------------------------
camera();
//  hint(DISABLE_DEPTH_TEST);
noLights();
// textMode(MODEL);
// textMode(SHAPE);
textSize(14);
fill(0);
text("Use r and l to rotate. Mouse wheel to zoom. Space to stop/start rotation. "
+"\n",
310, 20 );

//stroke(255, 0, 0);
//line (width/2, -100,
//  width/2, height+100 );
}

// ------------------------------------------------------------------

void showTheGrid() {
// show Cells : all
for (int i = 0; i < Cells.length; i++) {
for (int j = 0; j < Cells[i].length; j++) {
for (int k = 0; k < Cells[i][j].length; k++) {
//
Cells[i][ j][k].show();
//
}// for
}// for
}// for
} // func

// ----------------------------------------------------
// input funcs

void keyPressed () {

switch (state) {

case HELP :
// reset
state = GAME;
break;

case GAME :
if (key!=CODED) {

// not CODED -----------------------------------

if (key=='x'||key=='X') {
// reset
defineCells();
} else if (key == 'h' ) {
//
// F1
state = HELP;
println("1");
} else if (key == ' ' ) {
//
// F1
rotateFlag = !rotateFlag;
println("1");
}
} else {

// if (key==CODED) { --------------------------------------------
//
switch (keyCode) {

case java.awt.event.KeyEvent.VK_PAGE_UP :
zoomScale1-=.01;
break;

case java.awt.event.KeyEvent.VK_PAGE_DOWN :
zoomScale1+=.01;
break;

default :
// do nothing
break;
} // switch
} // else
break;

//
} // switch (state) {
//
} // func

// ----------------------------------------------------
// misc funcs

void defineCells() {
// define Cells

float widthOverAll = 6*(height/10);
float posX = (width/2) - (widthOverAll/2);
println (posX);

for (int i = 0; i < Cells.length; i++) {
for (int j = 0; j < Cells[i].length; j++) {
for (int k = 0; k < Cells[i][j].length; k++) {

// prepare values
color currentCol = color (111);
String randomWord="";
randomWord+=""+char(int(random(65, 95)));
randomWord+=""+char(int(random(65, 95)));
randomWord+=""+char(int(random(65, 95)));
randomWord+=""+char(int(random(65, 95)));

// create a Cell
Cells[i][ j][k] = new CellClass(
-230 + i*(height/10),
-185 + j*(height/10),
-230 + k*(height/10),
currentCol,
randomWord);
}
}
} // for
} // func

// ----------------------------------------

void mousePressed() {

switch (state) {

case HELP :
// go back
state = GAME;
break;

case GAME :
//
break;
} // switch
}//func

void mouseWheel(MouseEvent event) {

//This method controls zoomScale1 variable

if (event.getCount()==-1)
zoomScale1 += 0.1;
else if (event.getCount()==1) {
if (zoomScale1>=.1)
zoomScale1 -= 0.1;
}

// check lower boundary
if (zoomScale1<.1)
zoomScale1 = .1;
}

// ========================================================
// classes

class CellClass {

// this class represents one Box / Cell

float x;
float y;
float z;

float scX, scY;

color col;
color defaultCol;

String textCell="";

// constr
CellClass(float x_, float y_, float z_,
color col_,
String word_) {
x = x_;
y = y_;
z = z_;
col = col_;
defaultCol = col;

textCell=word_;
} // constr

void show() {
pushMatrix();

translate(x, y, z);
//rotateY ( currentAngle1 );

noFill();
stroke(255);
rect(-33, -16, 66, 32);

fill(0, 0, 255);//blue

noStroke();
// Cell(7);

text(textCell, 0, 0);
col = defaultCol;

// the Cell / box was drawn at (0, 0, 0), store that location
scX = screenX(0, 0, 0);
scY = screenY(0, 0, 0);

popMatrix();
} // method
} // class
// ==============================================================
``````