/*https://editor.p5js.org/p5/sketches/Simulate:_Spring
* @name Spring
* @frame 710, 400
* @description Click, drag, and release the horizontal bar to start the spring.
*/
// Spring drawing constants for top bar
let springHeight = 32,
left,
right,
maxHeight = 200,
minHeight = 100,
over = false,
move = false;
// Spring simulation constants
let M = 0.8, // Mass
K = 0.2, // Spring constant
D = 0.92, // Damping
R = 150; // Rest position
// Spring simulation variables
let ps = R, // Position
vs = 0.0, // Velocity
as = 0, // Acceleration
f = 0; // Force
function setup() {
createCanvas(710, 400);
rectMode(CORNERS);
noStroke();
left = width / 2 - 100;
right = width / 2 + 100;
}
function draw() {
background(102);
updateSpring();
drawSpring();
}
function drawSpring() {
// Draw base
fill(0.2);
let baseWidth = 0.5 * ps + -8;
rect(width / 2 - baseWidth, ps + springHeight, width / 2 + baseWidth, height);
// Set color and draw top bar
if (over || move) {
fill(255);
} else {
fill(204);
}
rect(left, ps, right, ps + springHeight);
}
function updateSpring() {
// Update the spring position
if ( !move ) {
f = -K * ( ps - R ); // f=-ky
as = f / M; // Set the acceleration, f=ma == a=f/m
vs = D * (vs + as); // Set the velocity
ps = ps + vs; // Updated position
}
if (abs(vs) < 0.1) {
vs = 0.0;
}
// Test if mouse if over the top bar
if (mouseX > left && mouseX < right && mouseY > ps && mouseY < ps + springHeight) {
over = true;
} else {
over = false;
}
// Set and constrain the position of top bar
if (move) {
ps = mouseY - springHeight / 2;
ps = constrain(ps, minHeight, maxHeight);
}
}
function mousePressed() {
if (over) {
move = true;
}
}
function mouseReleased() {
move = false;
}