Springs.

Springs.

Move the mouse over one of the circles and click to re-position. When you release the mouse, it will snap back into position. Each circle has a slightly different behavior.



int num = 3; 
Spring[] springs = new Spring[num]; 

void setup() {
  size(640, 360);
  noStroke(); 
  springs[0] = new Spring(240, 260, 40, 0.98, 8.0, 0.1, springs, 0); 
  springs[1] = new Spring(320, 210, 120, 0.95, 9.0, 0.1, springs, 1); 
  springs[2] = new Spring(180, 170, 200, 0.90, 9.9, 0.1, springs, 2);
}

void draw() {
  background(51); 

  for (Spring spring : springs) { 
    spring.update(); 
    spring.display();
  }
}

void mousePressed() {
  for (Spring spring : springs) { 
    spring.pressed();
  }
}

void mouseReleased() {
  for (Spring spring : springs) { 
    spring.released();
  }
}

class Spring { 
  // Screen values 
  float xpos, ypos;
  float tempxpos, tempypos; 
  int size = 20; 
  boolean over = false; 
  boolean move = false; 

  // Spring simulation constants 
  float mass;       // Mass 
  float k = 0.2;    // Spring constant 
  float damp;       // Damping 
  float rest_posx;  // Rest position X 
  float rest_posy;  // Rest position Y 

  // Spring simulation variables 
  //float pos = 20.0; // Position 
  float velx = 0.0;   // X Velocity 
  float vely = 0.0;   // Y Velocity 
  float accel = 0;    // Acceleration 
  float force = 0;    // Force 

  Spring[] friends;
  int me;

  // Constructor
  Spring(float x, float y, int s, float d, float m, 
  float k_in, Spring[] others, int id) { 
    xpos = tempxpos = x; 
    ypos = tempypos = y;
    rest_posx = x;
    rest_posy = y;
    size = s;
    damp = d; 
    mass = m; 
    k = k_in;
    friends = others;
    me = id;
  } 

  void update() { 
    if (move) { 
      rest_posy = mouseY; 
      rest_posx = mouseX;
    } 

    force = -k * (tempypos - rest_posy);  // f=-ky 
    accel = force / mass;                 // Set the acceleration, f=ma == a=f/m 
    vely = damp * (vely + accel);         // Set the velocity 
    tempypos = tempypos + vely;           // Updated position 

    force = -k * (tempxpos - rest_posx);  // f=-ky 
    accel = force / mass;                 // Set the acceleration, f=ma == a=f/m 
    velx = damp * (velx + accel);         // Set the velocity 
    tempxpos = tempxpos + velx;           // Updated position 


    if ((overEvent() || move) && !otherOver() ) { 
      over = true;
    } else { 
      over = false;
    }
  } 

  // Test to see if mouse is over this spring
  boolean overEvent() {
    float disX = tempxpos - mouseX;
    float disY = tempypos - mouseY;
    if (sqrt(sq(disX) + sq(disY)) < size/2 ) {
      return true;
    } else {
      return false;
    }
  }

  // Make sure no other springs are active
  boolean otherOver() {
    for (int i=0; i<num; i++) {
      if (i != me) {
        if (friends[i].over == true) {
          return true;
        }
      }
    }
    return false;
  }

  void display() { 
    if (over) { 
      fill(153);
    } else { 
      fill(255);
    } 
    ellipse(tempxpos, tempypos, size, size);
  } 

  void pressed() { 
    if (over) { 
      move = true;
    } else { 
      move = false;
    }
  } 

  void released() { 
    move = false; 
    rest_posx = xpos;
    rest_posy = ypos;
  }
} 

Functions Used

fill()

Sets the color used to fill shapes

Learn More
size()

Defines the dimension of the display window width and height in units of pixels

Learn More
ellipse()

Draws an ellipse (oval) to the screen

Learn More
setup()

The setup() function is run once, when the program starts

Learn More
mouseReleased()

The mouseReleased() function is called every time a mouse button is released

Learn More
draw()

Called directly after setup(), the draw() function continuously executes the lines of code contained inside its block until the program is stopped or noLoop() is called

Learn More
mousePressed()

The mousePressed() function is called once after every time a mouse button is pressed

Learn More
sq()

Squares a number (multiplies a number by itself)

Learn More
noStroke()

Disables drawing the stroke (outline)

Learn More
sqrt()

Calculates the square root of a number

Learn More
background()

The background() function sets the color used for the background of the Processing window

Learn More