Ackso-AnimatedLoop

For this gif I wanted to make something that felt less like an object and more like some kind of immersive space, so I extended it to the edges of the frame. I used a double exponential sigmoid function that slows in and slows out so that it starts with just a sliver of white in a black void, and the speed follows the interesting part of the gif. Since GIFs have limited colors, I couldn’t make the gradient perfectly smooth, so I decided to highlight this by only including 30 shades. As a result, in the beginning and end the gradient appears to be smooth, but when it fully expands the design of the wedges becomes clear. I like how this part turned out, however the second time the lines reach the bottom, the transition of motion appears somewhat unnatural since that action takes place during the fast part of the easing function.

// This is a template for creating a looping animation in Processing/Java. 
// When you press the 'F' key, this program will export a series of images
// into a "frames" directory located in its sketch folder. 
// These can then be combined into an animated gif. 
// Known to work with Processing 3.3.6
// Prof. Golan Levin, January 2018
 
//===================================================
// Global variables. 
String  myNickname = "ackso"; 
int     nFramesInLoop = 500;
int     nElapsedFrames;
boolean bRecording; 
 
//===================================================
void setup() {
  size (500, 500); 
  bRecording = false;
  nElapsedFrames = 0;
}
//===================================================
void keyPressed() {
  if ((key == 'f') || (key == 'F')) {
    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("frames/" + myNickname + "_frame_" + nf(nElapsedFrames, 4) + ".png");
    nElapsedFrames++; 
    if (nElapsedFrames >= nFramesInLoop) {
      bRecording = false;
    }
  }
}
 
//===================================================
void renderMyDesign (float percent) {
 
  pushMatrix(); 
  translate(width/2, height/2); 
  //rotate( HALF_PI); 
  //
  // YOUR ART GOES HERE.
  // This is an example of a function that renders a temporally looping design. 
  // It takes a "percent", between 0 and 1, indicating where we are in the loop. 
  // This example uses two different graphical techniques. 
  // Use or delete whatever you prefer from this example. 
  // Remember to SKETCH FIRST!
 
  //----------------------
  // here, I set the background and some other graphical properties
  background (0);
  smooth(); 
  stroke (0, 0, 0); 
  strokeWeight (3); 
 
  //----------------------
  // Here, I assign some handy variables. 
  float cx = 0;//width/2;
  float cy = 0;//height/2;
 
  //----------------------
  // Here's a linearly-moving white square
  float squareSize = 20;
  float topY = 0 - squareSize - 2;
  float botY = height + 2;
 
 
  //----------------------
  // Here's a sigmoidally-moving pink square!
  // This uses the "Double-Exponential Sigmoid" easing function 
  // from https://github.com/golanlevin/Pattern_Master
  float eased = function_DoubleExponentialSigmoid (percent, 0.7); 
 // float phaseOffset = 0.0; 
  //eased = (eased + phaseOffset)%1.0; 
  float yPosition2 = map(eased, 0, 1, topY, botY); 
 
  float radius=500;
  float rotatingArmAngle = map(eased,0,1,0,PI*4);
  float px = cx + radius*cos(rotatingArmAngle); 
  float py = cy + radius*sin(rotatingArmAngle); 
  fill    (100); 
  float startArc = 0;
 
  float start = 0; 
  float stop = 0; 
  if (rotatingArmAngle<=TWO_PI){
    start = startArc;
    stop = rotatingArmAngle;
  } else {
    start = rotatingArmAngle-PI*4;
    stop = startArc;
  }
 
 
  float segments=30;
 for (int i=0;i<segments;i++){
   float sliceWidth=(stop-start)/segments;
   float greyScale=map(i,0,segments,255,5);
   fill(greyScale);
   arc(cx,cy,720,720,start+i*sliceWidth+PI/2, stop+PI/2);
 }
 
 
 popMatrix();
}
 
 
 
//===================================================
// Taken from https://github.com/golanlevin/Pattern_Master
float function_DoubleExponentialSigmoid (float x, float a) {
  // functionName = "Double-Exponential Sigmoid";
 
  float min_param_a = 0.0 + EPSILON;
  float max_param_a = 1.0 - EPSILON;
  a = constrain(a, min_param_a, max_param_a); 
  a = 1-a;
 
  float y = 0;
  if (x<=0.5) {
    y = (pow(2.0*x, 1.0/a))/2.0;
  } else {
    y = 1.0 - (pow(2.0*(1.0-x), 1.0/a))/2.0;
  }
  return y;
}