## 05 Multiplicity

Slideshow Version

# Multiplicity

We want to be able to control not just single things at a time, but many things.

The power of computational machines is most directly seen when we ask the machine to execute small pieces of code repeatedly.

If we can parameterize the repetition and built rules about how to change the process slightly with each iteration, we can begin to produce complexity from very simple rules. ## Repetition and Variation

A computational system is best at replicating and producing patterns of processes.

Once we can codify a process into a simple set of executable instructions, we can begin to manipulate a set of parameters in an iterative way.

Slight changes in how we handle these instructions, in both the values of our data and the rules that govern them, can result in a richness of complexity that stems from a simple change in a simple repeated process. ## Parameterized…

So far, we have parameterized form a very particular way. We use variables to hold numeric values that are used to create geometries.

We have rules that govern the appropriate values for these “parameters,” so called because of how they are used in our sketches.

## Parameterized Multiplicity

The next stage is to see the rules and parameters that can govern the handling of many things. How do we parameterize multiplicity so we can control the number of things we are modeling, their behaviors, and even the rules that create, destroy, and changes those things?

## Today, in technical detail…

1. We are going to set up TONS of variables.
2. We will automate how we set their values.
3. We start using routines to update them.

1. All
“Control 2: Repetition”, pgs 61-68 and “Shape 2: Vertices” pgs 69-77
“Data 4: Arrays”, pgs 301-313
2. Supplementary
For the assignment, in Processing, read:
“Image 1: Display, Tint”, pgs 95-99
“Typography 1: Display”, pgs 111-116
“Input 1: Mouse I”, pgs 205-215
“Input 2: Keyboard”, pgs 223-227
“Input 3: Events”, pgs 229-236

## Assignment

Find here the multiplicity assignment

## 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 has 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;  //starting point for ellipse
float x, y;  // current position for ellipse
color c;  // "color" is a Processing data type.
float t; // a variable to track time.

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

radius = 20 + random(20);  // set a random ball radius between 20 and 40 pixels
startX = random(width);    // set a random ball starting positions
startY = random(height);
c = color(random(255), random(255),
random(255), 150); // line break!
rot = random(TWO_PI);  //set a random angle of oscillation between 0 and 2 Rads
amp = 20 + random(100); // sets a multiplier to control oscillation width
speed = random(1, 10); // set a multiplier to adjust oscillation speed
t = 0;

noStroke();
}

void draw() {
background(255); // redraws background every frame

fill(c);
x = t*amp*cos(rot) + startX;  // increment the ellipse x position
y = t*amp*sin(rot) + startY;  // increment the ellipse y position

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]; // create an array
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];
color[] c = new color[numBalls];
float[] t = new float[numBalls];

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

for( int i=0; i < numBalls; i++ ){
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];

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.

#### Remember “Declaring, Initializing, and Assigning Values”?

A few sessions ago, we set up parameters a specific way…

Declaring:

``````
int x;
``````

Initializing:

``````
x = 12;
``````

Combining (Declaring and initializing in the same statement):

``````
int x = 12;
``````

… in the case of this single integer, the computer already knows how much memory to set aside to hold this data. With an array, we’ll have to tell it how much space to set aside…

#### Array Declaration Syntax

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

``````
TYPE[] ARRAY_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 = 25;
int x = counts;
``````

#### Combining Syntax

``````
TYPE[] ARRAY_NAME = {VALUE1, VALUE2, VALUE3...};
``````

Example:

``````
int[] numbers = { 90, 150, 30 };
int a = numbers + numbers; // Sets variable a to 240
int b = numbers + numbers; // Sets variable b to 180
``````

#### Use an Array(index) Just Like a Variable

``````
int[] e = { 20, 40, 60, 80 };
int[] r = { 10, 20, 30, 40 };
ellipse( e, e, e, e );
rect   ( r, r, r, r );
``````

…or…

