Design Computation

Arrays

  1. Arrays
    1. Taming Multiplicity
    2. Names as mechanisms of control
    3. Example of singularity
    4. Example of multiplicity
    5. Basics of arrays

Taming Multiplicity

Changing single variables works to make geometry dynamic, but what about a hundred geometries, or a thousand?

Multiplicity always been easy on the mind and hard on the hand.

In a way, computer science and computation are forms of idealized engineering. You can make thousands of the same object, all differentiated in some way, with ease. The problem of production has been solved.

This is great as long as you don’t need a physical realization of that object, but in architecture, that is ultimately our primary concern. A bridge to the physical world still being developed by various industries (3D printers, CNC machines, etc.).

Names as a Mechanism of Control

We’re all special to our parents. But to the government, we’re all just numbers.

The cost of multiplicity is in referencing the objects to control.

Variables are the mechanism for control in computation. We choose a name for a value, associate that value with a geometry, object, or behavior, and we can consequently control that geometry, object, or behavior.

Control

What do you call the one circled in red?

The act of naming is a referencing mechanism in the real world. By naming a pet, we can establish a means of communication, and ultimately one means of control. We name things that are truly singular or unique, like people, pets, ships, countries, etc.

We have been naming individual variables so far, but that only works to a point. But if we need a thousand objects, we don’t necessarily want thousands of variables, each with a different name.

Other Means of Reference

However much we may wish license plates were about individuality, they are fundamentally a means of mass control.

But naming isn’t the only way to reference things. What is the name of your second dining room chair? It doesn’t have a name, but you don’t have a problem referencing it.

Next we will learn how to apply the productive power of the machine to the production of names.

Example of Singularity

A single circle moving in a sinuisoidal fashion.

Creating one object and making it move is what we have been implementing so far.


float startX, startY;
float x, y;
float rot, amp, speed, radius;
color c;  // "color" is a Processing data type.
float t;

void setup() {
  size(700, 400);
  smooth();

  radius = 20 + random(20);
  startX = random(width);
  startY = random(height);
  c = color(random(255), random(255), 
               random(255), 150); // line break!
  rot = random(TWO_PI);
  amp = 20 + random(100);
  speed = random(1, 10);
  t = 0;
  
  noStroke();
}

void draw() {
  background(255);

  fill(c);
  x = t*amp*cos(rot) + startX;
  y = t*amp*sin(rot) + startY;
  ellipse(x, y, radius, radius);
  
  t = sin( radians( speed*frameCount ) );
}

Example of Multiplicity

500 sinuisoidal circles moving at the same time.

If you want 500 moving circles, it’s best not to declare 500 * 10 or 5000 variables. So we use a data structure called “arrays” to help us.

The next few pages are on how arrays and loops work together to provide our first means of multiplicity and mass control.


int numBalls = 500;

float[] startX = new float[numBalls];
float[] startY = new float[numBalls];
float[] x = new float[numBalls];
float[] y = new float[numBalls];
float[] rot = new float[numBalls];
float[] amp = new float[numBalls];
float[] speed = new float[numBalls];
float[] radius = new float[numBalls];
color[] c = new color[numBalls];
float[] t = new float[numBalls];

void setup() {
  size(700, 400);
  smooth();

  for( int i=0; i < numBalls; i++ ){
    radius[i] = 20 + random(20);
    startX[i] = random(width);
    startY[i] = random(height);
    c[i] = color(random(255), random(255), 
       random(255), 150);
    rot[i] = random(TWO_PI);
    amp[i] = 20 + random(100);
    speed[i] = random(1, 10);
    t[i] = 0;
  }
  
  noStroke();
}

void draw() {
  background(255);

  for( int i=0; i < numBalls; i++ ){
    fill( c[i] );
    x[i] = t[i]*amp[i]*cos(rot[i]) + startX[i];
    y[i] = t[i]*amp[i]*sin(rot[i]) + startY[i];
    ellipse(x[i], y[i], radius[i], radius[i]);
    
    t[i] = sin( radians( speed[i]*frameCount ) );
  }
  
}

Basics of Arrays

Arrays are a way of taking a lot of variables and referring to them with a single name.

Arrays names here are an indexed reference mechanism.

The idea is simple:

  1. pick a name for this this “array” or collection of values, then
  2. reference each item by an integer, called an “index.”

Each bucket or place for data in an array is called an “element”. An array is then made of multiple elements of a particular data type. We can have an array of integers, floats (floating-point numbers), Strings, colors, etc. We cannot mix data types in an array.

Declaration Syntax

The brackets below tell us we’re working with an array.


TYPE[] NAME = new TYPE[ NUMBER_OF_ELEMENTS ];

Example:

int[] counts = new int[ 50 ];

This example produces an array of 50 integers. The number of elements (in this case, 50) must always be a positive integer.

Notice the use of the keyword “new”, that tells Processing to produce a new array. This keyword isn’t necessary for regular variables. It tells Processing to set aside a new block of memory that is large enough to contain exactly 50 integers.

Assigning and Reference Syntax


NAME[INDEX] = VALUE;
OTHER_VARIABLE = ARRAY_NAME[INDEX];

Example:


counts[3] = 25;
int x = counts[3];

Notes

x[i] is read as “ex sub eye”. Indices begin at zero, which means the last index is always equal to number of elements – 1.

ARRAY_NAME.length is equal to the “length” of the array, which is the number of elements.


int[] counts = new int[ 10 ];
counts[3] = 25;        // Initialize the value.
println( counts[3] );  // Output to the console.
int x = counts[3];     // Copy the value into
                       // another variable.

counts[3] = 12;        // Assign a new value.
println( x );          // x is still 25.

// Print the number of elements in the array.
println( counts.length ); // equals 10

// You can use a variable to put in place of the
// index. This allows us to automate the process
// of accessing array elements.
int i = 7;
counts[i] = 15;
println( counts[i] );  // Prints 15.