MAJ: Looking Outwards #5

Admiration: Pinokio


Pinokio, created by Shanshan Zhou, Adam Ben-Dror, and Joss Dogget, is an animatronic lamp that responds to faces and sounds. It has various behaviors, the most amusing of which is its ability to prevent itself from being turned off. Processing, Arduino, and OpenCV were used to make Pinokio.

I’m immediately reminded of Luxo Jr., Pixar’s lamp mascot. From a technical standpoint, I’d be interested to see how Pinokio‘s joints are modified from those of the typical lamp, as Pinokio appears to be capable of relatively fast (although relatively noisy) movement. I’d also be interested to see how Pinokio‘s observed behaviors are expressed in its programming.

For more about Shanshan Zhou, click here. For more about Adam Ben-Dror, click here. For more about Joss Dogget, click here.

Surprise: Tropism Well

Tropism Well, made by creative studio Harvey & John, is an interactive sculpture that pours drinks. Through a combination of an Arduino Mega and a ultrasonic sensor, Tropism Well is able to sense one’s presence and “bow” toward them. The weight of the liquid is used to create the bowing motion.

I’m particularly fond of the graceful motion Tropism Well is capable of. Although the bowing motion is simple, it is well executed and gives this robotic sculpture a feeling of life. I also like Tropism Well‘s elegant design, which is somewhat reminiscent of a fancy piece of furniture.

For more about Tropism Well, click here. For more about For more about Harvey & John, click here.

What Could Have Been: Daily Stack

Daily Stack, created by Sebastian Rønde Thielke and Anders Højmos, is a stack of wooden blocks placed on a base that interfaces with one’s computer to create visualizations of time commitments. There are three types and sizes of block, each which represent a kind of time commitment (work, break, and procrastination), and a time-span (60 minutes, 30 minutes, and 15 minutes.).

While I think that visualizing one’s time is a worthwhile idea, Daily Stack seems a bit contrived. The overall atheistic is charming, however I can’t help but think how easy it would be accidentally knock the blocks over.

For more about Sebastian Rønde Thielke, click here. For more about Anders Højmos, click here.

 

Ghosts (1000 lines)

For this part of the assignment I wanted to use for loops to make a complex, ghastly shape to be placed in a dark background. In some ways I find it successful, but I would like to get the movement a little more “floaty” than it currently is.

 


##Will Taylor
## Ghosts (1000 Liner)
width, height = 800,800
radius = 100
circleXY = [[int(random(width)), int(random(height))],
[int(random(width)), int(random(height))],
[int(random(width)), int(random(height))],
[int(random(width)), int(random(height))],
[int(random(width)), int(random(height))],
[int(random(width)), int(random(height))],
[int(random(width)), int(random(height))],
[int(random(width)), int(random(height))],
[int(random(width)), int(random(height))],
[int(random(width)), int(random(height))]]
def setup():
background(255,200)
size(width,height)
frameRate(24)

def draw():
background(0,10)
fill(0,120);
rect(0,0,width,height);
smooth()
strokeWeight(1)
stroke(0)


def checkMatch():
for i in xrange(len(circleXY)):
x = circleXY[i][0]
y = circleXY[i][1]
if (x == mouseX and y == mouseY):
background(0)
return True


def drawCircles():
rad = radius
for i in xrange(0, len(circleXY)):
stroke(2)
fill(255,10)
for x in xrange(len(circleXY) - i):
if x%2 == 0:
ellipse(circleXY[i][0], circleXY[i][1], rad-4*x, rad+4*x)
ellipse(circleXY[i][0], circleXY[i][1], rad+4*(x+1), rad-4*(x+1))
else:
ellipse(circleXY[i][0], circleXY[i][1], rad+4*x, rad-4*x)
ellipse(circleXY[i][0], circleXY[i][1], rad-4*(x+1), rad+4*(x+1))








def updateCircleX():
for i in xrange(len(circleXY)):
if (circleXY[i][0] > mouseX):
circleXY[i][0] -= int(2*(i+1)%4 + (i+1))
elif (circleXY[i][0] < mouseX):
circleXY[i][0] += int(2*(i+2)%4 + (i+1))