``````
int[] e = { 20, 40, 60, 80, 100, 120 };
ellipse( e, e, e, e );
ellipse( e, e, e, e );
``````

#### 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 = 25;        // Initialize the value.
println( counts );  // Output to the console.
int x = counts;     // Copy the value into
// another variable.

counts = 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.
``````

## Loops

1. Loops
1. “For” loops
2. More complex moving graphics
3. “For” loops and arrays
2. Loops and Arrays are Powerful
3. More On Arrays
1. Parallel Arrays
2. Multi-Dimensional Arrays

### “For” Loops A “for-loop” is a counting mechanism. It executes and a series of steps, then changes the value of the iterating variable. It continues to execute the code block repeatedly until the condition in the loop equals false.

Loops are mechanisms to leverage the power of automation and multiplicity.

“For-loops” are a great way to repeat a set of commands many times and get a variable to change. If you want to draw ten squares, for instance, you can either write ten rect() commands, or write a single for-loop to draw all ten for you.
HOW THEY WORK

Try this:

``````
size( 500,200 );
for( int i=0; i < 10; i++ ){
rect( i*30, 10, 20, 20 );
}
``````

Here’s an interpretation of what the for-loop statement means:

``````
for( int i=0; i < 10; i++ ){
// CODE HERE
}
``````

1) Define a variable i, make it store an integer, start at 0.

2) Continue the loop while the value of “i” is less than 10. (This is known a “condition”, which we haven’t discussed in detail yet. For now, just use this format, and place to the right of the less-than sign a maximum value you don’t want the variable to exceed.)

3) Do the stuff between the braces each loop: { … }

4) At the end of each loop, increase “i” by 1.

#### Notes

You can use any variable name, not only “i”, but it is the most common variable used with arrays, which we will experiment with on the next page.

This is a mechanism that falls under “control flow,” which refers to the means that a programming language provides to control how the more salient statements are executed. A “for-loop” really doesn’t do anything substantial by itself – it’s really just a way of executing a pre-defined set of statements repetitively.

A previous example, simplified by a for-loop.

``````
void setup(){
size(700, 350);
}

void draw(){
background(255);
stroke( 0, 0, 0, 100 );

for( int i=0; i < 90; i++ ){
bezier( i*10, 50, 100, 100, 200, 300, 300+i, 300 );
}
}
``````

Try counting by a different number:

``````
for( float t=0.0; t < TWO_PI; t+=0.1 ){
line( 200, 100, 200 + 100*cos(t), 100 + 100*sin(t) );
}
``````

### While Loops

“While loops” are capable of a similar type of iteration as for-loops.

In this case, the conditions

``````
int i=0;
while(i<80) {
line(30, i, 80, i);
i = i + 5;
}
``````

### Infinite Loops

When will the following code reach the end of the while-loop?

``````
int count = 0;
int t=0;
while (count < 100) {
println("count: " + count);
println("t: " + t);
count = count * 1;     // OOPS, does not change count
t++;
}
``````

… run it and find out. We can wait…

### Loops and Arrays Are Powerful With loops added, now we have a better idea of what’s going on here when we look at the code.

This example is called “looping over an array”. With one loop, you can fill/update/whatever any array of any size.

``````
int counts[] = new int;

for( int i=0; i < counts.length; i++ ) {
counts[i] = i * i;
}
``````

This example results in an array that contains { 0, 1, 4, 9, 16, 25 }. There is no “36” here, since we start counting at 0 and have 6 elements, we get to 5 and that’s it.

### Parallel Arrays

One way of producing multiplicity is to utilize “parallel arrays.” This data structure uses several arrays with different names but identical lengths to store related information by index.

Below, all the information about each ball is spread over 10 arrays. If we want information about ball #41, we can ask each array using index = 41.

``````
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];
color[] c = new color[numBalls];
float[] t = new float[numBalls];

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

for( int i=0; i < numBalls; i++ ){
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];