Flow – GIF

My mind process for this project: gif -> looping -> continuity -> time? -> something smooth -> curves? -> water -> flow
In the beginning, in my mind there were two paths for me to take – make something cool-looking/trippy that’s very math oriented, or make something nice to look at/aesthetically appealing. I was a bit lost on the former, so I went with the latter. I wanted something I wouldn’t mind staring at for a few minutes straight, so I ended up with this. I incorporated a lot of random factors so I wouldn’t mind staring at it for a few minutes straight multiple times. I think I invested too much time into trying to make it look pretty when I should have been using that time to try to figure out some cool mathy thing I could incorporate. Oh well, at least I’m happy with the outcome. Enjoyed this project. Will probably want to make another one soon/later.

This was a really quick idea sketch. The lines are really light…

Anyway, here’s the program. There is a lot of randomness involved, so each time you load it, you’re going to get something noticeably different. Enjoy!

``` int     nFramesInLoop = 300;
int     nElapsedFrames;
boolean bRecording;

ArrayList allPaths = new ArrayList();
PImage object;
PImage noncomformity;

//===================================================
void setup() {
size (300, 150);
bRecording = false;
nElapsedFrames = 0;
noFill();

int which = int(random(3));
boolean frog = false;

//Randomly choose 1 out of 3 available themes
if (which==0) {
}
else if (which==1) {
}
else {
int temp = int(random(2));
if (temp==1) {
frog = true;
}
}

//Create individual Path objects and append to global ArrayList
for (int i=0; i<9; i++) {
Path p = new Path();
//Last object has chance to be a frog
if (i==8 && frog==true){
p.changeLook(noncomformity);
}
}
}

//===================================================
void keyPressed() {
bRecording = true;
nElapsedFrames = 0;
}

//===================================================
void draw() {

// Compute a percentage (0...1) representing where we are in the loop.
float percentCompleteFraction = 0;
if (bRecording) {
percentCompleteFraction = (float) nElapsedFrames / (float)nFramesInLoop;
} else {
percentCompleteFraction = (float) (frameCount % nFramesInLoop) / (float)nFramesInLoop;
}

// Render the design, based on that percentage.
renderMyDesign (percentCompleteFraction);

// If we're recording the output, save the frame to a file.
if (bRecording) {
saveFrame("output/myname-loop-" + nf(nElapsedFrames,4) + ".png");
nElapsedFrames++;
if (nElapsedFrames > (nFramesInLoop+1)) {
bRecording = false;
}
}
}

void renderMyDesign(float percent) {
background(255);
fill(160, 200, 255, 80);
noStroke();
rect(0, 0, width, height);

int n = allPaths.size();

//Draw background bezier curves first
noFill();
for (int i=0; i1) t-=1;
float thickPercent = sin(2.0*t*TWO_PI);
float thickness = map(thickPercent,-1,1,thickness1,thickness2);
stroke(160, 200, 255, 80);
strokeWeight(thickness);
bezier(x1, y1, cpx1, cpy1, cpx2, cpy2, x2, y2);
}

//Draw moving object
void drawObject(float percent) {
//Make sure object is correct size before drawing
ownLook.resize(int(size)*2, int(size)*2);

//Object starts at random point on curve w/ random rotation
float t = startT+percent;
if (t>1) t-=1;
float x = map(t*width,0,width,x1,x2);
float y = bezierPoint(y1, cpy1, cpy2, y2, t);

float cx = x+(size/2);
float cy = y+(size/2);

//Draw the object
pushMatrix();
translate(cx, cy);
float angle = (t)*TWO_PI*rotation;
rotate(angle);
image(ownLook, -size, -size);
popMatrix();
}

//Change the images of moving object
void changeLook(PImage change){
ownLook = change;
}
}
```