Joshua

29 Jan 2013

textRain_screenShot_JLB

To implement text rain I created a class called Letter which contains a position, velocity, char, and some functions to move the letter and check if it is sitting on dark pixels.  To move the letters up I check another pixel above the first, and if it is also dark enough, the letter moves up to that position.  After changing the video to grey scale I simply check the red values (r,g, and b are now all the same) and if they are below a threshold, which i determined experimentally, they cause the letter to stop moving downward, or even move upward.

https://github.com/jlopezbi/textRainImplementation

 

 

import processing.video.*;
Capture video;
int[] backgroundPixels;
int numPixels;
int numLetters = 300;
float threshold = 31;
ArrayList rain;

void setup() {
  size(600, 450, P2D);
  smooth();
  video = new Capture(this, 160, 120);
  video.start();
  numPixels = video.width * video.height;
  backgroundPixels = new int[numPixels];
  loadPixels();

  rain = new ArrayList();
  for (int i = 0; i< numLetters;i++) {
    genRandLtr();
  }
}

void draw() {
  if (video.available()) {
    video.read();
    video.filter(GRAY);
    image(video, 0, 0, width, height);

  }
  loadPixels();
  for (int i =0;i<rain.size()-1;i++) {
    Letter l = (Letter) rain.get(i);
    l.updatePos();
    l.display();
    if (l.finished()) {
      rain.remove(i);
      genRandLtr();
    }
  }
  color pix = pixels[mouseY*width+mouseX];
  println(red(pix) +" "+ green(pix)+" "+ blue(pix));
  updatePixels();
}

void genRandLtr() {
  PVector pos = new PVector(random(0, width), 30);
  PVector vel = new PVector(0, random(0.5, 1));

  int lowerUpper = (int)random(2);
  int ascii;
  if (lowerUpper == 0) {
    ascii = (int) random(65, 90.1);
  }
  else {
    ascii = (int) random(97, 122.1);
  }

  char ltr = char(ascii);
  Letter letter = new Letter(pos, vel, ltr);
  rain.add(letter);
}

class Letter {
  //GLOBAL VARIABLES
  PVector pos;
  PVector vel;
  char ltr;
  int aboveCheck = 4;
  //CONTRUCTOR
  Letter(PVector _pos, PVector _vel, char _ltr){
    pos = _pos;
    vel = _vel;
    ltr = _ltr;

  }

  //FUNCTIONS
  void display(){
    textAlign(CENTER,BOTTOM);
    text(ltr, pos.x,pos.y);
    noFill();
    //ellipse(pos.x,pos.y,5,5);
  }

  void setRandPos(){
    pos = new PVector(random(0,width), 0);
  }

  void updatePos(){
    float xPos = pos.x;
    float yPos = pos.y;
    int indexAhead = int(xPos)+int(yPos)*width;
    int indexAbove = int(xPos)+int(yPos-aboveCheck)*width;
    float aheadCol = red(pixels[indexAhead]);
    float aboveCol = red(pixels[indexAbove]);
    if(aheadCol>threshold){
      pos.set(xPos+vel.x, yPos+vel.y,0);
    } 
    else if(aboveCol<=threshold){      
       pos.set(xPos, yPos-aboveCheck,0);     
     }        
}      

boolean finished(){     
   return(pos.y>=height-1 || pos.y<=aboveCheck);
  }  
}