// Based on R&F synthesis "soda processing", // which is in turn based on the Soda Constructor, http://www.sodaplay.com // The arrays of balls and springs int maxBalls=1000, maxSprings=1000; Ball[] balls = new Ball[maxBalls]; Spring[] springs = new Spring[maxSprings]; // How far we are into the arrays (how many have been created) int currBall=0, currSpring=0; // If a ball has been selected, its index (-1 if none) int selBall=-1; // Universal spring constant and drag coefficient // (each Ball and Spring has its own field, so they could be set independently) float k=0.1, drag=0.95; // Whether we are building (adding balls and springs) -- true // or simulating -- false boolean building=true; void setup() { size(400,400); smooth(); } void draw() { // Show mode by way of background if (building) background(128); else background(255); // Draw the springs first stroke(0); strokeWeight(2); for (int i=0; i= 0) { // Had previously selected -- cancel that selBall = -1; } else if (currBall= 0) { // When simulating, move ball and set its velocity balls[selBall].x = mouseX; balls[selBall].y = mouseY; balls[selBall].vx = mouseX-pmouseX; balls[selBall].vy = mouseY-pmouseY; } } void mouseReleased() { if (!building) selBall = -1; } void keyPressed() { if (key=='b') building=true; else if (key=='s') building=false; else if (key=='k') setK(k*0.5); else if (key=='K') setK(min(k*2,0.999)); else if (key=='d') setDrag(1-(1-drag)*0.5); else if (key=='D') setDrag(max(1-(1-drag)*2,0.001)); } // Set the spring constant for all springs void setK(float newK) { k = newK; println("k:"+k); for (int i=0; i