def updateCircleY():
vChase = 1
for i in xrange(len(circleXY)):
if (circleXY[i][1] > mouseY):
circleXY[i][1] -= int(2*(i+1) - i)
elif (circleXY[i][1] < mouseY):
circleXY[i][1] += int(2*(i+1) - i)

def updateCircles():
updateCircleX()
updateCircleY()

drawCircles()

updateCircles()
checkMatch()

 

A Good ‘Ol Fashioned Rumble! (Ten Liner)

Uh oh, looks like there’s a rumble! Use your cursor to either flee the scene, or stay and fight. When the circles get closer together, the screen flashes to give the effect of punches being thrown. The biggest challenge I faced for this assignment was getting each circle to move at a different rate. The method I ended up using allows the speed of a circle to be faster if it was drawn towards the end of the for loop.

 

##Will Taylor
## A Good 'Ol Fashioned Rumble (Ten Liner)
width, height = 400,400
radius = 10
circleXY = [[int(random(width)), int(random(height))],
[int(random(width)), int(random(height))],
[int(random(width)), int(random(height))],
[int(random(width)), int(random(height))],
[int(random(width)), int(random(height))],
[int(random(width)), int(random(height))],
[int(random(width)), int(random(height))],
[int(random(width)), int(random(height))],
[int(random(width)), int(random(height))],
[int(random(width)), int(random(height))]]
def setup():
size(width,height)
frameRate(32)

def draw():
background(255)
smooth()
strokeWeight(2)
stroke(0)


def checkMatch():
for i in xrange(len(circleXY)):
x = circleXY[i][0]
y = circleXY[i][1]
if (x == mouseX and y == mouseY):
background(0)
return True


def drawCircles():
rad = radius
for i in xrange(len(circleXY)):
if (i > len(circleXY)/2):
stroke(0)
fill(255)
else:
stroke(150)
fill(0)
ellipse(circleXY[i][0], circleXY[i][1], rad, rad);


def updateCircleX():
for i in xrange(len(circleXY)):
if (circleXY[i][0] > mouseX):
circleXY[i][0] -= int(2*(i+1)%4 + (i+1))
elif (circleXY[i][0] < mouseX):
circleXY[i][0] += int((i+2)%4 + (i+1))

def updateCircleY():
vChase = 1
for i in xrange(len(circleXY)):
if (circleXY[i][1] > mouseY):
circleXY[i][1] -= int(2*(i+1) - i)
elif (circleXY[i][1] < mouseY):
circleXY[i][1] += int(2*(i+1) - i)

def updateCircles():
updateCircleX()
updateCircleY()

drawCircles()

updateCircles()
checkMatch()

 

Lights Out (one liner)

Have you ever had the feeling that someone is following you? Well in this situation, you’d be correct. In the distance, you see a curtain that appears to be floating in midair flying towards you! Don’t let it catch you, or you won’t be able to see where you’re going. The curtain is relentless. Don’t look away, or you might find yourself in darkness!

 

//Lights out
// If the circle catches your cursor, it will turn out the lights

float buttonX = width/2;
float buttonY = height/2;

void setup(){
size(400,400);
background(255);
frameRate(140);
smooth();

}

void draw(){
float vChase = 1;
float rad = 10;
background(255,10);

stroke(0);
ellipse(buttonX, buttonY, rad, rad);

if(buttonX == mouseX && buttonY == mouseY){

background(0);
println("done");
}

if (buttonX > mouseX){
buttonX -= vChase;
println("minus X");
}

if (buttonX < mouseX){
buttonX += vChase;
println("plus X");

}

if (buttonY > mouseY){
buttonY -= vChase;
println("minus Y");
}

if (buttonY < mouseY){
buttonY += vChase;
println("plus Y");

}

}

BROCCOLI FAAAACE

