IFD:PhysicalComp2011/code

From Medien Wiki

This site belongs to the Physical Computing 2011 class.

24.10.2011 Processing sketches

I Simple shapes

/* SIMPLE SHAPES
 *
 * Get familiar with the coordinate system and the way
 * shapes are beeing drawn onto the screen.
 *
 * Frederic Gmeiner 2011
 */

// define the width and height of the display window:
// 400 x 400 px
size(400,400);

// draw the following shapes without outlines:
noStroke();
//set the fill color of the following shapes to pure red:
fill(255,0,0);
// draw a rectangle:
rect(230,230,50,100);
// set the fill color to pure green and draw a rectangle:
fill(0,255,0);
rect(200,200,50,100);
// set the outline color to pure blue:
stroke(0,0,255);
// draw the following shapes without any fill color:
noFill();
// draw a ellipse:
ellipse(100,100,20,20);



II Relations

/* RELATIONS
 *
 * Instead of using fixed values, we use variables
 * to formulate relations. In this example a structure
 * based on two vertical parallel lines with a circle 
 * in between is formulated. 
 *
 * Frederic Gmeiner 2011
 */
 
// variable to store the radius of the circle:
int rad = 40;
// variables to store the x and y position of the structure:
int startPointX = 100;
int startPointY =100;

size(400,400);

// left line starts at the defined values and has a length of 80px:
line(startPointX, startPointY, startPointX, startPointY+80);

// the ellipse in between the two lines has a radius of "rad",
// so the width and height is "2*rad". Since ellipses have their
// origin in the middle in processing, we need to add the radius
// to our "startPointX" value to have it centered in between the lines:
ellipse(startPointX+rad, startPointY+40, 2*rad, 2*rad);

// the right line is set in relation to the width of the circle: 
line(startPointX+(2*rad), startPointY, startPointX+(2*rad), startPointY+80);



III Functions

/* FUNCTIONS
 * 
 * Here we define a custom function ("crossFunction()") which draws a 
 * cross onto the screen.
 * It takes the parameters: X value, Y value and the size.
 * Also the continuous mode is introduced, which 
 * uses the processing functions setup() and draw().
 * Via the pre-defined variables "mouseX" and "mouseY" we
 * can access the current mouse position.
 *
 * Frederic Gmeiner 2011
 */

// the setup() function is called everytime the program
// starts once.
void setup(){
  size(400,400);
}

// the draw() function is the main loop function of your program:
// after every operation in the draw function has been 
// called, the draw function is called again. this
// goes on until the program quits.
void draw(){
  background(255);
  crossFunction(mouseX,mouseY,10);
}

// this is the definition of the custom function "crossFunction()":
void crossFunction(int crossX, int crossY, int crossSize){
  line(crossX-crossSize/2, crossY-crossSize/2, crossX+crossSize/2, crossY+crossSize/2);
  line(crossX+crossSize/2, crossY-crossSize/2, crossX-crossSize/2, crossY+crossSize/2);
}



IV Movement & conditions

/* MOVEMENT & CONDITIONS
 * 
 * By changing a variable during the runtime, 
 * we can alter the condition of the program.
 * Here we increment an integer variable
 * each time draw() is called. This variable is
 * used for the x-position of a line, thus
 * creating the illusion of a continuous movement
 * from left to right. 
 * Via the "if" and "else" branches we can react
 * to different states of the program and alter it
 * accordingly.
 *
 * Frederic Gmeiner 2011
 */

// variable to store the x-position of the line:
int lineX = 0;

void setup(){
  size(500,300);
}

void draw(){
  // clear the background
  background(255);
  
  // if the x position of the line is larger than the middle of the screen:
  if(lineX > width/2){
     // change the stroke colour to pure red:
    stroke(255,0,0);
  // if the x position of the line is smaller than the middle of the screen:
  }else{
    // set the stroke coulour to black:
    stroke(0,0,0);
  }
  
  // draw a vertical line from the top (0) to the bottom ("height") at
  // the current x-position:
  line(lineX,0,lineX,height);
  
  // increment the lineX variable by 1 
  // (you could also simply write "lineX++")
  lineX = lineX+1;
  
  // use the "println()" function to show the value of variables 
  // in the console. this is helpful for debugging.
  println(lineX);
}



