Nature of Code Midterm Documentation

Nature of Code Mid Term Documentation from Colin Narver on Vimeo.

For my midterm, I was inspired by Andy Warhol's "Floating Silver Pillows" from the "Regarding Warhol: Sixty Artists, Fifty Years" show at the Met. Using the Toxiclibs library, I created an array list of silver ballon like shapes that I made in illustrator as well as a hand object to hit them. I wanted to recreate the joy children have in knocking around balloons in a small room.

I then incorporated an attraction behavior to the elements and used a system of checking if a balloon has been hit and then marking it with a number. This was based on the ability to determine the distance between my hand object and the ballons. Then, If the marked number exceeds my pre-determined threshold for hits, a negative force is imposed upon the balloon and it appears to loose helium or it's ability to float.

I was inspired and enabled by the Nature of Code examples on attract/repel as well as the mechanics of the simple spring (both utilizing the toxiclibs library).

 

//ballons svg files with a bit of rotation 
//checking to see if another particle is hit would be built in the main program

import toxi.geom.*;
import toxi.physics2d.*;
import toxi.physics2d.behaviors.*;

ArrayList<Particle> particles;

VerletPhysics2D physics;

Particle p1;
Particle p2;

PImage balloon;
PImage background;
PImage hand;

void setup () {
  size (850, 700, P2D);

  balloon = loadImage("silver_pillows.png");
  background = loadImage("warhol_cow.jpeg");
  hand =loadImage("hand.png");
  smooth();

  physics = new VerletPhysics2D ();
  physics.setDrag (0.01);

  particles = new ArrayList<Particle>();
  for (int i = 0; i < 80; i++) {
    particles.add(new Particle(balloon, new Vec2D(random(width), random(height)), -32, -1, 120, 80));
  }

  //physics.addBehavior(new GravityBehavior(new Vec2D(0, -0.05)));
  physics.setWorldBounds(new Rect(0, 0, width, height));

  // Make two particles
  p1 = new Particle(hand, new Vec2D(width/2, height/2.5), 32, -1, 20, 30);
  p2 = new Particle(hand, new Vec2D(width, 180), 32, -10, 70, 100);
  // Lock one in place
  p1.lock();

  // Make a spring connecting both Particles
  VerletSpring2D spring=new VerletSpring2D(p1, p2, 100, 0.005);

  // Anything we make, we have to add into the physics world
  physics.addParticle(p1);
  physics.addParticle(p2);
  physics.addSpring(spring);
}

void draw () {
  background (255); 
  tint (255); 
  imageMode (CORNER);  
  image(background, 0, 0);

  physics.update ();

  // Draw a line between the particles
  stroke(0);
  strokeWeight(2);
  line(p1.x, p1.y, p2.x, p2.y);

  // Display the particles
  p1.display();
  p2.display();

  // Move the second one according to the mouse
  if (mousePressed) {
    p2.lock();
    p2.x = mouseX;
    p2.y = mouseY;
    p2.unlock();
  } 

  for (Particle p: particles) {
    p.display();
    p.checkEdges();
    //p.checkIfHit (p1.x, p1.y, 30); 
    p.checkIfHit (p2.x, p2.y, 35);
//    p.oscillate();
    p.markHits(); 

    }
  }

//spring or sin wave---give it a slight force from being applied by 
//call it in the par

// class Spore extends the class "VerletParticle2D"
class Particle extends VerletParticle2D {

  // variable for helium level, affect the brightness
  //need to apply a force to each on pushing them down
  //checking the hitter particle against the others 

  float theta = 0.0;
  PImage balloon;
  int howManyTimesHit = 0; 
  int widthS;
  int heightS;
  int angle;

  boolean isHit = false;

  Particle (PImage _balloon, Vec2D loc, float len, float strength, int _widthS, int _heightS) {
    super(loc);    //has to be first in order
    balloon = _balloon;
    widthS= _widthS;
    heightS = _heightS;
    physics.addParticle(this);
    physics.addBehavior(new AttractionBehavior(this, len, strength));  //variables for behavior elements
  }

  void display () {
    stroke (0);
    strokeWeight(2);

    imageMode (CENTER); 
    tint (255); 
    image(balloon, x, y, widthS, heightS);
  }

  void checkEdges() {
    if (x> width) {
      x=0;
    } 
    else if (x< 0) {
      x=width;
    }

    if (y> height) {
      y=0;
    } 
    else if (y<0) {
      y=height;
    }
  }

//incorporate oscillation here:
//  void oscillate() {
//    
// float a = map(cos(theta), -1.0, 1.0, -.05,.001);
//// float z = map(sin(theta), -1.0, 1.0, 0,-1.1);
//     theta += 0.002;
//     Vec2D osc = new Vec2D(a,random(-.01,.01));
//      addForce(osc); 
//    
//  }

  void checkIfHit (float handX, float handY, int handRad) {
    float d =  dist (x, y, handX, handY);
//    println(d + " " + isHit);
    float threshold = 30 + handRad;
    if (!isHit &&  d < threshold ) { 
      howManyTimesHit++;
      isHit = true;
    } 
    else if (d > threshold) {
      isHit = false;
    }
  }

  void markHits () {

    fill(255, 244, 0);
    textSize(30);
    text(howManyTimesHit, x, y); 

    float helium = map(howManyTimesHit,0,20,-0.05,0.05);

      Vec2D down = new Vec2D(0,helium);
      addForce(down);

  }
}