Design Computation
Render as Slideshow | Accordion

Parameterization

Parametric design has been getting a lot of press recently. The technique itself is rather established, however, and architecture is just beginning to develop its own parameterized models and techniques. This module investigates the mechanics of a parametric system, how to develop a set of parameters, and develops a framework around thinking parametrically.

Reading

  1. All
    In Processing, pgs 37-50, Data 1: Variables, Math 1: Arithmetic Functions.
    Excerpt, from The Logic of Architecture, William J. Mitchell. Found here.
  2. For the ambitious
    In Processing, Math 2: Curves, pgs 79-84.

Assignment

See the Parameterization Assignment.

Data

A figure-8 torus, one of the more simple forms of computational geometry. Source code here.

This unit describes what data are and how to manipulate them in Processing. This lecture also begins to cover the mechanisms for creating variable and parameterized geometries in Processing. This includes variables, arrays, math functions, loops, etc.

Outline

  1. What are data? (aka. Yes, the word is plural…)
  2. Basic data “types”
  3. Declaring, initializing, and assigning values to variables
  4. Manipulating variables
  5. Incorporating variables into drawing functions
  6. Moving graphics
  7. Math functions

What are data?

Data are pieces of information stripped of their meaning. The numbers may constitute a data set. By themselves, they have no meaning whatsoever.

But placed into a context, the nature of the numbers changes entirely. When we learn that these are a list of the average daily temperatures in New York City, in Fahrenheit, they become “information.”

Types and Values

In computers, data values are stored in variables, and those values are typed.

TYPE SYMBOL DATA CONTAINED EXAMPLE
integer int positive and negative whole numbers 0,-104,1254302
floating-point number float decimal fractions 3.14159, -1.41285
boolean boolean true or false true
string String (with a capital “S”) a sequence of alpha-numeric characters “Hello World!”
color color a special processing data type that wraps RGBA or HSBA color data under a single variable color red = color(255, 0, 0);

A variable, like in mathematics, is a name or symbol (technically called an “identifier”) that represents some piece of data. But unlike algebra and calculus, which typically use one-letter variables, names of variables in Processing can have many letters, symbols, and even numbers.

All variables in Processing and other similar languages have a type, which specifies what kind of data the variable stores.

Functions as Types and Values

Everything in computation has a type and value. In fact, statements like line() or bezier() have a type and a value as well. Their “type” is “function,” and their values consist of the instructions required to perform their task, like drawing a line.

The key fact to remember is that data, whether numbers, Strings, or functions, have a (1) name, (2) type, and (3) value.

Can we start describing architectural elements and concepts with names, types, and values?

Declaring, Initializing, and Assigning Values

Variables are just buckets of memory into which you put values. Using them requires a 3-step process.

Declaring a Variable

“Declaring” is the procedure of telling Processing what symbol you want to use and what type of data it will represent.

Examples:


int x;
float gravitationalConstant;
String mothersMaidenName; // camelCaseHasHumps

Initializing and Assigning Values

Initializing tells Processing the very first value to store in the variable. Processing needs this so you don’t end up using the “null” value, which stands for “no value”.

Initializing takes the very same format as assigning values anywhere in a program.


x = 10;
gravitationalConstant = 0.000000000066742;
mothersMaidenName = "Smith";

The variable always appears on the left of the single equal sign, and the value appears on the right. Like any other statement in Processing, the semicolon ends the command.

Combining

Declaring and initializing can be done in the same statement:


int x = 10;
float gravitationalConstant = 0.000000000066742;
String mothersMaidenName = "Smith";

// We can display the values of variables in the console when we need to see them.
println( x );
println( gravitationalConstant );
println( mothersMaidenName );

Manipulating Values

Variables are the core mechanism of manipulating data, both the values and types of data.

The number 5 by itself is immutable – it always equals 5. But when used as a value assigned to a variable, the value of the variable can be changed.

Like mathematical variables, in Processing’s variables, numeric values can be added, multiplied, subtracted, divided, incremented, etc. This usually takes the form of a variable being assigned a new value based on numbers, other variables, and functions that perform mathematical operations( sine, cosine, etc.).

Examples:


float x = 10;
float y = 20;
float z;
z = x + y; // z is 30.
z = y/5 + x*1.2; // z is 16;
x = x - 1; // x is 9, decremented by 1.
Operation Operator Example
addition + x = x + y;
subtraction - z = y – 10;
multiplication * x = y * z;
division / z = y – x;
modulo (remainder after division) % z = y%x;

Order of Operations

Processing follows the same order of operations from algebra and arithmetic. Using parentheses makes the desired order explicit.


z = x * (y + 10) + 5 * (x * 13 + 1);

Variables and Drawing Functions

Wherever you use data, you can put a variable in its place.

Copy and paste this code into Processing and press play. Then close the sketch window, come back to Processing and change x and y to change the composition.

Change orangeR, orangeG, and orangeB to change the colors. Try changing the equations inside the fill(…) statement.