Exercise I: Bouncing Line

This is one possible solution to achieve that the line from the example above changes it direction when it reaches the left and right boundaries of the sketch window.

/* BOUNCING LINE
 * 
 * This is a modification of the previous sketch
 * so that the line will bounce off the left and
 * right borders of the window. Notice the introduction
 * of the variable "speed" to control the speed and 
 * direction of the moving line.
 *
 * Frederic Gmeiner 2011
 */
 
// variable to hold the currect x position of the line
int lineX = 0;
// variable that controls the speed and direction
int speed =1;

void setup(){
  size(500,300);
}

void draw(){
  background(204);
  
   // if the x position of the line exceeds the right border of the window:
   // change the direction by setting the speed to a negative value
  if(lineX > width){
    speed = -1; 
  }
  // accordingly set the speed to a positive value as soon as the line touches 
  // the left border.
  if(lineX < 0 ){
    speed = 1;
  }
  
  // here the new x position is calculated by adding the speed onto the 
  // current x position. if speed is -1, lineX decreases. if speed is 1, lineX 
  // increases.
  lineX = lineX + speed;
  
  // draw the line based on the calculated x position:
  line(lineX,0,lineX,height);
}



Exercise II: A frightened rectangle

Write a sketch that contains one rectangle with a size of 20x20px.
As soon as the mouse pointer is over the rectangle, the rectangle starts to shiver.

Some useful hints:


07.11.2011 Processing sketches

Exercise I: Bouncing Line (Advanced)

/* BOUNCING LINE ADVANCED
 * 
 * Notice the introduction of the variables 
 * "speed" and "direction to control the speed 
 * and direction of the moving line inependently.
 *
 * Frederic Gmeiner 2011
 */

// variable to hold the currect x position of the line
float lineX = 0;
// variable that controls the speed
float speed = 2.3f;
// variable that controls the direction
// (either 1 or -1)
int direction = 1;


void setup(){
  size(300,300);
}

void draw(){
  
  background(204);
  
   // if the x position of the line exceeds the right border of the window
   // OR (||) the x position of the line exceeds the left border 
   // of the window:
  if(lineX > width || lineX < 0){
    direction = direction * -1; // change the direction 
  }
  
  // here the new x-position is calculated by adding the speed and direction onto the 
  // current x-position. if direction is -1, lineX decreases. if direction is 1, lineX 
  // increases:
  lineX = lineX + (speed * direction);
  
  // draw the line based on the calculated x-position:
  line(lineX,0,lineX,height);
}



Exercise II: Solution

/* A FRIGHTENED SQUARE
 * 
 * A little sketch to illustrate the random() function
 * and a more complex boolean equation to check whether
 * the mouse pointer is inside a rectangular shape.
 *
 * Frederic Gmeiner 2011
 */

// the x an y positions of the square:
float xPos = 200f;
float yPos = 200f;
// the width and height of the square:
int s = 20;

void setup(){
   size(400,400);
}

void draw(){
  background(204);
  
  // Here we check if the position of the mouse is somewhere inside of the
  // square. To know this, all these four contitions must be true ( && ):
  if( mouseX > xPos && mouseX < xPos + s && mouseY > yPos && mouseY < yPos + s){
      xPos += random(-2,3); // add a random value between -2 and 3 to the xPos
      yPos += random(-2,3);
      fill(40);
  }else{
    fill(255);
  }
  
  // finally draw the square: 
  rect(xPos, yPos, s, s);

}




V for() loops

/* DYNAMIC DISTRIBUTION
 * 
 * This sketch demonstrates the usage of
 * a for-loop for calculating and drawing
 * a certain number of ellipses according
 * to the changing mouseX position.
 *
 * Frederic Gmeiner 2011
 */


