// Pairs - Jim Bumgardner int startTime; float durationS = 2; float durationMS = durationS*1000; float segDist = 100; PVector[] coords = new PVector[4]; float d1,d2; void setup() { size(500,500); noStroke(); fill(0); smooth(); background( #ffffff ); for (int i = 1; i < 4; ++i) { coords[i] = new PVector(random(width),random(height)); } for (int i = 1; i < 4; ++i) { nextPoint(); } startTime = millis(); frameRate(24); d1 = random(10,50); d2 = random(10,50); } void nextPoint() { coords[0] = coords[3]; coords[1] = coords[2]; // reflect about coords[0] coords[1].x = coords[0].x - (coords[1].x-coords[0].x); coords[1].y = coords[0].y - (coords[1].y-coords[0].y); do { float a = random(TWO_PI); coords[3] = new PVector(random(width),random(height)); } while (dist(coords[3].x,coords[3].y,width/2,height/2) > width/3); float a = random(TWO_PI); coords[2] = new PVector(coords[3].x+cos(a)*segDist,coords[3].y+sin(a)*segDist); d1 = d2; d2 = random(10,50); } void draw() { fill(50,100,50,20); rect(0,0,width,height); float r = (millis() - startTime)/durationMS; while (r > 1.0) { r -= 1.0; nextPoint(); startTime += durationMS; } float x = bezierPoint(coords[0].x, coords[1].x, coords[2].x, coords[3].x, r); float y = bezierPoint(coords[0].y, coords[1].y, coords[2].y, coords[3].y, r); float tx = bezierTangent(coords[0].x, coords[1].x, coords[2].x, coords[3].x, r); float ty = bezierTangent(coords[0].y, coords[1].y, coords[2].y, coords[3].y, r); float a = atan2(ty,tx); noStroke(); float d = lerp(d1,d2,r); if (frameCount % 2 > 0) { fill( #ffaaaa ); ellipse(x+cos(a-PI/2)*d,y+sin(a-PI/2)*d,10,10); } else { fill( #aaaaff ); ellipse(x+cos(a+PI/2)*d,y+sin(a+PI/2)*d,10,10); } }