Month: June 2015
Bonus: Waves
int i, w=1024, h=768, x, y, s=10;
float k, m, r, j=.01;
void setup() {
size(w, h, P3D);
noStroke();
}
void draw()
{
background(#A4D6E8);
lights();
beginShape(8);
for (i=0; i < w*h; i+=s)
{
x=i%w;
y=i/w;
k=y+s;
m=x+s;
fill(100, 100, random(220,255), 200);
vertex(x, n(y*w+x), y);
vertex(m, n(y*w+m), y);
vertex(m, n(k*w+m), k);
vertex(m, n(k*w+m), k);
vertex(x, n(k*w+x), k);
vertex(x, n(y*w+x), y);
i+=i%w==0?w*(s-1):0;
}
endShape();
r-=j;
fill(100, 100, random(220,255), 200);
rect(0, width* .5, width, 400);
}
float n(float i) {
return noise(i%w*j, i*j/w+r)*s*8+h/2;
}
Final Assignments
For the workshop our goal is to produce three final products.
1. High Resolution 11 x 17″ print
2. HD Video animation (1920 x 1080 px) or (1024 x 768 px)
3. Laser cut Lamp (size to be determined)
Creating a lamp with Processing
We will use an existing Processing library to create the pieces for the laser-cut lamp. Let’s follow the instructions here.
Codeable Objects Library
Codeable Objects is a library for Processing that allows anyone to design and construct an artifact using geometric computation and digital fabrication. This tutorial will show you how to use the library to make a laser cut lamp. The library allows you to customize the size, shape and decorative patterns of the lamp.
Bonus: Circular Galaxy
int num = 40, circles=80, frames=60;
float theta;
void setup() {
size(540, 540);
}
void draw() {
randomSeed(3453);
background(0);
noStroke();
float angle = 0;
for (int j=0; j < circles; j++) {
fill(255, 25);
float r = random(TWO_PI);
beginShape(TRIANGLE_STRIP);
float r2 = random(30, 50);
for (int i=0; i < num; i++) {
angle=TWO_PI/num*i+r;
float offSet=TWO_PI/num*i;
float d = 120+cos(offSet*3)*r2;
float x = width/2 +sin(theta+offSet)*10 + sin(angle)*d;
float y = height/2 + cos(theta+offSet)*10 + cos(angle)*d;
vertex(x, y);
ellipse(x, y, 3, 3);
}
endShape(CLOSE);
}
theta+=TWO_PI/frames;
//if (frameCount <= frames) saveFrame("imge-###.gif");
}
Bonus: Glitch 2
PImage img;
int min = 40, max = 80;
int r = 10;
void setup() {
img = loadImage("https://s-media-cache-ak0.pinimg.com/736x/2c/f6/a5/2cf6a58f75b368949cf98db03b925f1b.jpg");
size(img.width, img.height);
image(img, 0, 0);
}
void draw() {
doStuff();
}
void keyPressed() {
save(random(123456)+".jpg");
}
void doStuff() {
PImage tmp = createImage(width, height, RGB);
tmp.loadPixels();
float rd = random(25, 100);
for (int px=0; px < width; px++) {
for (int py=0; py < height; py++) {
float br = brightness(img.get(px, py));
if (br>rd) tmp.pixels[py*width+px]=get(px, py);
}
}
tmp.updatePixels();
int v = (int)random(-r, r);
int v2 = (int)random(-r, r);
image(tmp, v, v2);
}
void mouseClicked() {
//doStuff();
}
Bonus: Mouse Follower
// P_2_2_3_02.pde
//
// Generative Gestaltung, ISBN: 978-3-87439-759-9
// First Edition, Hermann Schmidt, Mainz, 2009
// Hartmut Bohnacker, Benedikt Gross, Julia Laub, Claudius Lazzeroni
// Copyright 2009 Hartmut Bohnacker, Benedikt Gross, Julia Laub, Claudius Lazzeroni
//
// http://www.generative-gestaltung.de
/**
* form mophing process by connected random agents
* two forms: circle and line
*
* MOUSE
* click : start a new circe
* position x/y : direction and speed of floating
*
* KEYS
* 1-2 : fill styles
* 3-4 : form styles circle/line
* arrow up/down : step size +/-
* f : freeze. loop on/off
* Delete/Backspace : clear display
* s : save png
* r : start pdf recording
* e : stop pdf recording
*/
import processing.pdf.*;
import java.util.Calendar;
boolean recordPDF = false;
int formResolution = 15;
int stepSize = 2;
float distortionFactor = 1;
float initRadius = 150;
float centerX, centerY;
float[] x = new float[formResolution];
float[] y = new float[formResolution];
boolean filled = false;
boolean freeze = false;
int mode = 0;
void setup(){
// use fullscreen size
size(displayWidth, displayHeight);
smooth();
// init form
centerX = width/2;
centerY = height/2;
float angle = radians(360/float(formResolution));
for (int i=0; i < formResolution; i++){
x[i] = cos(angle*i) * initRadius;
y[i] = sin(angle*i) * initRadius;
}
stroke(0, 50);
background(255);
}
void draw(){
// floating towards mouse position
if (mouseX != 0 || mouseY != 0) {
centerX += (mouseX-centerX) * 0.01;
centerY += (mouseY-centerY) * 0.01;
}
// calculate new points
for (int i=0; i < formResolution; i++){
x[i] += random(-stepSize,stepSize);
y[i] += random(-stepSize,stepSize);
// ellipse(x[i], y[i], 5, 5);
}
strokeWeight(0.75);
if (filled) fill(random(255));
else noFill();
if (mode == 0) {
beginShape();
// start controlpoint
curveVertex(x[formResolution-1]+centerX, y[formResolution-1]+centerY);
// only these points are drawn
for (int i=0; i < formResolution; i++){
curveVertex(x[i]+centerX, y[i]+centerY);
}
curveVertex(x[0]+centerX, y[0]+centerY);
// end controlpoint
curveVertex(x[1]+centerX, y[1]+centerY);
endShape();
}
if (mode == 1) {
beginShape();
// start controlpoint
curveVertex(x[0]+centerX, y[0]+centerY);
// only these points are drawn
for (int i=0; i < formResolution; i++){
curveVertex(x[i]+centerX, y[i]+centerY);
}
// end controlpoint
curveVertex(x[formResolution-1]+centerX, y[formResolution-1]+centerY);
endShape();
}
}
void mousePressed() {
// init forms on mouse position
centerX = mouseX;
centerY = mouseY;
// circle
if (mode == 0) {
centerX = mouseX;
centerY = mouseY;
float angle = radians(360/float(formResolution));
float radius = initRadius * random(0.5,1.0);
for (int i=0; i < formResolution; i++){
x[i] = cos(angle*i) * radius;
y[i] = sin(angle*i) * radius;
}
}
// line
if (mode == 1) {
centerX = mouseX;
centerY = mouseY;
float radius = initRadius * random(0.5,5.0);
float angle = random(PI);
radius = initRadius*4;
angle = 0;
float x1 = cos(angle) * radius;
float y1 = sin(angle) * radius;
float x2 = cos(angle-PI) * radius;
float y2 = sin(angle-PI) * radius;
for(int i=0; i < formResolution; i++) {
x[i] = lerp(x1, x2, i/(float)formResolution);
y[i] = lerp(y1, y2, i/(float)formResolution);
}
}
}
void keyPressed() {
if (keyCode == UP) stepSize++;
if (keyCode == DOWN) stepSize--;
stepSize = max(stepSize, 1);
println("stepSize: " + stepSize);
}
void keyReleased() {
if (key == 's' || key == 'S') saveFrame(timestamp()+"_##.png");
if (key == DELETE || key == BACKSPACE) background(255);
if (key == '1') filled = false;
if (key == '2') filled = true;
if (key == '3') mode = 0;
if (key == '4') mode = 1;
// ------ pdf export ------
// press 'r' to start pdf recording and 'e' to stop it
// ONLY by pressing 'e' the pdf is saved to disk!
if (key =='r' || key =='R') {
if (recordPDF == false) {
beginRecord(PDF, timestamp()+".pdf");
println("recording started");
recordPDF = true;
stroke(0, 50);
}
}
else if (key == 'e' || key =='E') {
if (recordPDF) {
println("recording stopped");
endRecord();
recordPDF = false;
background(255);
}
}
// switch draw loop on/off
if (key == 'f' || key == 'F') freeze = !freeze;
if (freeze == true) noLoop();
else loop();
}
// timestamp
String timestamp() {
Calendar now = Calendar.getInstance();
return String.format("%1$ty%1$tm%1$td_%1$tH%1$tM%1$tS", now);
}
Exercise 55
int _numChildren = 4; int _maxLevels = 4; Branch _trunk; void setup() { size(750,500); background(255); noFill(); smooth(); newTree(); } void newTree() { _trunk = new Branch(1, 0, width/2, height/2); _trunk.drawMe(); } void draw() { background(255); _trunk.updateMe(width/2, height/2); _trunk.drawMe(); }
class Branch { float level, index; float x, y; float endx, endy; float strokeW, alph; float len, lenChange; float rot, rotChange; Branch[] children = new Branch[0]; Branch(float lev, float ind, float ex, float why) { level = lev; index = ind; strokeW = (1/level) * 10; alph = 255 / level; len = (1/level) * random(500); rot = random(360); lenChange = random(10) - 5; rotChange = random(10) - 5; updateMe(ex, why); if (level < _maxLevels) { children = new Branch[_numChildren]; for (int x=0; x < _numChildren; x++) { children[x] = new Branch(level+1, x, endx, endy); } } } void updateMe(float ex, float why) { x = ex; y = why; rot += rotChange; if (rot > 360) { rot = 0; } else if (rot < 0) { rot = 360; } len -= lenChange; if (len < 0) { lenChange *= -1; } else if (len > 500) { lenChange *= -1; } float radian = radians(rot); endx = x + (len * cos(radian)); endy = y + (len * sin(radian)); for (int i=0; i < children.length; i++) { children[i].updateMe(endx, endy); } } void drawMe() { if (level > 1) { strokeWeight(strokeW); stroke(0, alph); fill(255, alph); line(x, y, endx, endy); ellipse(endx, endy, len/12, len/12); } for (int i=0; i < children.length; i++) { children[i].drawMe(); } } }
Exercise 54
// P_2_1_3_02.pde
//
// Generative Gestaltung, ISBN: 978-3-87439-759-9
// First Edition, Hermann Schmidt, Mainz, 2009
// Hartmut Bohnacker, Benedikt Gross, Julia Laub, Claudius Lazzeroni
// Copyright 2009 Hartmut Bohnacker, Benedikt Gross, Julia Laub, Claudius Lazzeroni
//
// http://www.generative-gestaltung.de
/**
* draw a module made of lines in a grid
*
* MOUSE
* position x : number of tiles horizontally
* position y : number of tiles vertically
*
* KEYS
* 1-3 : draw mode
* s : save png
* p : save pdf
*/
import processing.pdf.*;
import java.util.Calendar;
boolean savePDF = false;
float tileCountX = 5;
float tileCountY = 5;
int count = 10;
int colorStep = 20;
int lineWeight = 0;
int strokeColor = 0;
color backgroundColor = 0;
int drawMode = 1;
void setup() {
size(600, 600);
}
void draw() {
if (savePDF) beginRecord(PDF, timestamp()+".pdf");
colorMode(HSB, 360, 100, 100);
smooth();
strokeWeight(0.5);
strokeCap(ROUND);
tileCountX = mouseX/30+1;
tileCountY = mouseY/30+1;
background(backgroundColor);
for (int gridY=0; gridY<= tileCountY; gridY++) {
for (int gridX=0; gridX<= tileCountX; gridX++) {
float tileWidth = width/tileCountX;
float tileHeight = height/tileCountY;
float posX = tileWidth*gridX;
float posY = tileHeight*gridY;
float x1 = tileWidth/2;
float y1 = tileHeight/2;
float x2 = 0;
float y2 = 0;
pushMatrix();
translate(posX, posY);
for(int side = 0; side < 4; side++) {
for(int i=0; i< count; i++) {
// move end point around the four sides of the tile
if(side == 0){
x2 += tileWidth/count;
y2 = 0;
}
if(side == 1){
x2 = tileWidth;
y2 += tileHeight/count;
}
if(side == 2){
x2 -= tileWidth/count;
y2 = tileHeight;
}
if(side == 3){
x2 = 0;
y2 -= tileHeight/count;
}
// adjust weight and color of the line
if(i < count/2){
lineWeight += 1;
strokeColor += 60;
}
else {
lineWeight -= 1;
strokeColor -= 60;
}
// set colors depending on draw mode
switch(drawMode){
case 1:
backgroundColor = 360;
stroke(0);
break;
case 2:
backgroundColor = 360;
stroke(0);
strokeWeight(lineWeight);
break;
case 3:
backgroundColor = 0;
stroke(strokeColor);
strokeWeight(mouseX/100);
break;
}
// draw the line
line(x1, y1, x2, y2);
}
}
popMatrix();
}
}
if (savePDF) {
savePDF = false;
endRecord();
}
}
void keyPressed() {
if (key == 's' || key == 'S') saveFrame(timestamp()+"_##.png");
if (key == 'p' || key == 'P') savePDF = true;
if (key == '1') drawMode = 1;
if (key == '2') drawMode = 2;
if (key == '3') drawMode = 3;
}
// timestamp
String timestamp() {
Calendar now = Calendar.getInstance();
return String.format("%1$ty%1$tm%1$td_%1$tH%1$tM%1$tS", now);
}
Exercise 53
// P_2_1_3_04.pde
//
// Generative Gestaltung, ISBN: 978-3-87439-759-9
// First Edition, Hermann Schmidt, Mainz, 2009
// Hartmut Bohnacker, Benedikt Gross, Julia Laub, Claudius Lazzeroni
// Copyright 2009 Hartmut Bohnacker, Benedikt Gross, Julia Laub, Claudius Lazzeroni
//
// http://www.generative-gestaltung.de
/**
* changing positions of stapled circles in a grid
*
* MOUSE
* position x : module detail
* position y : module parameter
*
* KEYS
* 1-3 : draw mode
* arrow left/right : number of tiles horizontally
* arrow up/down : number of tiles vertically
* s : save png
* p : save pdf
*/
import processing.pdf.*;
import java.util.Calendar;
boolean savePDF = false;
float tileCountX = 6;
float tileCountY = 6;
int count = 0;
int drawMode = 1;
void setup() {
size(550, 550);
}
void draw() {
if (savePDF) beginRecord(PDF, timestamp()+".pdf");
colorMode(HSB, 360, 100, 100);
rectMode(CENTER);
smooth();
stroke(0);
noFill();
background(360);
count = mouseX/10 + 10;
float para = (float)mouseY/height;
for (int gridY=0; gridY <= tileCountY; gridY++) {
for (int gridX=0; gridX <= tileCountX; gridX++) {
float tileWidth = width / tileCountX;
float tileHeight = height / tileCountY;
float posX = tileWidth*gridX + tileWidth/2;
float posY = tileHeight*gridY + tileHeight/2;
pushMatrix();
translate(posX, posY);
// switch between modules
switch (drawMode) {
case 1:
for(int i=0; i < count; i++) {
rect(0, 0, tileWidth, tileHeight);
scale(1 - 3.0/count);
rotate(para*0.1);
}
break;
case 2:
for(float i=0; i < count; i++) {
noStroke();
color gradient = lerpColor(color(0), color(52, 100, 71), i/count);
fill(gradient, i/count*200);
rotate(PI/4);
rect(0, 0, tileWidth, tileHeight);
scale(1 - 3.0/count);
rotate(para*1.5);
}
break;
case 3:
colorMode(RGB, 255);
for(float i=0; i < count; i++) {
noStroke();
color gradient = lerpColor(color(0, 130, 164), color(255), i/count);
fill(gradient,170);
pushMatrix();
translate(4*i,0);
ellipse(0, 0, tileWidth/4, tileHeight/4);
popMatrix();
pushMatrix();
translate(-4*i,0);
ellipse(0, 0, tileWidth/4, tileHeight/4);
popMatrix();
scale(1 - 1.5/count);
rotate(para*1.5);
}
break;
}
popMatrix();
}
}
if (savePDF) {
savePDF = false;
endRecord();
}
}
void keyReleased(){
if (key == 's' || key == 'S') saveFrame(timestamp()+"_##.png");
if (key == 'p' || key == 'P') savePDF = true;
if (key == '1') drawMode = 1;
if (key == '2') drawMode = 2;
if (key == '3') drawMode = 3;
if (keyCode == DOWN) tileCountY = max(tileCountY-1, 1);
if (keyCode == UP) tileCountY += 1;
if (keyCode == LEFT) tileCountX = max(tileCountX-1, 1);
if (keyCode == RIGHT) tileCountX += 1;
}
// timestamp
String timestamp() {
Calendar now = Calendar.getInstance();
return String.format("%1$ty%1$tm%1$td_%1$tH%1$tM%1$tS", now);
}