Skip navigation

Monthly Archives: January 2009

IMG_6303

This is my soda can button. The program detects when a soda can is placed on the coaster-like button and simulates fizzing by trapping the bubbles at the top of the screen. Once the can is lifted, the bubbles move upwards freely to give the effect of drinking the soda.

Here’s a close up of the button. I basically just soldered two wires to the mouse left button and made it so when the can was placed, it would complete the circuit and thus press the button.

IMG_6305

Here’s the code. I modified this Processing tutorial.

int numBalls = 700;
float spring = 0.005;
float gravity = 0.03;
float friction = -0.5;
Ball[] balls = new Ball[numBalls];

void setup()
{
size(500, 800);
noStroke();
smooth();
for (int i = 0; i < numBalls; i++) {
balls[i] = new Ball(random(width), random(height), random(5, 15), i, balls);
}
}

void draw()
{
background(85,52,19);
for (int i = 0; i < numBalls; i++) {
if (keyPressed) {
balls[i].collide();
balls[i].collect();
balls[i].display();
} else {
balls[i].collide();
balls[i].move();
balls[i].display();
}
}
}

class Ball {
float x, y;
float diameter;
float vx = 0;
float vy = 0;
int id;
Ball[] others;

Ball(float xin, float yin, float din, int idin, Ball[] oin) {
x = xin;
y = yin;
diameter = din;
id = idin;
others = oin;
}

void collide() {
for (int i = id + 1; i < numBalls; i++) {
float dx = others[i].x – x;
float dy = others[i].y – y;
float distance = sqrt(dx*dx + dy*dy);
float minDist = others[i].diameter/2 + diameter/2;
if (distance < minDist) {
float angle = atan2(dy, dx);
float targetX = x + cos(angle) * minDist;
float targetY = y + sin(angle) * minDist;
float ax = (targetX – others[i].x) * spring;
float ay = (targetY – others[i].y) * spring;
vx -= ax;
vy -= ay;
others[i].vx += ax;
others[i].vy += ay;
}
}
}

void move() {
vy -= gravity;
y = y – .25;
if (y width) {
x = width – diameter;
vx *= friction;
}
else if (x – diameter height) {
y = height – diameter/2;
vy *= friction;
}
else if (y – diameter/2 < 0) {
y = diameter/2;
vy *= friction;
}
}

void display() {
fill(255, 204);
ellipse(x, y, diameter, diameter);
}
}

Cube, coveredCube Output

I had a bluetooth keyboard around that I didn’t like, so I created a new kind of wireless input device. I made a cube that could sense which side was up — my original plan being to use this information to roll around a virtual cube. However, making the cube took so much time I ended up having to go with a simpler idea — displaying a color similar to the currently-up color of he cube.

Source code posted here.

My instructable for the orientation sensors here.

A bit more detail. The five-cent orientation sensors (two of these are used):

orientation sensor, no top

With the cap on:

orientation sensor, assembled

The keyboard interface. There were conveniently placed “test points” — essentially hacking-ready solder pads — for each contact:
Keyboard interface

Everything fit into the box (a floppy disk box that I’ve had for something like six years and have never used for anything):

Cube, put together

Overall, I’m pleased with the feel of the resulting cube. I think more could be done with the visualization. I’d also like it if the tilt sensors worked better (the nickles sometimes bind a bit on the perfboard). Finally, even though I do like the current feel, the whole cube isn’t as solid as it could be — a purpose-built (and painted) enclousure would be a nice addition to this project.

I’m still learning Processing so please excuse me if this reeks of tutorial stuff. I did learn a lot and tried to add different visual elements. Here’s a screenshot and code. By the way, the music was “Anyway You Choose to Give It” by The Black Ghosts, remixed by Boy-8-Bit.

Picture 1

int numChars = 26;
color[] colors = new color[numChars];
int keyIndex;
float keyScale;
int rectWidth;

int gx = 15;
int gy = 35;
float leftColor = 0.0;
float rightColor = 0.0;

void setup()
{
size(400, 400);
noStroke();
background(0);
smooth();
keyScale = 400/numChars-1.0;
rectWidth = width/4;
}

void draw()
{
float circles = map(mouseX, 0, 50, 2, 18);
int x = int(random(0, 400));
int y = int(random(0, 400));
if(keyPressed) {
if(key >= ‘A’ && key <= ‘y’) {
if(key <= ‘Y’) {
keyIndex = key-‘A’;
} else {
keyIndex = key-‘a’;
}
fill(millis()%255);
float beginRect = rectWidth/2 + keyIndex*keyScale-rectWidth/2;
rect(beginRect, 0.0, rectWidth, height);
}
if (key == ‘z’) {
setup();
}
}
if (mousePressed) {
ellipse(x, y, circles, circles);
}
}

 

Screen Shot from program

Screen Shot from program

Code Below:

 

 

