Tools.
Processing, Illustrator, After Effects
Concept.
Nancy Wu, Lily Kim, Tina Huamin, and Kai Watanabe collaborated to create a drawing software code in Processing then drew frame by frame to create this rotoscope.  

Code created for this drawing software in Processing:
//import codeanticode.tablet.*;
//Tablet tablet;
int sw = 5;
float x;
float y;
float m;
float n;
int i=0;
int a=0;
float opa = 255;
float speed; 
PImage selector;
PImage swopa;
int sx = 1240;
int sy = 6;
color scolor;

String videoPrefix = "footage-";
int totalFrames = 167;
PImage videoFrame;
String drawingPrefix = "animation-";
PImage drawing;
int currentFrame = 0;
boolean toggledraw=true;
boolean showVideo = true;
boolean line = true;
boolean dots = false;
boolean scratch = false;
boolean multiline = false;
boolean bubble = false;
boolean showInterface = true;
boolean overlay =false;
boolean speedbrush;

PGraphics d;  // Drawing layer
//pGraphics d1; //overlay layer
void setup() {
  size(1280, 720);
  //tablet = new Tablet(this); 
  d = createGraphics(width, height);
  //d1 = createGraphics(width, height);
  loadFrame();
  loadDrawing();
  selector = loadImage("colors.png");
  swopa = loadImage("swopa.png");
  scolor = color(0, 0, 0);
}
void draw() {
  background(153);
  sw=5+a*2;
  opa=255+25.5*(-i);
  x = random(-10, 10);
  y =random (-20, 20);
  m= random (1, 3);
  n= random (1, 2);
  if (showVideo) {
    image(videoFrame, 0, 0, width, height);
  }
  if (overlay) {
    d.blendMode(ADD);
  } else {
    d.blendMode(BLEND);
  }
  if (toggledraw) {
    if (mousePressed) {
      if (line) {
        d.beginDraw();
        //d.strokeWeight(30 * tablet.getPressure());
        d.strokeWeight(sw);
        d.stroke(scolor, opa);
        d.line(mouseX, mouseY, pmouseX, pmouseY);  
        d.endDraw();
      }
      if (dots) {
        d.beginDraw();
        d.noStroke();
        d.fill(scolor, opa);
        float rx1 = random(-3*sw, 3*sw);
        float ry1 = random(-3*sw, 3*sw);
        float rx2 = random(-5*sw, 5*sw);
        float ry2 = random(-5*sw, 5*sw);
        d.ellipse(mouseX+rx1, mouseY+ry1, sw, sw);
        d.ellipse(mouseX+rx2, mouseY+ry2, sw/1.5, sw/1.5);
        d.endDraw();
      }
      if (scratch) {
        d.beginDraw();
        d.stroke(scolor, opa);
        d.strokeWeight(sw);
        d.line(mouseX+m*x, mouseY+n*y, mouseX-y, mouseY-x);
        d.line(mouseX-n*x, mouseY+m*y, mouseX+y, mouseY-x);
        d.line(mouseX-m*y, mouseY+n*x, mouseX+x, mouseY-y);
        d.line(mouseX+n*y, mouseY+m*x, mouseX-x, mouseY-y);
        d.line(mouseX+m*x, mouseY+n*y, mouseX-y, mouseY-x);
        d.line(mouseX-n*x, mouseY+m*y, mouseX+y, mouseY-x);
        d.line(mouseX-m*y, mouseY+n*x, mouseX+x, mouseY-y);
        d.line(mouseX+n*y, mouseY+m*x, mouseX-x, mouseY-y);
        d.endDraw();
      }
      if (multiline) {
        d.beginDraw();
        //d.strokeWeight(30 * tablet.getPressure());
        d.strokeWeight(sw);
        d.stroke(scolor, opa);
        d.line(mouseX, mouseY, pmouseX, pmouseY);  
        d.line(mouseX+5, mouseY+10, pmouseX+5, pmouseY+10); 
        d.line(mouseX-5, mouseY-10, pmouseX-5, pmouseY-10);
        d.line(mouseX-2.5, mouseY-5, pmouseX-2.5, pmouseY-5);
        d.line(mouseX+2.5, mouseY+5, pmouseX+2.5, pmouseY+5);
        d.endDraw();
      }
      if (bubble) {
        d.beginDraw();
        d.stroke(scolor, opa);
        d.strokeWeight(1);
        d.noFill();
        float rx1 = random(-3*sw, 3*sw);
        float ry1 = random(-3*sw, 3*sw);
        float rx2 = random(-5*sw, 5*sw);
        float ry2 = random(-5*sw, 5*sw);
        d.ellipse(mouseX+rx1, mouseY+ry1, sw, sw);
        d.ellipse(mouseX+rx2, mouseY+ry2, sw/1.5, sw/1.5);
        d.endDraw();
      }
       if (speedbrush) {
      d.beginDraw();
      d.noFill();
      float mouseSpeed= abs(mouseX-pmouseX)+abs(mouseY-pmouseY);
      d.stroke(scolor, opa);
      
      float targetSpeed = mouseSpeed* sw * 0.1;
      float easing = 0.1;
      speed += (targetSpeed - speed) * easing;
      
      d.strokeWeight(speed);
      d.line(pmouseX, pmouseY, mouseX, mouseY);
      d.endDraw();
    }
    }
  }
  image(d, 0, 0, width, height);

  //println(sw);
  if (showInterface) {
    push();
    textSize(12);
    //text("Strokeweight",20,70);
    //text("Opacity",20,40);
    fill(255, 100);
    noStroke();
    rect(5, 15, 160, 70, 10);
    fill(0);
    text(opa/2.55, 105, 40);
    text(sw, 110, 70);
    image(swopa, 0, 0);
    image(selector, sx, sy);
    pop();
  }
}
void keyPressed() {
  if (key == ' ' ) {
    showVideo = !showVideo;
  }
  if (key=='1') {
    line=true;
    dots=false;
    scratch =false;
    multiline = false;
    bubble = false;
    speedbrush = false;
    //checkBrushes();
  }
  if (key=='2') {
    dots=true;
    line=false;
    scratch =false;
    multiline = false;
    bubble = false;
    speedbrush = false;
    //checkBrushes();
  }
  if (key=='3') {
    scratch =true;
    dots=false;
    line=false;
    multiline = false;
    bubble = false;
    speedbrush = false;
    //checkBrushes();
  }
  if (key=='4') {
    multiline = true;
    scratch =false;
    dots=false;
    line=false;
    bubble = false;
    speedbrush = false;
  }
  if (key=='5') {
    bubble = true;
    multiline = false;
    scratch =false;
    dots=false;
    line=false;
    speedbrush = false;
  }
   if (key=='6') {
    speedbrush = true;
    bubble = false;
    multiline = false;
    scratch =false;
    dots=false;
    line=false;
  }
  if (key=='o' || key == 'O') {
    overlay=!overlay;
  }
  //  if (key=='n'){
  //}

  if (key == 'z' ) {
    d.beginDraw();
    d.clear();
    d.endDraw();
  }
  if (key == 's') {
    showInterface =!showInterface;
  }
  if (key == ']') {
    a++;
    //sw=5+a*2;
  }
  if (key == '[') {
    //sw=5+a*2;
    if (sw==1) {
      sw=1;
    } else {
      a--;
    }
  }
  if (key=='t') {
    if (toggledraw==true) {
      toggledraw=false;
    } else {
      toggledraw=true;
    }
  }
  if (key == CODED) {
    if (keyCode == LEFT) {  // Left arrow key
      saveAnimationFrame();
      currentFrame--;
      if (currentFrame < 0) {
        currentFrame = totalFrames - 1;
      }
      loadFrame();
      loadDrawing();
    } else if (keyCode == RIGHT) {  // Right arrow key
      saveAnimationFrame();
      currentFrame++;
      if (currentFrame >= totalFrames) {
        currentFrame = 0;
      }
      loadFrame();
      loadDrawing();
    }
    if (keyCode == UP) {
      if (i==0) {
        i=0;
      } else {
        i--;
      }
    } else if (keyCode == DOWN) {
      if (i==9) {
        i=9;
      } else {
        i++;
      }
    }
  }
}
void mousePressed() {
  if (overSelector()) {
    toggledraw=false;
    scolor = selector.get(mouseX-sx, mouseY-sy);
  } else {
    toggledraw=true;
  }
}
//void checkBrushes(){
//  if(line==true){
//    dots=false;
//  }
//  else if(dots==true){
//    line=false;
//  }
//}
void saveAnimationFrame() {
  d.save("frames/" + drawingPrefix + nf(currentFrame, 4) + ".png");
  // Clear the drawing layer
  d.beginDraw();
  d.clear();
  d.endDraw();
}
void loadFrame() {
  String filename = videoPrefix + nf(currentFrame, 4) + ".png";
  videoFrame = loadImage(filename);
  println(currentFrame + " / " + (totalFrames-1));
}
void loadDrawing() {
  try {
    String filename = drawingPrefix + nf(currentFrame, 4) + ".png";
    drawing = loadImage("frames/" + filename);
    d.beginDraw();
    d.image(drawing, 0, 0, width, height);
    d.endDraw();
  } 
  catch (Exception e) {
    println("Computer says 'No!' " + e);
  }
}
boolean overSelector() {
  if (mouseX > sx && mouseX < sx+selector.width && 
    mouseY > sy && mouseY < sy+selector.height) {
    return true;
  } else {
    return false;
  }
}

You may also like

Back to Top