i like broccoli
this amuses me

 
  import oscP5.*;
  OscP5 oscP5;
  
  // num faces found
  int found;
  
  // pose
  float poseScale;
  PVector posePosition = new PVector();
  PVector poseOrientation = new PVector();
  
  // gesture
  float mouthHeight;
  float mouthWidth;
  float eyeLeft;
  float eyeRight;
  float eyebrowLeft;
  float eyebrowRight;
  float jaw;
  float nostrils;
  
  void setup() {
    size(640, 480);
    frameRate(30);
  
    oscP5 = new OscP5(this, 8338);
    oscP5.plug(this, "found", "/found");
    oscP5.plug(this, "poseScale", "/pose/scale");
    oscP5.plug(this, "posePosition", "/pose/position");
    oscP5.plug(this, "poseOrientation", "/pose/orientation");
    oscP5.plug(this, "mouthWidthReceived", "/gesture/mouth/width");
    oscP5.plug(this, "mouthHeightReceived", "/gesture/mouth/height");
    oscP5.plug(this, "eyeLeftReceived", "/gesture/eye/left");
    oscP5.plug(this, "eyeRightReceived", "/gesture/eye/right");
    oscP5.plug(this, "eyebrowLeftReceived", "/gesture/eyebrow/left");
    oscP5.plug(this, "eyebrowRightReceived", "/gesture/eyebrow/right");
    oscP5.plug(this, "jawReceived", "/gesture/jaw");
    oscP5.plug(this, "nostrilsReceived", "/gesture/nostrils");
  }
  
  void draw() {  
    background(255);
    stroke(0);
  
    if (found > 0) {
      translate(posePosition.x, posePosition.y);
      scale(poseScale);
      noFill();
      PImage broccoli;
      broccoli= loadImage("broccoli .png");
      image(broccoli, mouthWidth-60, eyebrowLeft-mouthHeight-60, 100, 100);
      fill(255);
      strokeWeight(0);
      ellipse(-20, eyeLeft * -9, 10, 10);
      ellipse(20, eyeRight * -9, 10, 10);
     fill (50,205,50);
     ellipse(-20, eyeLeft * -9, 7, 7);
      ellipse(20, eyeRight * -9, 7, 7);
      fill(0);
      ellipse(-20, eyeLeft * -9, 3, 3);
      ellipse(20, eyeRight * -9, 3, 3);
    
       PImage leftBrow;
       leftBrow= loadImage ("Left.png");
       image(leftBrow, -30, eyebrowLeft * -6, 25,5);
       
       PImage rightBrow;
       rightBrow= loadImage ("Right .png");
       image (rightBrow, 15, eyebrowRight * -6, 25, 5);
       
       PImage Mouth;
       Mouth= loadImage ("Mouth.png");
       image (Mouth,-15,15, mouthWidth*3, mouthHeight *3);

   }
  }
  
  // OSC CALLBACK FUNCTIONS
  
  public void found(int i) {
    println("found: " + i);
    found = i;
  }
  
  public void poseScale(float s) {
    println("scale: " + s);
    poseScale = s;
  }
  
  public void posePosition(float x, float y) {
    println("pose position\tX: " + x + " Y: " + y );
    posePosition.set(x, y, 0);
  }
  
  public void poseOrientation(float x, float y, float z) {
    println("pose orientation\tX: " + x + " Y: " + y + " Z: " + z);
    poseOrientation.set(x, y, z);
  }
  
  public void mouthWidthReceived(float w) {
    println("mouth Width: " + w);
    mouthWidth = w;
  }
  
  public void mouthHeightReceived(float h) {
    println("mouth height: " + h);
    mouthHeight = h;
  }
  
  public void eyeLeftReceived(float f) {
    println("eye left: " + f);
    eyeLeft = f;
  }
  
  public void eyeRightReceived(float f) {
    println("eye right: " + f);
    eyeRight = f;
  }
  
  public void eyebrowLeftReceived(float f) {
    println("eyebrow left: " + f);
    eyebrowLeft = f;
  }
  
  public void eyebrowRightReceived(float f) {
    println("eyebrow right: " + f);
    eyebrowRight = f;
  }
  
  public void jawReceived(float f) {
    println("jaw: " + f);
    jaw = f;
  }
  
  public void nostrilsReceived(float f) {
    println("nostrils: " + f);
    nostrils = f;
  }
  
 
  void oscEvent(OscMessage m) {
  
   
    println("#received an osc message");
    println("Complete message: "+m);
    println(" addrpattern: "+m.addrPattern());
    println(" typetag: "+m.typetag());
    println(" arguments: "+m.arguments()[0].toString());
  
    if (m.isPlugged() == false) {
      println("UNPLUGGED: " + m);
    }
  }

