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
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
background()
The background() function sets the color used for the background of the Processing window
Learn More
Learn to Program