I was inspired for this design by caustics. I had made something similar in a previous semester so I piggy-backed off of that code, but remade it so that it flowed using sine waves rather than with noise. I also made it loop. I feel that I could have worked much longer on the different ways of making the circles scale, but I am nonetheless pleased with my results. For me it has a calming feel. The thing I feel I failed most at with this project was time consumption. I spent a long time trying to figure out some intricate system to animate, when in the end I wound up going with something simple. This is mostly because I fell back to researching, and I looked at the Bees and Bombs website. The interesting animations with simple geometry were very impressive, and it reminded me of a (less impressive than theirs) work that I had done which may be adaptable.

```
/////////////////////////
// Flowing
// Author: Matt Kellogg
// Created: September 22, 2014
// Edited: February 10, 2015 added saving images and use of sin wave
/////////////////////////
//declare globals/constants
var backgroundColor, diam;
var img;
var counter;
var SAVE_IMAGE = false;
function setup() {
createCanvas(1500,1500);
img = createGraphics(1500,1500);
// Similar to additive color blending which wasn't working
img.blendMode(DODGE);
// a deep red
backgroundColor = color(125,20,20);
diam = 90.0;
counter = 0;
if (SAVE_IMAGE){
for (counter = 0; counter< 10; counter++){
drawImage(counter);
save(img, "gif-image-"+counter+".png");
}
}
}
function drawImage(counter){
//declare variables so they aren't re-instantiated per loop
var r, b, d, x2, y2, x, y, xDif;
// The distance to the next circle at the same height
xDif = 2*diam*cos(radians(30));
img.blendMode(NORMAL);
img.background(backgroundColor);
img.blendMode(DODGE);
img.noStroke();
for (x = -diam; x < width+diam; x+=xDif)
{
for (y = -diam; y < height+ diam; y+= diam)
{
//for each position draw a two circles
// the second is down and to the right
// so that all the circles will be tangent
// without the size variation
// map red and blue values to x and y positions
r = map(x, 0, width, 50, 120);
b = map(y, 0, height, 50, 120);
img.fill(r,100,b);
// generate noise for the first diameter based on
// the position and the frameCount
d = diam*(1.0+Math.sin((x+y+counter*2)*0.314))/2.0;//(Math.sin(y*frameCount*0.1)+Math.cos(x*frameCount*0.1))*diam;//noise(x*0.1, y*0.1, frameCount*0.01)*diam - diam/3.0;
img.ellipse(x, y, diam+d, diam+d);
// calculate the position for the second circle
x2 = x + diam*Math.cos(radians(30));
y2 = y + diam*Math.sin(radians(30));
// get the red and blue
r = map(x, 0, width, 50, 120);
b = map(y, 0, height, 50, 120);
img.fill(r,100,b);
// make some noise
d = diam*(1.0+Math.sin((x2+y2+counter*2)*0.314))/2.0;//(Math.sin(y*frameCount*0.1)+Math.cos(x*frameCount*0.1))*diam;//noise(x*0.1, y*0.1, frameCount*0.01)*diam-diam/3.0;
img.ellipse(x2, y2, diam+d, diam+d);
}
}
}
function draw() {
drawImage(frameCount/2);
background(0);
image(img,0,0);
}
```