# nannon-AnimatedLoop

end of semester edit:

I went back a couple times on this assignment and finally got it to be a bit closer to what I envisioned.

Final:

A few iterations:

-----------------------------------------------------------

I originally wanted to do something totally different (a set of eyes that opened into new eyes), but I eventually thought that it was too complicated and illustrative and decided to invest my time in doing something 3D instead. I saw this cool gif with rotating text in a cylinder in the spirit of Zach Lieberman the other day, and wanted to do something similar. Unfortunately, I decided all of the Wednesday night, and only had Thursday to do it. Having never worked in 3D before, this was really torturous, but still kind of rewarding. I'm disappointed I didn't get the final (as of now) to how I imagined it in my head, but I'm going to keep working on this. Ultimately, I want the text to actually be a coherent sentence, and have different text on the inside of the cylinder and out. A lot of time was spent figuring out Geomerative and cyinder geometry, but I did really learn a lot. I didn't have time to use p5_func, but hopefully will get around to it as I continue to flesh this guy out.

Thank you Golan  for taking the time to explain a ton mathematics.

```// 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 import geomerative.*;   RFont f; RShape fire; RPoint[] points; RShape[] letterShapes; //=================================================== // Global variables. String myNickname = "nannon"; int nFramesInLoop = 120; int nElapsedFrames; boolean bRecording;   //=================================================== void setup() { size (640, 640, P3D); lights(); background(0); bRecording = false; nElapsedFrames = 0;   RG.init(this); fire = RG.getText("x", "Optimo.ttf", 72, CENTER);   RG.setPolygonizer(RG.UNIFORMLENGTH); RG.setPolygonizerLength(1); fill(255);   letterShapes = fire.children;     smooth(); } //=================================================== 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 &gt;= nFramesInLoop) { bRecording = false; } } }   //=================================================== void renderMyDesign (float percent) { // background(0); translate(320, 320, 200); rotateX(PI); rotateY(map(percent,0,1,0,PI/2)); rotateZ(sin(PI)); stroke(255); noFill();     int r= 100; int nSlices = 50; int zA = -20; int zB = 20;           rotateY(PI/2); rotateX(PI/2); noFill();   // draw a cylinder noFill(); stroke(255); beginShape(TRIANGLE_STRIP); for (int i=0; i&lt;=nSlices; i++) { float theta = map(i, 0, nSlices, 0, 2*PI); float pX = r*cos(theta); float pY = r*sin(theta); vertex(pX, pY, zA); vertex(pX, pY, zB); } endShape();   // print("x1:"+points[0].x+" "+"y:"+ points[0].y+" "); // print("x2:"+points[points.length-1].x+" "+"y:"+ points[points.length-1].y+" ");       //beginShape(); //for (int i=0; i&lt;points.length; i++) { // float newX = map(points[i].x, -187, 189, 0, 0.6*(2*PI)); // float newZ = map(points[i].y, -24, 0, 0, 0.6*(2*PI)); // vertex(r*cos(newX), points[i].y, abs(r*cos(newZ)));   // endShape(); //}       noFill(); stroke(255); //int nLetters = 16; //for (int i=0; i&lt;nLetters; i++) {         //int nPointsInThisContour = 16; for (int k=0; k&lt;10; k++) { pushMatrix(); float letterTheta = k* radians(45.0);     float letterX = r * cos(letterTheta); float letterY = r * sin(letterTheta);     //float eased = function_DoubleExponentialSigmoid(percent, 0.7); //float newletterY = map(eased, 0,1,0,PI);   translate(letterX, letterY); rotateX( radians(90)); rotateY(letterTheta+ radians(90));   fill(255); stroke(255); beginShape(); RPoint[] points = letterShapes[0].getPoints(); for (int j=0; j&lt;points.length; j++) {   //print(points[j].x); //float ht = map(j, 0, nPointsInThisContour, 0, TWO_PI); float hpx = points[j].x; float hpy = points[j].y; float hpz =0;     vertex(hpx, hpy, hpz);   //ellipse(hpx,hpy,10,10); } endShape(); popMatrix(); }   } 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&lt;=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; }```