size(300,150);
background(255);

int x = 67;
int y = 81;

int orangeR = 255;
int orangeG = 153;
int orangeB = 50;

stroke( orangeR, orangeG, orangeB );

// You can do math in functions, too. 
fill( orangeR/2, orangeG/2, orangeB/2 ); 

rect(95,20,x,y);
rect(205,20,x-100,y);
rect(95,130,x,y-100);
rect(205,130,x-100,y-100);

Moving Graphics

Processing provides simple ways to implement dynamic and interactive form without sacrificing power or flexibility.

Processing, like other programming languages, has a fundamental way to organize programs. This is not only for Processing’s benefit – this organizational method helps you to organize your thoughts and design process.

The most basic structure is based on Processing’s commitment to interactive graphics.

Like in motion pictures, movement in Processing occurs by drawing many frames each second. Once you associate graphics with variables, you write code to change the variables every time a new frame is drawn. draw() is the place where you put all that has to be drawn and executed in a single frame.

Special Processing Variables

Processing has several reserved names that you can’t use as variable names but that give us access to special values.

height
An integer containing the height of the sketch in pixels.

width
An integer containing the width of the sketch in pixels.

mouseX
An integer containing the x-coordinate of the mouse cursor.

mouseY
An integer containing the y-coordinate of the mouse cursor.

frameCount
A positive integer containing the number of the frame being drawn, starting with 1, incremented every time Processing “calls” draw().

The code below uses one of these.


int x;

void setup(){
  // Set the size of the sketch.
  size(600,300);

  // Initialize x.
  x=0;

  // Set the stroke color to bright blue.
  stroke(0,0,255);
}

void draw(){ 
  // Clear the sketch window with white.
  background(255,255,255);

  // Draw a vertical line from the top
  // of the sketch window to the bottom.
  line(x,0,x,height);

  // Increment x so that in the next frame
  // the line is drawn one pixel to the right.
  // This takes the value of x, adds 1 to it, then
  // assigns the value to x again.
  x = x + 1;
} 

Math Functions

Just a moving bezier curve, using trig functions to create the motion. Source code for moving bezier here.. Try to modify the code to move the anchor points as well. Use the Processing Reference if you need it.

Processing has a thorough library of standard mathematical functions available in most any programming language.

These functions are different from the drawing functions you have seen before in that they are said to “return a value.” That is, we can place these functions to the right of an equal sign, and when Processing calculates the value, it assigns that value to the left of the equal sign.

Trigonometric Functions


float x = cos( PI/3 ); // cosine function
float y = sin( PI/3 ); // sine function
float z = tan( PI/3 ); // tangent function

Inverse trig functions:


float theta = acos( 0.1 );
float phi = asin( 0.1 );

Exponential and logarithmic functions:


float x = pow( t, 3 );  // t cubed.
float x = exp( t );     // e to the power of t.
float x = sq( t );      // t squared.
float x = sqrt( z );    // Square root of z.

Random number functions:


// Pseudo-random decimal number between 0 and 5.
float r = random( 0, 5 );

// Random number from the Perlin noise function.
float n = noise( millis()*0.0005, t );

More… See the Processing reference under Calculation, Random, and Trigonometry.

Constants

PI
Equal to 3.1415927

TWO_PI, HALF_PI, QUARTER_PI
You can probably guess.

Parameters

Parametric Design is getting a lot of attention these days, but in the computational world, every statement is already “parameterized.” Since functions have arguments, and we can refer to data with names using variables, then our sketches can be easily parameterized, and we’re automatically in the realm of “parametric design.”

This coffee table can be parameterized by length, width, height, and number of legs… OR we can use aspect ratio, table area, thickness, and number legs.

State

The “state” of a sketch consists of all the values of all the variables we’re using at any one time. In Processing, this doesn’t really include functions, but it does include all the values of all the variables that we’re depending on at any given time.

Computation proceeds by assessing the state of a system, then modifying that state depending on various calculations or conditions that we set. These modifications can happen automatically (as with an algorithm), or manually (with a user interface).

In the former case, we’re deferring our judgement to the system. In the latter case, we’re relying on the computer to present the information to us in a meaningful way, so we can make meaningful decisions ourselves.

Animation and State

Animating in Processing is easy. Since Processing already gives us a draw() function that is repeatedly called several times a second, we can naturally make animations by giving Processing a set of instructions on what to draw().

The trick is drawing slightly different geometry with each frame.

Pseudocode for Animation

Pseudocode is our technique for writing instruction in English that are easily translatable into computational language. This involves being very specific about the data we are talking about.

  1. Declare variables (tell Processing what names we want to use and what types they represent)
  2. Initialize values (tell Processing where to start)
  3. Draw something with the variables.
  4. Change the value (state) of the variables.
  5. Repeat steps 3-5.

Procedures like this one are just the start of learning to think in a computational way. Technically, this is an imperative paradigm, where a program has a state (consisting of all the values of the variables we have declared), that we change over time.