Project 10: Creature

For a while I had this image of a fat, fleshy creature sitting in a box, going about his business, possibly living in another dimension or world.  (The sandwich he is eating is invisible because it exists in a virtual non-space). In this project, I wanted to give the sense of invading someone else’s living space.  I wanted to create a little bit of humor that refers to this kind of aesthetic in my drawing through the movements of this creature that make it seem alive. Using the spring template, I  added a trait where the spring ball will hide every time the cursor moves towards him. He might try and peek out if you wait for a few seconds.  You can try to pick him up but he will eventually break from terror.
Screen Shot 2015-12-18 at 8.42.34 AM

Screen Shot 2015-12-18 at 11.12.52 AM Screen Shot 2015-12-18 at 11.13.19 AM

 

Project10

var myParticles = [];
var mySprings = [];
var nPoints; 
// The index in the particle array, of the one the user has clicked.
var whichParticleIsGrabbed = -1;
var indexHide = 0

//-------------------------
function setup() {
  createCanvas(600, 400);
  createParticles(); 
  createSpringMeshConnectingParticles(); 
}

//-------------------------
function createParticles(){

  var radius = 100;
  var aParticle = new Particle(); 
  //var bParticle = new Particle();

  aParticle.set(width/2+10, height/2);
  //aParticle.bFixed = true
  
  myParticles.push(aParticle);
    
  for (var i=0; i<9; i++) {
    var t = map(i, 0,9, 0,TWO_PI);
    var rx = width/2  + radius * cos(t);
    var ry = height/2 + radius * sin(t);
    var aParticle = new Particle(); 
    aParticle.set(rx,ry);
    myParticles.push(aParticle);
  }
}

//-------------------------
function createSpringMeshConnectingParticles(){
  // Stitch the particles together into a mesh, 
  // by connecting them to their neighbors with springs.
  
  // The spring constant. 
  var K = 0.01; 
  
  // stitch the particles together into a blob.
  for (var i=1; i<myParticles.length; i++) {
    var p = myParticles[i];
    var q = myParticles[i+1];
    if (i==(myParticles.length-1)){
      q = myParticles[1];
    }
    var aSpring = new Spring(); 
    aSpring.set (p, q, K);
    mySprings.push(aSpring);
  }
  
  // connect all the particles to the center one into a blob.
  for (var i=1; i<myParticles.length; i++) {
    var p = myParticles[0];
    var q = myParticles[i];
    var aSpring = new Spring(); 
    aSpring.set (p, q, K);
    mySprings.push(aSpring);
  }
}

function mousePressed() {
  // If the mouse is pressed, 
  // find the closest particle, and store its index.
  whichParticleIsGrabbed = -1;
  var maxDist = 9999;
  for (var i=0; i<myParticles.length; i++) {
    var dx = mouseX - myParticles[i].px;
    var dy = mouseY - myParticles[i].py;
    var dh = sqrt(dx*dx + dy*dy);
    if (dh < maxDist) {
      maxDist = dh;
      whichParticleIsGrabbed = i;
    }
  }
}
 
 
function draw() {
  background (0);
  
  var gravityForceX = 0;
  var gravityForceY = 0;
 
  for (var i=0; i<myParticles.length; i++) {
    myParticles[i].update(); // update all locations
    if (mouseX > width/2 - 50 && mouseX < 400 
      || mouseY > width/2 + 100 && i == indexHide) {
      gravityForceY = 0.2
    } else { (gravityForceY = -0.001)
    }
  }
 
  if (mouseIsPressed 
      && whichParticleIsGrabbed > -1 
      && mouseX > 200 && mouseX < 400 || mouseX > width/2 + 20 && mouseX < width/2 - 20
      && mouseX != width/2
      && mouseY > 100 && mouseY < 400) { 
    // If the user is grabbing a particle, peg it to the mouse.
    myParticles[whichParticleIsGrabbed].px = mouseX 
    myParticles[whichParticleIsGrabbed].py = mouseY
  }
  for (var i=0; i<myParticles.length; i++) {
    myParticles[i].bPeriodicBoundaries = false;
    myParticles[i].bHardBoundaries = true; 
    myParticles[i].addForce(gravityForceX, gravityForceY); 
  }
 
  for (var i=0; i<mySprings.length; i++) {
    mySprings[i].update(); // draw all springs
  }

  for (var i=0; i<mySprings.length; i++) {
     mySprings[i].render(); // draw all springs
  }

  for (var i=0; i<myParticles.length; i++) {
    myParticles[i].render(); // draw all particles
  }
  
  // draw a blob.
  // Some of the complexity here comes from rendering it with bezier.
 
  fill('salmon'); 
  noStroke();
  beginShape(); 
  curveVertex(myParticles[9].px, myParticles[9].py);
  for (var i=1; i<myParticles.length; i++){
    curveVertex(myParticles[i].px, myParticles[i].py);
  }
  curveVertex(myParticles[1].px, myParticles[1].py);
  endShape(CLOSE); 
   noStroke()
  fill('linen')
  rect(150, 270, 270, 150)

}
 