// Q: mixed rectangles& circles(yellow and purple) on navy
// A: red ellipses
// S: green ellipses
// D: pink backqround change from bottom left
// z: orange background change from bottom left
// X: purple circles from bottom left
// C: pink circles from bottom right
// V: restore blue
// B: white background
float fillSize=0;
float fillSizeZ=0;
float fillSizeX=0;
float fillSizeC=0;
float fillSizeF=0;
float fillSizeQ=0;
float location =width/2;
int numCountA= 0;
int numCountS=0;
void setup(){
  background(36,34,121);
  size(500,500);
  smooth();
}
void draw(){
  for (int i=50; i>0; i–){
    numCountS= numCountS + 16;
    if (numCountS > 100000){
      numCountS=0;
    }
  } 
  // V: restore blue
  if (key == ‘v’ || key == ‘V’) {
    background(36,34,121);
  }
  // B:white background
  if (key == ‘b’ || key == ‘B’) {
    background(255, 50);
  }
  for (int i=0; i<50; i++){
    numCountA= numCountA + 16;
    if (numCountA > 100000){
      numCountA=0;
    }
  } 
  //A:red ellipses
  if (key == ‘a’ || key == ‘A’){
    background(36,34,121);
    noFill();
    stroke(255,0,0);
    strokeWeight(6);
    ellipse(random(000,250),random(00,250), numCountA/1000, numCountA/1000);
  }
  // S:green ellipses
  if(key==’s’|| key==’S’){
    background(36,34,121);
    noFill();
    stroke(0,255,0);
    strokeWeight(10);
    ellipse(random(250,500),random(250,500), numCountS/1000, numCountS/1000);
  }
  // D:pink backqround change from bottom left
  if (key ==’d’|| key ==’D’){
    for (int i=0; i<=100; i++){
      fillSize = fillSize +1;
      if (fillSize ==1500|| fillSize >1500){
        fillSize =0;
      }
    }
    fill(239,30,173);
    noStroke();
    ellipse(0,0,fillSize, fillSize);
    println(fillSize);  
  }
  // z:orange background change from bottom left
  if (key ==’z’|| key ==’Z’){
    for (int i=0; i<=100; i++){
      fillSizeZ = fillSizeZ +1;
      if (fillSizeZ ==1500|| fillSizeZ >1500){
        fillSizeZ =0;
      }
    }
    fill(246,155,38);
    noStroke();
    ellipse(0,500,fillSizeZ, fillSizeZ);
    println(fillSizeZ);  
  }
  // X:purple circles from bottom left
  if (key ==’x’|| key ==’X’){
    for (int i=0; i<=100; i++){
      fillSizeX = fillSizeX +.5;
      if (fillSizeX ==1500|| fillSizeX >1500){
        fillSizeX =0;
      }
    }
    noFill();
    strokeWeight(5);
    stroke(165,38,246);
    ellipse(0,400,fillSizeX, fillSizeX);
    println(fillSizeX);  
  }
  //C:pink circles from bottom right
  if (key ==’c’|| key ==’C’){
    for (int i=0; i<=100; i++){
      fillSizeC = fillSizeC +.5;
      if (fillSizeC ==1500|| fillSizeC >1500){
        fillSizeC =0;
      }
    }
    noFill();
    strokeWeight(5);
    stroke(231,12,223);
    ellipse(400,400,fillSizeC, fillSizeC);
    println(fillSizeC);  
  }
  //Q:mixed rectangles& circles(yellow and purple) on navy
  if (key ==’q’|| key ==’Q’){
    for (int i=0; i<=100; i++){
      fillSizeQ = fillSizeQ +1;
      if (fillSizeQ ==50|| fillSizeQ >50){
        fillSizeQ =0;
      }
    }
    noFill();
    strokeWeight(random(0,6));
    stroke(250,252,64);
    background(36,34,121);
    rect(random(0,60),random(0,100),fillSizeQ, fillSizeQ);
    rect(random(80,300),random(130,400),fillSizeQ, fillSizeQ);
    rect(random(300, 350),random(300,350),fillSizeQ, fillSizeQ);
    stroke(149,131,217);
    ellipse(random(0,500),random(0,500),fillSizeQ, fillSizeQ);
    ellipse(random(400,480),random(400,480),fillSizeQ, fillSizeQ);
    ellipse(random(200,400),random(200,175),fillSizeQ, fillSizeQ);
  }
}
Spots and Light

Spots and Light

I wanted to create a visualization that didn’t have a specific focal point, and one that would not persist without interaction. Thus I have a warping repeated texture of dots with lights “behind” them. I like the mystery here; the dots are always “in plain sight” but you can’t see them without the lights.

Source code, for now, at: http://www.cs.cmu.edu/~jmccann/ex1.zip

http://paulshen.name/sketches/3

Paul Shen

Installations

Swimming Pool – Leandro Erlich

Interactive Water Pool Art+Com

Interactive Water Pool 2 Art+Com

Cheese Christian Moeller

Legible City – Jeffrey Shaw (1989)

The Golden Calf – Jeffrey Shaw (1994)

The Giver of Names – David Rokeby (1990)

Pocket Full of Memories – George LeGrady (2001-2003)