// the number of circles:
int numCircles = 15;

void setup(){
  size(500,200);
  stroke(255);
  fill(150);
  smooth();
}

void draw(){
  background(255);
  
  // calculate the distance between the circles
  // so that in total it results in the mouseX position:
  float distance = mouseX / (numCircles-1);
  
  // for every circle (numCircles) calculate the xPos
  // and draw it onto the screen:
  for(int i=0; i < numCircles; i++){
    float xPos = i*distance;
    ellipse(xPos,100,10,10); 
  }
}




VI The array: a collection of variables

/* Random points in an array
 * 
 * This demonstrates how to store values in 
 * an array. This is useful when working with
 * many things which share the same parameters.
 * Here we use two arrays to store the coordinates
 * of circles.
 *
 * Frederic Gmeiner 2011
 */

// total number of circles:
int numCircles = 40;

// the radius of the circles 
float rad = 20f;

// initializing two arrays for storing the x and y positions
// of the circles:
float[] xPositions = new float[numCircles];
float[] yPositions = new float[numCircles];


void setup(){
  
  size(500,500);
  smooth();
  noStroke();
  fill(150);
  
  // iterating over the arrays to set each position with 
  // a random value based on the window size:
  for(int i=0; i< numCircles; i++){
    xPositions[i] = random(0,width);
    yPositions[i] = random(0,height);
  }
}


void draw(){

  background(204);
  
  // again iterating over the arrays. but this time we only 
  // get the x and y coordinates to draw the circles:
  for(int i=0; i< numCircles; i++){
    ellipse(xPositions[i], yPositions[i], rad, rad);
  }

}



Exercise III

Modify the example VI so that the size of the circles changes over time using the sine function sin().

Helpful links:
sin() Example
General introduction (Try out the sketch by copy-pasting it into your processing editor)


14.11.2011 Processing sketches

EXERCISE III: SOLUTION

/* PULSING CIRCLES
 * 
 * Mofification of the example above so that
 * the circles will shrink and grow by using
 * a sinewave.
 *
 * Frederic Gmeiner 2011
 */

int numCircles = 40;
float rad = 20f;

// initial angle of 0. this will increase during the
// runtime of the programm and will be used to calculate
// the sine based on this value in order so modify the size of
// circles.
float angle = 0.0f;
// how fast the angle will increase is defined by the speed variable:
float speed = 0.01;

float[] xPositions = new float[numCircles];
float[] yPositions = new float[numCircles];


void setup(){
  size(500,500);
  smooth();
  noStroke();
  fill(150);
  
  for(int i=0; i< numCircles; i++){
    xPositions[i] = random(0,width);
    yPositions[i] = random(0,height);
  }
}


void draw(){

  background(204);
  // add the speed value to the angle:
  angle += speed;
  
  // calculate the diamater by calculating the sine value of the
  // angle and scaling it up by the value of 30. This is necessary since
  // the sin() funtion returns only values between -1 and 1.
  float diameter = sin(angle)*30;

  for(int i=0; i< numCircles; i++){
    // draw the circles:
    ellipse(xPositions[i], yPositions[i], diameter, diameter);
  }
}




VII.a Another sine and cosine example

/* ELLIPTICAL MOTION
 * 
 * A little demonstration of the sine and 
 * cosine relation.
 *
 * Frederic Gmeiner 2011
 */

float speed = 0.1f;  // frequency
float angle = 0.0f; // you might also call it theta


void draw(){
  
  background(200);
  angle += speed;
  
  point(50,50);
  point(50+ (cos(angle)/2*50), 50+ (sin(angle)*50));

}




VII.b Relation of degree, PI and sine

int degr= 0;

println("0° Degrees:");
println("PI:" + radians(degr) / PI);
println("sine:" + round(sin(radians(degr))) + "\n");