Sin clock

Clock sketch

I made a clock where each division of time is one half period of a sin wave. From top to bottom there are milliseconds, seconds, minutes, and hours. I made it smoothly transition by fractional parts of a second. Originally I was going to modulate all of them together, but the time was not decipherable from the resulting wave.

Dandilion (10 lines)

mbk-10lines

For this project I wanted to make a flower blow in the wind. I wanted the mouse to blow the seeds off of the flower, and then have them wrap around the border and land back onto the flower. This turned out to be a bit more challenging than I had originally thought.

10-lines-sketch

FaceOSC – Babel

Screen Shot 2014-10-06 at 17.19.40 Screen Shot 2014-10-06 at 17.19.49

 

word vomit.

this began as a concept where moving elements of your face would cause marks of this motion to appear, without actually showing your face back. This eventual evolved into leaving falling characters in this style. In the end, It seemed more natural to have words pouring from your mouth. The face I used is heavily inspired by my previous face projects. I enjoy serious faces that wobble.

IMG_1008

the face’s primary control is how open the mouth is, which dictates rate of word pour, thickness of lines, and amour of wobble. the rest of the facial properties are used to handle the rendering of the face in 3D space.

The last part of this may or may not be lines from Blue Swede’s Hooked on a Feeling.

import oscP5.*;
OscP5 oscP5;

//class that handles the falling letters
class Letter {
  char c;
  int x;
  int y;
  float scale;
  float speed;
  
  Letter(char tempc, int tempx, int tempy, float tempscale){
    c = tempc;
    x = tempx;
    y = tempy;
    scale = tempscale;
    speed = 0.0;
  }
  
  void update(){
    speed = speed + 0.5;
    y += int(speed*scale);
  }
  
  void display(){
    textSize(25*scale);
    fill(map(mouthHeight,0,7,100,0));
    text(c,x,y,0);
  }
  
  Boolean finished(){
    return y >= height + 20;
  }
} 

String words;
int textLen;
int textInd;
int spaceInd;

ArrayList<Letter> letters;

// num faces found
int found;

// pose
float poseScale;
PVector posePosition = new PVector();
PVector poseOrientation = new PVector();

// gesture
float mouthHeight;
float mouthWidth;
float eyeLeft;
float eyeRight;
float eyebrowLeft;
float eyebrowRight;
float jaw;
float nostrils;

void setup() {
  textMode(SHAPE);
  size(640, 480, OPENGL);
  frameRate(30);
  
  //chars are selected in order from this text. Lorem Ipsum
  //because I am too lazy
  words="Lorem ipsum dolor sit amet, consectetur adipisicing elit," 
       +" sed do eiusmod tempor incididunt ut labore et dolore "
       +"magna aliqua. Ut enim ad minim veniam, quis nostrud "
       +"exercitation ullamco laboris nisi ut aliquip ex ea commodo"
       +" consequat. Duis aute irure dolor in reprehenderit in "
       +"voluptate velit esse cillum dolore eu fugiat nulla "
       +"pariatur. Excepteur sint occaecat cupidatat non proident, "
       +"sunt in culpa qui officia deserunt mollit anim id est "
       +"laborum.";
  textLen = words.length();
  textInd = 0;
  spaceInd = 0;
  
  letters = new ArrayList<Letter>();

  oscP5 = new OscP5(this, 8338);
  oscP5.plug(this, "found", "/found");
  oscP5.plug(this, "poseScale", "/pose/scale");
  oscP5.plug(this, "posePosition", "/pose/position");
  oscP5.plug(this, "poseOrientation", "/pose/orientation");
  oscP5.plug(this, "mouthWidthReceived", "/gesture/mouth/width");
  oscP5.plug(this, "mouthHeightReceived", "/gesture/mouth/height");
  oscP5.plug(this, "eyeLeftReceived", "/gesture/eye/left");
  oscP5.plug(this, "eyeRightReceived", "/gesture/eye/right");
  oscP5.plug(this, "eyebrowLeftReceived", "/gesture/eyebrow/left");
  oscP5.plug(this, "eyebrowRightReceived", "/gesture/eyebrow/right");
  oscP5.plug(this, "jawReceived", "/gesture/jaw");
  oscP5.plug(this, "nostrilsReceived", "/gesture/nostrils");
}