//==========================================================
var Particle = function Particle() {
  this.px = 0;
  this.py = 0;
  this.vx = 0;
  this.vy = 0;
  this.mass = 1.0;
  this.damping = 0.92;
  
  this.bFixed = false;
  this.bLimitVelocities = true;
  this.bPeriodicBoundaries = false;
  this.bHardBoundaries = false;
  
  
  // Initializer for the Particle
  this.set = function(x, y) {
    this.px = x;
    this.py = y;
    this.vx = 0;
    this.vy = 0;
    this.damping = 0.96;
    this.mass = 1.0;
  };

  // Add a force in. One step of Euler integration.
  this.addForce = function(fx, fy) {
    var ax = fx / this.mass;
    var ay = fy / this.mass;
    this.vx += ax;
    this.vy += ay;
  };

  // Update the position. Another step of Euler integration.
  this.update = function() {
    if (this.bFixed == false){
      this.vx *= this.damping;
      this.vy *= this.damping;
  
      this.limitVelocities();
      this.handleBoundaries();
      this.px += this.vx;
      this.py += this.vy;
    }
  };

  this.limitVelocities = function() {
    if (this.bLimitVelocities) {
      var speed = sqrt(this.vx * this.vx + this.vy * this.vy);
      var maxSpeed = 10;
      if (speed > maxSpeed) {
        this.vx *= maxSpeed / speed;
        this.vy *= maxSpeed / speed;
      }
    }
  };

  this.handleBoundaries = function() {
    if (this.bPeriodicBoundaries) {
      if (this.px > width) this.px -= width;
      if (this.px < 0) this.px += width;
      if (this.py > height) this.py -= height;
      if (this.py < 0) this.py += height;
    } else if (this.bHardBoundaries) {
      if (this.px >= width){
        this.vx = abs(this.vx)*-1;
      }
      if (this.px <= 0){
        this.vx = abs(this.vx);
      }
      if (this.py >= height){
        this.vy = abs(this.vy)*-1;
      }
      if (this.py <= 0){
        this.vy = abs(this.vy);
      }
    }
  };

  this.render = function() {
    noFill();
    noStroke();
    ellipse(this.px, this.py, 9, 9);
  }
}


//==========================================================
var Spring = function Spring() {
  var p;
  var q;
  var restLength;
  var springConstant;

  this.set = function(p1, p2, k) {
    p = p1;
    q = p2;
    var dx = p.px - q.px;
    var dy = p.py - q.py;
    restLength = sqrt(dx * dx + dy * dy);
    springConstant = k;
  };

  this.update = function() {
    var dx = p.px - q.px;
    var dy = p.py - q.py;
    var dh = sqrt(dx * dx + dy * dy);

    if (dh > 1) {
      var distention = dh - restLength;
      var restorativeForce = springConstant * distention; // F = -kx
      var fx = (dx / dh) * restorativeForce;
      var fy = (dy / dh) * restorativeForce;
      p.addForce(-fx, -fy);
      q.addForce( fx,  fy);
    }
  };

  this.render = function() {
    noStroke();
    line(p.px, p.py, q.px, q.py);
  };
}