degr= 90;
println("90° Degrees:");
println("PI:" + radians(degr) / PI);
println("sine:" + round(sin(radians(degr))) + "\n");

degr= 180;
println("180° Degrees:");
println("PI:" + radians(degr) / PI);
println("sine:" + round(sin(radians(degr))) + "\n");

degr= 270;
println("270° Degrees:");
println("PI:" + radians(degr) / PI);
println("sine:" + round(sin(radians(degr))) + "\n");

degr= 360;
println("360° Degrees:");
println("PI:" + radians(degr) / PI);
println("sine:" + round(sin(radians(degr))) + "\n");



VIII Reading data from a text file

Imports a data table from a textfile with tab seperated values (tsv).
These formats are very common when exporting spreadsheets from Excel or similar software.
Make sure that the file "measurements.tsv" exists in the data folder of this sketch.

Download: Media:PhysicalComp11 reading tsv.zip




21.11.2011 Arduino workshop sketches

I Blinking LED

/* BLINKING LED
 *
 * Demonstrates how to make a LED connected to digital pin 4 
 * blink in an interval of 1 second. 
 *
 * You could also use the internal LED on pin 13. This
 * LED is mounted onto the board with a resistor in between,
 * so whenn connecting a LED to pin 13 we don't need an extra
 * resistor.
 *  
 */


// specifiy the pin for our LED
int ledPin = 4;

void setup(){ 
  // configure the pin of the LED as an output
  pinMode(ledPin, OUTPUT);
}


void loop(){
  
  // set the LED pin to HIGH (+5 Volts)
  digitalWrite(ledPin, HIGH);
  // wait for 1000 milliseconds = 1 second
  delay(1000);
  // set the LED pin to LOW (0 Volts)
  digitalWrite(ledPin, LOW);
  // again wait 1 second
  delay(1000);

}



II Pushbutton

/* PUSHBUTTON
 *
 * Here we connect a pushbutton to the digital pin 2.
 * When the button is pressed, the LED on port 13
 * (the internal one), starts blinking.
 *  
 */

int myLedPin = 13;      // LED pin
int myButtonPin = 2;    // input pin (for the pushbutton)
int myButtonState = 0;  // variable for storing the inputpin status


void setup() {
  // declare the LED pin as output
  pinMode(myLedPin, OUTPUT);
  // declare the button pin as input
  pinMode(myButtonPin, INPUT);
  
}

void loop(){
   // read the current state of the button pin
   // (either HIGH or LOW) and store it in the
   // variable myButtonState:
  myButtonState = digitalRead(myButtonPin);
  
  // whenever the button is pressed:
  // start the LED blinking
  if (myButtonState == HIGH) {
      digitalWrite(myLedPin, HIGH);
      delay(300);
      digitalWrite(myLedPin, LOW);
      delay(300);
  }
  // when the button is not pressed:
  else{
    // turn off the LED
    digitalWrite(myLedPin, LOW);
  }
}




28.11.2011 Arduino & Processing sketches

III Potentiometer (Arduino)

/* TURNING THE KNOB (ARDUINO)
 * 
 * Here we connect a potentiometer (variable resistor) to
 * the analog pin 3 of our Arduino to control the state 
 * of an LED connected to pin 13 and also to send the
 * value via the serial connection to a processing sketch.
 *
 * The value we get from an analog pin is ranging from 
 * 0 to 1023 (10 Bit). In order to send it as one Byte 
 * (8 Bit) we have to scale the incomming value using
 * the map() function. 
 *
 * NOTE: You can use the same code for many different 
 * types of variable resistors (e.g. photo resistor, 
 * bend sensor, etc.)
 * 
 * Frederic Gmeiner, 2011 
 */

// specify the pin numbers we are going to use:
int ledPin = 13;
int potiPin = 3;
// create a variable to hold the value from the poti:
int potiValue;

void setup(){
  // set the pin mode of the led pin to  act as an output:
  pinMode(ledPin,OUTPUT);
  // establish a serial connection:
  Serial.begin(9600);
}