InTouch – Tangible Media Group MIT Media Lab (1997)

Mary Sester – Access (2003)

The Most Wanted Painting – Komar & Melamid (1995-1997)

Graffiti Research Lab

Boundary Functions – Scott Snibe (1998)

Stock Merket Skirt – Nancy Patterson (1998)

clink! – Fabian Winkler (2002)

Wooden Mirror – Daniel Rozin (1999)

A Hole in Space – Kit Galloway and Sherrie Rabinowitz (1980)

Is anyone out there? – Stephen Wilson (1992)

Das Zimmer (The Room) – Pipilotti Rist (1994)

Cubee

This visualization accompanies “I’d Rather Dance With You” by Kings of Convenience. The objects are simple shapes (circles, “loud” circles, arrows, meteors) with colors drawn randomly from a set of rainbow colors, on a black background, but they are transient so it’s hard to capture a screenshot. I wanted to convey the dancing-ness of the music with fast-moving objects with colorfulness that hopefully reminds people of the disco era. The code can be found here; the input uses numbers 1-8.

// Darren’s Dancing Man

int size_x = 1000;

int size_y = 1000;
int i;

float bodywidth = 75;
float bodyheight = 150;
float L_x = size_x/2 – bodywidth/2;
float L_y = size_y/3;
float R_x = L_x + bodywidth;
float R_y = L_y;
float L_angle1 = 0.0;
float L_angle2 = 0.0;
float R_angle1 = 0.0;
float R_angle2 = 0.0;
float segLength_arm = 50;
float rand_x;
float rand_y;
float rand_col;

void setup() {
size(size_x, size_y);
smooth();
strokeWeight(25.0);
stroke(0, 100);
}

void draw() {
background(25,25,25);
if(keyPressed) {
if (key == ‘z’) {
ellipse(size_x/2,size_y/2-bodyheight/2,500+300,500+300);
if (mousePressed) {
fill(random(255),random(255),random(255));

}
R_angle1 = (mouseX/float(width) – 0.5) * -PI;
R_angle2 = (mouseY/float(height) – 0.5) * PI;

L_angle1 = PI + (mouseX/float(width) – 0.5) * -PI;
L_angle2 = (mouseY/float(height) – 0.5) * PI;

draw_man();
}
if (key == ‘x’) {
ellipse(size_x/2,size_y/2-bodyheight/2,500+125,500+125);
if (mousePressed) {
fill(random(255),random(255),random(255));
}
R_angle1 = (mouseX/float(width) – 0.5) * -PI;
R_angle2 = (mouseY/float(height) – 0.5) * PI;

L_angle1 = PI + (mouseX/float(width) – 0.5) * -PI;
L_angle2 = (mouseY/float(height) – 0.5) * PI;

draw_man();
}
if (key == ‘c’) {
ellipse(size_x/2,size_y/2-bodyheight/2,500 – 50,500 – 50);
if (mousePressed) {
fill(random(255),random(255),random(255));
}
R_angle1 = (mouseX/float(width) – 0.5) * -PI;
R_angle2 = (mouseY/float(height) – 0.5) * PI;

L_angle1 = PI + (mouseX/float(width) – 0.5) * -PI;
L_angle2 = (mouseY/float(height) – 0.5) * PI;

draw_man();
}
i = i +1;
if (i%100 == 0) {
rand_x = random(size_x);
rand_y = random(size_y);
}
ellipse(rand_x,rand_y,100,100);

//if (key == ‘b’) {
// new_rand = random(255);
//}
}
else {
if (mousePressed) {
fill(random(255),random(255),random(255));
}
R_angle1 = (mouseX/float(width) – 0.5) * -PI;
R_angle2 = (mouseY/float(height) – 0.5) * PI;

L_angle1 = PI + (mouseX/float(width) – 0.5) * -PI;
L_angle2 = (mouseY/float(height) – 0.5) * PI;

draw_man();
}

}

void segment(float x, float y, float a, float segLength) {
translate(x, y);
rotate(a);
line(0, 0, segLength, 0);
}

void draw_man() {

rect(L_x,L_y,bodywidth,bodyheight);
ellipse(L_x + bodywidth/2, L_y-bodywidth/2,bodywidth/3,bodywidth/2);
pushMatrix();
segment(R_x, R_y, R_angle1, segLength_arm);
segment(segLength_arm, 0, R_angle2, segLength_arm);
popMatrix();

pushMatrix();
segment(L_x, L_y, L_angle1, segLength_arm);
segment(segLength_arm, 0, L_angle2, segLength_arm);
popMatrix();
}

sketches

I wanted to create a watercolor-esque feeling, something very sketchy, and white, and bright. I don’t actually think I am super happy with the direction that I have gone with it, but it is at least aesthetically appealing (to me) While working on it I came up with maybe two or three other concepts that I want to explore. So that is good at least.

The applet is here (with source): http://patrickgagekelley.com/gobbledigook/applet/

Screen captures here: on Flickr

Design a site like this with WordPress.com
Get started