void draw() {  
  //face drawing
  background(255);
  stroke(0);
  float nscale = poseScale/3.0;
  noFill();
  pushMatrix(); 
  translate (posePosition.x, posePosition.y, 0);
  scale(nscale);
  rotateY (0 - poseOrientation.y); 
  rotateX (0 - poseOrientation.x); 
  rotateZ (    poseOrientation.z); 
  int r1 = int(random(-1*mouthHeight, mouthHeight)/1.4);
  int r2 = int(random(-1*mouthHeight, mouthHeight)/1.4);
  int r3 = int(random(-1*mouthHeight, mouthHeight)/1.4);
  line(-40 + r1, eyeLeft * -9, -5, -10 + r1, eyeLeft * -9,0);
  line(40 + r1, eyeRight * -9, -5, 10 + r1, eyeRight * -9,0);
  line(-50 + r2, eyebrowLeft * -5, -5, -8 + r2, eyebrowLeft * -5,0);
  line(50 + r2, eyebrowRight * -5, -5, 8 + r2, eyebrowRight * -5,0);
  line(-5 + r3,nostrils * 1,0,5 + r3,nostrils*1,0);
  strokeWeight(mouthHeight);
  line(-mouthWidth + r3,45,0,mouthWidth + r3,45,0);
  
  popMatrix();
  println("mWidth: " + mouthWidth + ", mHeight: " + mouthHeight);

  //generates new falling letters
  for(int i = 0; i < int(mouthHeight/1.4); i++){
    if (spaceInd % 2 == 0){
      letters.add(new Letter(words.charAt(textInd),
                  int(posePosition.x + random(-2*mouthWidth - mouthHeight,
                                               2*mouthWidth + mouthHeight)),
                  int(posePosition.y + 65), nscale));
      textInd = (textInd + 1) % textLen;
    }
    spaceInd++;
  }
    
  //updates and displays letters  
  for (int i = letters.size()-1; i >= 0; i--) {
    Letter letter = letters.get(i);
    letter.update();
    letter.display();
    if (letter.finished()) {
      letters.remove(i);
    }
  }
}

// OSC CALLBACK FUNCTIONS

public void found(int i) {
  println("found: " + i);
  found = i;
}

public void poseScale(float s) {
  println("scale: " + s);
  poseScale = s;
}

public void posePosition(float x, float y) {
  println("pose position\tX: " + x + " Y: " + y );
  posePosition.set(x, y, 0);
}

public void poseOrientation(float x, float y, float z) {
  println("pose orientation\tX: " + x + " Y: " + y + " Z: " + z);
  poseOrientation.set(x, y, z);
}

public void mouthWidthReceived(float w) {
  println("mouth Width: " + w);
  mouthWidth = w;
}

public void mouthHeightReceived(float h) {
  println("mouth height: " + h);
  mouthHeight = h;
}

public void eyeLeftReceived(float f) {
  println("eye left: " + f);
  eyeLeft = f;
}

public void eyeRightReceived(float f) {
  println("eye right: " + f);
  eyeRight = f;
}

public void eyebrowLeftReceived(float f) {
  println("eyebrow left: " + f);
  eyebrowLeft = f;
}

public void eyebrowRightReceived(float f) {
  println("eyebrow right: " + f);
  eyebrowRight = f;
}

public void jawReceived(float f) {
  println("jaw: " + f);
  jaw = f;
}

public void nostrilsReceived(float f) {
  println("nostrils: " + f);
  nostrils = f;
}

// all other OSC messages end up here
void oscEvent(OscMessage m) {
  
  /* print the address pattern and the typetag of the received OscMessage */
  println("#received an osc message");
  println("Complete message: "+m);
  println(" addrpattern: "+m.addrPattern());
  println(" typetag: "+m.typetag());
  println(" arguments: "+m.arguments()[0].toString());
  
  if(m.isPlugged() == false) {
    println("UNPLUGGED: " + m);
  }
}