void loop(){
  // read the current value of the poti pin 
  // and store it in the variable potiValue:
  potiValue = analogRead(potiPin);
  
  // if the value is over a certain threshold
  // (here it's 511 or the middle of the range),
  // turn the LED on, otherwise turn it off:
  if(potiValue > 511){
    digitalWrite(ledPin,HIGH);
  }else{
    digitalWrite(ledPin,LOW);
  }
  
  // in oder to send the poti value as one byte (0-255)
  // we have to scale it from the original range (0 - 1023):
  int scaledVal = map(potiValue,0,1023,0,255);
  // send the scaled value via the serial port as a byte:
  Serial.print(scaledVal,BYTE);
  // wait a little bit to not overload the serial buffer:
  delay(50);
}



III Potentiometer (Processing)

/* TURNING THE KNOB (PROCESSING)
 * 
 * Example of how to read incomming data
 * from the serial connection.
 * 
 * Frederic Gmeiner, 2011 
 */

// first we have to import the serial library:
import processing.serial.*;

// variable for our Serial object:
Serial myPort;
// variable to hold the incomming value
int incomingVal;

void setup(){
  size(255,255);
  // this line is very helpful to find out the name of the serial 
  // port of your Arduino. It lists all available ports of your
  // computer. (Make sure that your arduino is connected to a USB
  // port before running this sketch) 
  println(Serial.list());
  
  // make a new Serial object with the name of our current Arduino 
  // port. NOTE: The name of the port is different for each Arduino
  // so we have to change it accordingly. On a windows system it is
  // called different like "COM3" or similar. 
  myPort = new Serial(this,"/dev/tty.usbserial-A70061cx",9600);
}

void draw(){
  background(0);
  
  // only read from the serial port if there is new data 
  // available and store this in the variable incommingVal:  
  while(myPort.available() > 0){
    incomingVal = myPort.read();
  }
  // set the fill color to the incoming value: 
  fill(incomingVal);
  // draw a rectangle with the height of the
  // incomming value:
  rect(0,height-incomingVal,width,height);
}



05.12.2011 Arduino & Processing sketches

IV LED Brightness (Arduino)

/* MOUSE LED (ARDUINO)
 * 
 * This sketch uses the PWM (Pulse width modulation)
 * function of the Arduino to create voltages between 
 * 0V and 5V (analog output) to set the brightness of a LED.
 * The value for the LED brightness is received via 
 * the serial connection from a processing sketch where
 * it is created from the mouse's y position.
 *
 * Look at the example "I Blinking LED" for how to 
 * connect the LED, but make sure that you use the
 * pin declared in this sketch.
 *  
 * Frederic Gmeiner, 2011 
 */

// pin connected to the LED
// (make sure that it is labeled with PWM)
int myLedPin = 11;   
// for storing the incoming data
byte myIncomingData;      

void setup() {
  // initialize serial communication
  Serial.begin(9600);
}

void loop() {
  // only read if there is new data on the serial port
  while (Serial.available() > 0) {
    myIncomingData = Serial.read();
  }

  // set brightness of the LED with the last value from the serial port
  analogWrite(myLedPin, myIncomingData);

  // wait 10 milliseconds to avoid overloading the serial port
  delay(10);
}



IV LED Brightness (Processing)

/* MOUSE LED (PROCESSING)
 * 
 * Here we take the y-position of the mouse
 * and map it to the range of 0-255 to 
 * set the background color and to
 * send it to the serial port of the
 * Arduino.
 *  
 * Frederic Gmeiner, 2011 
 */

import processing.serial.*;

// serial port object
Serial myPort;
// for storing the scaled y position value
int myValue;

void setup()
{  
  size(200, 500);
  // print all serial devices
  println("Available serial ports:");
  println(Serial.list());
  // set the port which is connected to the arduino board
  // !!! CHANGE THE "/dev/tty.usbserial-A70061cx" TO THE NAME OF YOUR
  // PORT !!!
  myPort = new Serial(this, "/dev/tty.usbserial-A70061cx", 9600);
}

void draw()
{ 
  // get the y position of the mouse, which can be something
  // between 0 and the HEIGHT of the sketch window and map
  // it to the range of 0 - 255. The map() function returns a
  // float value so we have to cast the output to an integer
  // before assigning it to myValue
  myValue = int( map(mouseY,0,height,0,255));
  // for debugging: print myValue to the console
  println(myValue);
  // set the background color to myValue
  background(myValue);
  // send myValue to the arduino port
  myPort.write(myValue);
}



IX translate() and rotate() (PROCESSING ONLY)

/* ORBITING RECTS (PROCESSING ONLY)
 * 
 * Example of the translate() and rotate()
 * functions. Try to comment out certain lines
 * of the code to understand what exactly happens
 * during the runtime of the program.
 *
 * There is also a good tutorial which explains
 * 2D transformations:
 * http://processing.org/learning/transform2d/
 * 
 * Frederic Gmeiner, 2011 
 */

// value used for the increasing rotation 
float rotationVal = 0;

void setup(){
  size(500,500);
  smooth();
  noStroke();
  // this tells processing to draw rectangles
  // from the center instead of the upper left
  // corner
  rectMode(CENTER);
}

void draw(){
  
  background(100);
  // set the origin to the center of the sketch window
  // (so width/2, height/2 is now equal to 0,0 )
  translate(width/2,height/2);
  // rotate the whole scene by the amount of
  // the increasing rotationVal
  rotate(rotationVal);
  // change the origin again by 100 pixels to the right. 
  // we are doing this so that the rectangle won't stick 
  // to the center of the sketch and rotates there, 
  // but rather let the rect orbit around the
  // center with a distance of 100px.
  translate(100,0);
  
  // now draw the black rectangle to the 
  // origin (0,0)
  fill(0);
  rect(0,0,30,30);
  
  // to get to the position of the smaller red
  // rectangle which is circling faster, we have
  // to rotate the scene again with a multiplication
  // of the prvious rotation:
  rotate(rotationVal*4);
  // shift the origin again by 40px to the right:
  translate(40,0);
  
  // draw the smaller red rectangle
  fill(255,0,0);
  rect(0,0,5,5);
  
  // increase the rotation value a bit:
  rotationVal += 0.01;
}



X String, Char & Typography (PROCESSING ONLY)

/* RANDOM LETTERS
 * 
 * Example of how to work with font files and
 * charecters (char).
 * In order to use a font face we have to 
 * convert it using the Tools>create font...
 * menu. This will make the font available 
 * in the data folder of this sketch.
 * Follow this tutorial for detailed 
 * descriptions:
 * http://processing.org/learning/text/
 * 
 * Frederic Gmeiner, 2011 
 */

// create a font object
PFont mySerif;

void setup() {
  size(400,400);
  smooth();
  // load the font file "Baskerville-48.vlw" from
  // the data folder
  // !!! MAKE SURE THAT YOU HAVE THE FILE IN YOUR 
  // DATA FOLDER OR THAT YOU CREATED A NEW ONE AND CHANGED
  // THE NAME ACCORDINGLY !!!
  mySerif = loadFont("Baskerville-48.vlw");
  // set the text align to center
  textAlign(CENTER);
  background(0);
  fill(255,0,0);
  // specify the font and the size which should 
  // be used when calling the text() function
  textFont(mySerif, 15);
  // write "random letters" to the position 50,15
  text("random letters", 50, 15);
}

void draw() {
  //background(0);
  
  fill(200,200,200,50);
  // set the font and font size
  textFont(mySerif, 32);
  // instead of writing a String to the screen we only
  // draw a single randomly chosen character to the current
  // mouse position.
  // the char() function returns a character from the unicode 
  // table by the index. 
  text( char(int(random(150))), mouseX, mouseY);
}