harsh-Body

1. Wolly-Willy

This was a reference to the children's toy Wolly-Willy, but done in a digital format.

2. Beard of Boids

Here's a beard made out of tiny hair follicles that behave like boids.

3. Animate Artworks

Here I tried to bring to life already made artwork - I liked the recursion in the Dali piece and how computation enabled changing it dynamically.

Bonus: Here's one with Mona-Lisa

 

Code: Wolly Willy

//
// a template for receiving face tracking osc messages from
// Kyle McDonald's FaceOSC https://github.com/kylemcdonald/ofxFaceTracker
//
// 2012 Dan Wilcox danomatika.com
// for the IACD Spring 2012 class at the CMU School of Art
//
// adapted from from Greg Borenstein's 2011 example
// http://www.gregborenstein.com/
// https://gist.github.com/1603230
//
import oscP5.*;
OscP5 oscP5;
import processing.video.*;
 
 
// num faces found
int found;
 
float[] rawArray;
 
// pose
float poseScale;
PVector posePosition = new PVector();
PVector poseOrientation = new PVector();
 
int numPoints = 4000;
Vehicle[] vehicles;
PVector[] lowPoints;
 
float prevMouseX;
float prevMouseY;
 
PImage img;
PImage lightOff;
PImage lightOn;
Capture cam;
 
float mappedPoseScale;
 
float[][] mouseCircle;
 
float[][] setupPoints;
float[][] centDist;
 
String mode;
 
void setup() {
  size(640, 480);
  frameRate(30);
  rawArray = new float[132];
  cam = new Capture(this, 640, 480, 30);
  cam.start();
  img = loadImage("hair.png");
  lightOff = loadImage("lightoff.png");
  lightOn = loadImage("lighton.png");
 
 
  oscP5 = new OscP5(this, 8338);
  oscP5.plug(this, "found", "/found");
  oscP5.plug(this, "rawData", "/raw");
  oscP5.plug(this, "poseScale", "/pose/scale");
  oscP5.plug(this, "posePosition", "/pose/position");
  oscP5.plug(this, "poseOrientation", "/pose/orientation");
 
  vehicles = new Vehicle[numPoints];
  lowPoints = new PVector[numPoints];
  initializeVehicles();
 
  setupPoints = new float[numPoints][2];
  centDist = new float[numPoints][2];
 
  mode = "setup";
}
 
void draw() {  
  //println(posePosition.x,posePosition.y);
  background(255);
  stroke(0);  
  mappedPoseScale = map(poseScale,0,6,0,1);
 
  if(keyPressed){
    if(key == ' '){
      mode = "follow";
    }
    if(key == 'r'){
      mode = "reset";
    }
  }
 
 ////////////////////// DISPLAY WEBCAM IMAGE //////////////////////
  if(cam.available()) {
    cam.read();
  }
  image(cam,0,0);
  //////////////////////////////////////////////////////////////////
  if(mode == "setup"){  
    mouseCircle = getCirclePoints(30, mouseX, mouseY);   
 
    moveBoidsInside(mouseCircle, mouseX,mouseY,30);
    for(int i=0; i<numPoints; i++){
      float[] curLoc = new float[2];
      curLoc[0] = vehicles[i].location.x;
      curLoc[1] = vehicles[i].location.y;
 
      float[] curDist = new float[2];
      curDist[0] = vehicles[i].location.x-posePosition.x;
      curDist[1] = vehicles[i].location.y-posePosition.y;   
      setupPoints[i] = curLoc;
      centDist[i] = curDist;
    }
    //if(mousePressed){ 
    //    image(lightOn,mouseX,mouseY);
    //}
    //else{
    //    image(lightOff,mouseX,mouseY);
    //}
  }
 
 
  if(mode == "follow" && found != 0){
    for(int i=0; i<numPoints; i++){
      Vehicle curBoid = vehicles[i];
      float[] curBoidLoc = new float[2];
      curBoidLoc[0] = curBoid.location.x;
      curBoidLoc[1] = curBoid.location.y;
      curBoid.maxspeed = 5;
      curBoid.maxforce = 0.2;
 
      if(curBoid.location.y < height-60){
        PVector newLoc = new PVector(posePosition.x+centDist[i][0]*mappedPoseScale,posePosition.y+centDist[i][1]*mappedPoseScale);
        //println(newLoc);
        curBoid.arrive(newLoc);
        curBoid.update();
        curBoid.display();
      }
    }
  }
 
  if(mode == "reset"){
    int num = 0;
    for(int i=0; i< numPoints; i++){
      Vehicle curBoid = vehicles[i];
      curBoid.maxspeed = 50;
      curBoid.maxforce = 10;
      curBoid.jiggleRadius = 1;
      curBoid.arrive(lowPoints[i]);
      curBoid.update();
      curBoid.display();
      if((curBoid.location.y-lowPoints[i].y) < 2){ num++; } } if(num >= numPoints){
        mode = "setup";
      }
  }
 
}
 
 
 
////////////////////////////////////////////////////////////////////////
/////////////////////Vehicle Settings //////////////////////////////////
////////////////////////////////////////////////////////////////////////
 
void initializeVehicles(){
  for(int i=0; i<numPoints; i++){
    PVector pos = new PVector(random(width), random(height-30,height));
    lowPoints[i] = pos;
    Vehicle new_vehicle = new Vehicle(pos.x,pos.y);
    vehicles[i] = new_vehicle;
  }
}
 
void jiggle(){
  for(int i=0; i<numPoints; i++){
    Vehicle v = vehicles[i];
    v.arrive(v.location);
    v.update();
    v.display();
  }
}
 
void display(){
    for(int i=0; i<numPoints; i++){
    Vehicle v = vehicles[i];
    v.update();
    v.display();
  }
}
 
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
 
// OSC CALLBACK FUNCTIONS
 
public void found(int i) {
  //println("found: " + i);
  found = i;
}
 
public void poseScale(float s) {
  //println("scale: " + s);
  poseScale = s;
}
 
public void posePosition(float x, float y) {
  //println("pose position\tX: " + x + " Y: " + y );
  posePosition.set(x, y, 0);
}
 
public void poseOrientation(float x, float y, float z) {
  //println("pose orientation\tX: " + x + " Y: " + y + " Z: " + z);
  poseOrientation.set(x, y, z);
}
 
public void rawData(float[] raw) {
  rawArray = raw; // stash data in array
}
 
// all other OSC messages end up here
void oscEvent(OscMessage m) {
  if(m.isPlugged() == false) {
    //println("UNPLUGGED: " + m);
  }
}

Code: Artwork

 

// Processing 3.0x template for receiving raw points from
// Kyle McDonald's FaceOSC v.1.1 
// https://github.com/kylemcdonald/ofxFaceTracker
//
// Adapted by Kaleb Crawford and Golan Levin, 2016-7, after:
// 2012 Dan Wilcox danomatika.com
// for the IACD Spring 2012 class at the CMU School of Art
// adapted from from Greg Borenstein's 2011 example
// https://gist.github.com/1603230
 
import oscP5.*;
OscP5 oscP5;
int found;
float[] rawArray;
int highlighted; //which point is selected
float poseScale;
 
PImage background;
PImage mouth;
PImage left_eyebrow;
PImage right_eyebrow;
PImage small_eyebrows;
PImage smallest_eyebrows;
PImage eyes;
 
 
 
float mouthOff;
 
float rightBrowOff;
float leftBrowOff;
float smallBrowOff;
 
float prevRightBrowOff;
float prevLeftBrowOff;
float mappedScale;
 
//--------------------------------------------
void setup() {
  size(800, 682);
  frameRate(30);
 
  rawArray = new float[132]; 
  oscP5 = new OscP5(this, 8338);
  oscP5.plug(this, "found", "/found");
  oscP5.plug(this, "rawData", "/raw");
  oscP5.plug(this, "poseScale", "/pose/scale");
 
  background = loadImage("base.png");
  mouth = loadImage("mouths.png");
  left_eyebrow = loadImage("left eyebrow.png");
  right_eyebrow = loadImage("right eyebrow.png");
  small_eyebrows = loadImage("small eyebrows.png");
  eyes = loadImage("eyes.png");
  smallest_eyebrows = loadImage("smallest eyebrows.png");
 
 
}
 
//--------------------------------------------
void draw() {  
  mappedScale = map(poseScale, 0,5,0,1);
 
  prevRightBrowOff = rightBrowOff;
  prevLeftBrowOff = leftBrowOff;
 
  rightBrowOff = (getLeftBrowHeight());
 
  leftBrowOff =  (getRightBrowHeight());
 
  smallBrowOff = (getRightBrowHeight());
 
  image(background, 0, 0);
 
  pushMatrix();
  translate(0,-(rightBrowOff*2));
  image(left_eyebrow, 0, -2);
  popMatrix();
 
  pushMatrix();
  translate(0,-(leftBrowOff*8));
  image(right_eyebrow, 0, 0);
  popMatrix();
 
  pushMatrix();
  translate(0,-(leftBrowOff));
  image(small_eyebrows, 0, 0);
  popMatrix();
 
  pushMatrix();
  translate(0,-(leftBrowOff*0.5));
  image(smallest_eyebrows, 0, 0);
  popMatrix();
 
  if(leftEyeClosed() || rightEyeClosed()){
    image(eyes, 0, 0);
  }
 
  pushMatrix();
  tint(255, 300-(getMouthMovement())*5);
  image(mouth, 0, 0);
  popMatrix();
 
 
 
 
}
 
//--------------------------------------------
void drawFacePoints() {
  int nData = rawArray.length;
  for (int val=0; val<nData; val+=2) {
    if (val == highlighted) { 
      fill(255, 0, 0);
      ellipse(rawArray[val], rawArray[val+1], 11, 11);
    } else {
      fill(100);
      ellipse(rawArray[val], rawArray[val+1], 8, 8);
    }
  }
}
 
//--------------------------------------------
void drawFacePolygons() {
  noFill(); 
  stroke(100); 
 
  // Face outline
  beginShape();
  for (int i=0; i<34; i+=2) { vertex(rawArray[i], rawArray[i+1]); } for (int i=52; i>32; i-=2) {
    vertex(rawArray[i], rawArray[i+1]);
  }
  endShape(CLOSE);
 
  // Eyes
  beginShape();
  for (int i=72; i<84; i+=2) {
    vertex(rawArray[i], rawArray[i+1]);
  }
  endShape(CLOSE);
  beginShape();
  for (int i=84; i<96; i+=2) {
    vertex(rawArray[i], rawArray[i+1]);
  }
  endShape(CLOSE);
 
  // Upper lip
  beginShape();
  for (int i=96; i<110; i+=2) { vertex(rawArray[i], rawArray[i+1]); } for (int i=124; i>118; i-=2) {
    vertex(rawArray[i], rawArray[i+1]);
  }
  endShape(CLOSE);
 
  // Lower lip
  beginShape();
  for (int i=108; i<120; i+=2) { vertex(rawArray[i], rawArray[i+1]); } vertex(rawArray[96], rawArray[97]); for (int i=130; i>124; i-=2) {
    vertex(rawArray[i], rawArray[i+1]);
  }
  endShape(CLOSE);
 
  // Nose bridge
  beginShape();
  for (int i=54; i<62; i+=2) {
    vertex(rawArray[i], rawArray[i+1]);
  }
  endShape();
 
  // Nose bottom
  beginShape();
  for (int i=62; i<72; i+=2) {
    vertex(rawArray[i], rawArray[i+1]);
  }
  endShape();
}
 
 
//--------------------------------------------
public void found(int i) {
  found = i;
}
public void rawData(float[] raw) {
  rawArray = raw; // stash data in array
}
 
public void poseScale(float s) {
  //println("scale: " + s);
  poseScale = s;
}
 
//--------------------------------------------
void keyPressed() {
  int len = rawArray.length; 
  if (keyCode == RIGHT) {
    highlighted = (highlighted + 2) % len;
  }
  if (keyCode == LEFT) {
    highlighted = (highlighted - 2 + len) % len;
  }
}

harsh-LookingOutwards03

Delicate Boundaries - Chris Sugrue

This project interests me not because of the artistic concept behind it(which I find a bit simplistic), but because of the novel use of media. The way the artist uses projection mapping to bridge the divide between the digital and the physical is incredible - giving digital objects a "presence" without much effort. This served as a reference point for my "Augmented Body" project.

 

harsh-viewing04

Spectacle: The use of digital technologies for mostly aesthetic and commercial purpose - wowing the viewer with technological marvel or obsessiveness about craft.

Speculation: Being self-aware of the nature of digital media, and reflecting/expressing this awareness through means of irony. Usually separated from the technical craft of creation itself.

 

 

Ugly Dynamics - this example from the video just blew my mind - both in its conceptual brilliance and incredible affect and experience.
Warburton clearly thinks of this as a combination of Speculation and Spectacle - and I could not agree more. It is incredibly self-aware, both in terms of aesthetics as well as conceptual execution (the project is filled to the brim with irony). I also think that this project reclaims spectacle as speculation - looking beyond the normal's of "simulation" and shifting the context of what we think simulation is. It's incredibly subversive - while still pushing the frontier on human experience. I'm incredibly jealous of both the technical and conceptual brilliance shown by Nikita Daikur here, never seen anything like this before.

Here's where it lies:
Drag -----/----- Acceleration
Visibility -/--------- Invisibility
Surplus -----/----- Waste
Commerce ---------/- Art

Ugly Dynamics from nikita diakur on Vimeo.

harsh-telematic

 

link

This interactive environment is called "Bird-Do-Or-Die" where users compete or collaborate to either save or kill the bird(s). This is best played over a period of time. People should use their asynchronous free time to either protect or kill the bird - competing against other users over longer durations.

The network model here is ideally a many-to-many setup - where people form teams to work on saving/and or killing the bird over time. This also makes the system asynchronous - where people can work on increasing the bridge blocks over time, which then others must overcome to kill the bird. The roles are essentially oppositional - where people work to defeat the other's work.

harsh-LookingOutwards02

Ars (Rockheim) - Feb 2012

link

This project by Marius Watz particularly caught my eye. It's a  generative video for the LED media facade of Norway's national museum of pop&rock. What makes it particularly compelling for me (as may be painfully obvious) is its direct link to architecture. I've rarely seen generative art being linked to built architecture before, and this one is particularly compelling. Not only because of the striking image it makes, but also because of the algorithm that generated it. It looks like Watz used a 2-D ribbon explosion (for the lack of a better word) algorithm in this project - which he then mapped onto the 3-D facade. The 2-D image has a certain animated quality about it which I think is partly the result of some stochastic process. This, combined with the multitude and composition of colors, makes the image very aesthetically pleasing to me - which then directly impacts the architecture.

 

harsh – Reading03

Reading Naimark makes me deeply uncomfortable. It's not because of the complexities that arise in the definitions of "First Word" and "Last Word" art, I'm okay with that, it's the deep level of ambiguity between these two terms that hits the uncanny spot. I get it, Naimark is trying to argue that the very nature of the relationship between art and technology means that it's almost impossible to say what's "First Word" and what's "Last Word", and this questions my assumptions about technology as an artistic medium to a very fundamental level. I've always assumed that Real art is First Word, art that is not afraid to experiment, art that tries to expand the field and its definition, art that uses new media as exploration, or uses old media in a new way.

But, Naimark sheds doubt upon this whole worldview - isn't art done with high skill, in an established setting also art? And isn't art playing with technology just that? A form of play?  I guess a conclusion for me is not about the medium, but about the effect of the art. Does the art make a comment on society and the way we operate? Is it aesthetic? Does it move people? If so, yes, it's  both First Word and Last Word, but then I ask, why all this playing around with technology?

harsh – Clock

IMAGES

GIF 

 

EMBED

This project was really fun to work on, with my intention being to make a linguistic representation of time. I first started with trying to tell the time in an interesting way - which simply involved applying a polish notation idea to the time itself, so something like 8:41 would become "eleven past half past eight" - while this was alright, I tried to make it more and more interesting. This led me to make the time more complex, by adding and removing common idioms such as "Half" and "Quarter" from the time. After this, a friend suggested for this complexity to increase the longer the function runs, which I thought was an awesome idea, and was the last thing I implemented.

In its current state, the text overflows from the screen and you must scroll to see the rest, I've currently paused trying to make the text smaller for it to fit in the screen - hopefully, this will come to realization in a future version. (Update- fixed it!)

let timer = 2;
 
function getWord(number){
 
  number = int(number);
 
  if (number==1){return "one "}
  else if (number==2){return "two "}
  else if (number==3){return "three "}
  else if (number==4){return "four "}
  else if (number==5){return "five "}
  else if (number==6){return "six "}
  else if (number==7){return "seven "}
  else if (number==8){return "eight "}
  else if (number==9){return "nine "}
  else if (number==10){return "ten "}
  else if (number==11){return "one " + "past " +"ten "}
  else if (number==12){return "two " + "past " +"ten "}
  else if (number==13){return "three " + "past " +"ten "}
  else if (number==14){return "four " + "past " +"ten "}
  else if (number==15){return "QUARTER "}
 
  return number.toString();
 
}
 
function getWordHour(number){
 
  number = int(number);
 
 
  if (number==0){return "twelve"}
  else if (number==1){return "one "}
  else if (number==2){return "two "}
  else if (number==3){return "three "}
  else if (number==4){return "four "}
  else if (number==5){return "five "}
  else if (number==6){return "six "}
  else if (number==7){return "seven "}
  else if (number==8){return "eight "}
  else if (number==9){return "nine "}
  else if (number==10){return "ten "}
  else if (number==11){return "eleven"}
  else if (number==12){return "twelve"}
 
  return number.toString();
 
}
 
function makeTimeString(listWithShit){
var decimalTime = listWithShit[0];
var changes = listWithShit[1];
var operator = listWithShit[2];
 
var decimalTimeString = decimalTime.toString();
 
var hourString = decimalTimeString.slice(0,2);
 
if(int(hourString) > 12)
 
{ 
  hourString = int(hourString) - 12;
  hourString = hourString.toString();
 
}
 
else if(int(hourString) < 1) { hourString = int(hourString) + 12; hourString = hourString.toString(); } var minuteString = decimalTimeString.slice(3,5); var minuteStringInt = int(minuteString); minuteStringInt = int( map(minuteStringInt,0,100,0,60) ); var finalString = "" for(var i=operator.length-1; i>=0; i--){
  var curOperator = operator[i];
 
  var curChange = changes[i]
 
  if(curChange == 15){curChange = "QUARTER "}
  else if(curChange == 30){curChange = "HALF "}
  else if(curChange == 10){curChange = "TEN ";}
  else if(curChange == 5){curChange = "FIVE ";}
 
  finalString+=curChange;
 
  if(curOperator == "-"){finalString+="past ";}
  else if(curOperator == "+"){finalString+="to ";}
}
 
 
var newMinuteString = "";
 
if(minuteStringInt>=45){
  var hourStringInt = int(hourString)+1;
  hourString = hourStringInt.toString();
  var leftOverMinutes = minuteStringInt-45;
 
  if(leftOverMinutes == 0){
    newMinuteString = "QUARTER "+"before "
  }
  else{
    newMinuteString = getWord(leftOverMinutes) + "past " + "QUARTER " + "before "
  }
}
 
else if(30<=minuteStringInt  && minuteStringInt<45){
  var leftOverMinutes = 45-minuteStringInt;
 
  if(leftOverMinutes == 15){
    newMinuteString = "HALF "+"past "
  }
  else{
    newMinuteString = getWord(leftOverMinutes) + "past "+"HALF "+"past "
  }
}
 
else if(15<=minuteStringInt  && minuteStringInt<30){
  if(minuteStringInt == 15){
    newMinuteString = "QUARTER "+"past ";
  }
  else{
    var leftOverMinutes = 30-minuteStringInt;
    newMinuteString = getWord(leftOverMinutes) + "to "+"QUARTER "+"past ";
  }
}
 
else if(0<=minuteStringInt  && minuteStringInt<15){
    if(minuteStringInt != 0){
      newMinuteString = getWord(minuteStringInt) +"past "      
    }
 
}
 
var hourStringWord = getWordHour(int(hourString));
//hourStringWord = hourStringWord.slice(0,hourStringWord.length-1);
 
var timestring = finalString + newMinuteString + hourStringWord + "."
 
finalString = "It is " + timestring.toLowerCase();
return finalString;
}
 
 
function complicatedClock(hour,minute){
  var currentTime = hour+map(minute,0,60,0,1);
  var newTime = currentTime;
 
  // LIST TO KEEP TRACK OF ALL THE SUBTRACTIONS/ADDITIONS BEING MADE
  var changes = [];
 
  // LIST TO KEEP TRACK OF WHETHER THE CHANGES ARE ADDITIONS OR SUBTRACTIONS
  var operator = [];
 
  var timeChanges = [30,15,10,5];
 
  for(var i = 0; i < timer; i++){
 
    var curIndex = int(random(0,4));
 
    var stepChange = timeChanges[curIndex];
 
    var addOrSubtract = random(0,1);
 
    if(addOrSubtract < 0.5){ changes.push(stepChange); operator.push("+"); newTime = newTime + map(stepChange,0,60,0,1); } else { changes.push(stepChange); operator.push("-"); newTime = newTime-map(stepChange,0,60,0,1); } } return [newTime,changes,operator]; } var curTimeString; var increasing = true; var textYTop = 20; function setup() { createCanvas(500,500); background(50); textFont("Helvetica"); fill(255); noStroke(); curTimeString = makeTimeString(complicatedClock(hour(),minute())); } function keyPressed(){ if (keyCode == ESCAPE){ increasing = false; } else { increasing = true; } } function mouseWheel(event) { textYTop -= event.delta; if(textYTop > 30){
  	textYTop = 29;
  }
 
}
 
function draw() {
  rectMode(CORNER);
  background(50);
 
  if (frameCount % (120) == 0 && increasing == true){
    curTimeString = makeTimeString(complicatedClock(hour(),minute()));
    timer+= 4;
  }
  text(curTimeString,20,textYTop,460,curTimeString.length*100);
}

harsh-Scope

praxinoscope-output

Here's an interpolation between Batman and a Coorgi - I'm not sure there's much else to say beyond that I would like to improve the interpolation between these two beings in the near future.

 
 
 
double[][] points = {
 
  {86.920948, -23.249132}, 
 
  {86.664672, -24.823893}, 
 
  {86.175996, -26.342519}, 
 
  {85.463499, -27.769999}, 
 
  {84.557778, -29.083769}, 
 
  {83.499422, -30.278466}, 
 
  {82.332896, -31.368541}, 
 
  {81.149804, -32.441065}, 
 
  {79.973249, -33.520753}, 
 
  {78.804825, -34.609233}, 
 
  {77.646171, -35.708105}, 
 
  {76.498983, -36.818939}, 
 
  {75.365020, -37.943267}, 
 
  {74.246116, -39.082578}, 
 
  {73.144184, -40.238308}, 
 
  {72.061223, -41.411829}, 
 
  {70.972337, -42.579390}, 
 
  {69.761074, -43.618243}, 
 
  {68.418840, -44.480833}, 
 
  {66.966098, -45.140455}, 
 
  {65.435219, -45.590573}, 
 
  {63.859903, -45.846697}, 
 
  {62.266241, -45.938590}, 
 
  {60.670160, -45.900258}, 
 
  {59.079093, -45.765953}, 
 
  {57.495346, -45.562513}, 
 
  {55.921415, -45.293435}, 
 
  {54.359616, -44.961068}, 
 
  {52.811914, -44.568224}, 
 
  {51.279888, -44.118075}, 
 
  {49.764723, -43.614049}, 
 
  {48.267215, -43.059734}, 
 
  {46.787793, -42.458789}, 
 
  {45.326554, -41.814870}, 
 
  {43.883302, -41.131573}, 
 
  {42.455647, -40.416190}, 
 
  {41.029901, -39.696975}, 
 
  {39.603639, -38.978787}, 
 
  {38.177011, -38.261328}, 
 
  {36.750165, -37.544299}, 
 
  {35.323253, -36.827402}, 
 
  {33.896425, -36.110339}, 
 
  {32.469830, -35.392812}, 
 
  {31.043618, -34.674523}, 
 
  {29.617942, -33.955174}, 
 
  {28.192952, -33.234467}, 
 
  {26.768798, -32.512105}, 
 
  {25.345168, -31.788715}, 
 
  {23.953224, -31.009128}, 
 
  {22.902710, -29.831666}, 
 
  {22.680213, -28.269473}, 
 
  {23.119263, -26.745011}, 
 
  {24.109144, -25.503345}, 
 
  {25.432246, -24.616583}, 
 
  {26.880274, -23.943827}, 
 
  {28.355004, -23.331482}, 
 
  {29.844053, -22.754683}, 
 
  {31.337536, -22.189417}, 
 
  {32.829143, -21.619219}, 
 
  {34.321058, -21.049826}, 
 
  {35.813617, -20.482123}, 
 
  {37.307001, -19.916596}, 
 
  {38.801390, -19.353730}, 
 
  {40.296962, -18.794014}, 
 
  {41.793891, -18.237937}, 
 
  {43.292349, -17.685990}, 
 
  {44.792498, -17.138667}, 
 
  {46.294506, -16.596460}, 
 
  {47.798529, -16.059869}, 
 
  {49.304718, -15.529390}, 
 
  {50.813220, -15.005525}, 
 
  {52.324176, -14.488776}, 
 
  {53.837714, -13.979648}, 
 
  {55.353963, -13.478649}, 
 
  {56.873039, -12.986285}, 
 
  {58.395047, -12.503068}, 
 
  {59.920088, -12.029507}, 
 
  {61.448249, -11.566115}, 
 
  {62.979608, -11.113404}, 
 
  {64.514231, -10.671886}, 
 
  {66.052173, -10.242072}, 
 
  {67.593476, -9.824473}, 
 
  {69.138972, -9.422747}, 
 
  {70.696441, -9.070563}, 
 
  {72.264665, -8.769725}, 
 
  {73.840441, -8.511216}, 
 
  {75.421355, -8.286148}, 
 
  {77.010010, -8.129169}, 
 
  {78.605791, -8.140331}, 
 
  {80.180613, -8.391741}, 
 
  {81.669897, -8.958155}, 
 
  {82.980798, -9.863096}, 
 
  {84.054231, -11.041537}, 
 
  {84.902440, -12.392737}, 
 
  {85.573674, -13.840886}, 
 
  {86.109564, -15.344604}, 
 
  {86.500435, -16.892308}, 
 
  {86.756509, -18.468101}, 
 
  {86.900946, -20.058175}, 
 
  {86.960155, -21.653820}, 
 
  {-92.890651, -19.904734}, 
 
  {-92.758800, -18.310670}, 
 
  {-92.471637, -16.737408}, 
 
  {-92.016404, -15.204235}, 
 
  {-91.449681, -13.708261}, 
 
  {-90.762578, -12.264018}, 
 
  {-89.904046, -10.915597}, 
 
  {-88.818938, -9.743826}, 
 
  {-87.491318, -8.858478}, 
 
  {-85.987059, -8.323836}, 
 
  {-84.404541, -8.101408}, 
 
  {-82.805413, -8.104900}, 
 
  {-81.213356, -8.260255}, 
 
  {-79.633312, -8.511646}, 
 
  {-78.059562, -8.800258}, 
 
  {-76.491277, -9.117235}, 
 
  {-74.928640, -9.460988}, 
 
  {-73.371745, -9.829889}, 
 
  {-71.820604, -10.222284}, 
 
  {-70.275145, -10.636502}, 
 
  {-68.735225, -11.070864}, 
 
  {-67.200631, -11.523689}, 
 
  {-65.671088, -11.993299}, 
 
  {-64.146266, -12.478025}, 
 
  {-62.625786, -12.976208}, 
 
  {-61.109226, -13.486201}, 
 
  {-59.596125, -14.006370}, 
 
  {-58.085991, -14.535094}, 
 
  {-56.578306, -15.070764}, 
 
  {-55.072531, -15.611780}, 
 
  {-53.568110, -16.156552}, 
 
  {-52.064477, -16.703494}, 
 
  {-50.561059, -17.251026}, 
 
  {-49.057280, -17.797568}, 
 
  {-47.552568, -18.341535}, 
 
  {-46.046930, -18.882933}, 
 
  {-44.543998, -19.431792}, 
 
  {-43.044152, -19.989031}, 
 
  {-41.546932, -20.553289}, 
 
  {-40.051859, -21.123215}, 
 
  {-38.558441, -21.697462}, 
 
  {-37.066172, -22.274690}, 
 
  {-35.574540, -22.853560}, 
 
  {-34.083026, -23.432738}, 
 
  {-32.602190, -24.038181}, 
 
  {-31.188586, -24.784709}, 
 
  {-29.920084, -25.757031}, 
 
  {-28.873428, -26.961008}, 
 
  {-28.366090, -28.458148}, 
 
  {-28.837907, -29.958080}, 
 
  {-29.979152, -31.068115}, 
 
  {-31.364692, -31.864293}, 
 
  {-32.799297, -32.572786}, 
 
  {-34.229666, -33.289793}, 
 
  {-35.656745, -34.013328}, 
 
  {-37.081507, -34.741413}, 
 
  {-38.504946, -35.472085}, 
 
  {-39.928063, -36.203384}, 
 
  {-41.351862, -36.933352}, 
 
  {-42.777344, -37.660029}, 
 
  {-44.205493, -38.381447}, 
 
  {-45.637276, -39.095625}, 
 
  {-47.073627, -39.800568}, 
 
  {-48.515442, -40.494263}, 
 
  {-49.963570, -41.174676}, 
 
  {-51.418802, -41.839756}, 
 
  {-52.881861, -42.487433}, 
 
  {-54.353390, -43.115622}, 
 
  {-55.843187, -43.698704}, 
 
  {-57.360900, -44.204745}, 
 
  {-58.901183, -44.637333}, 
 
  {-60.459110, -45.001394}, 
 
  {-62.030409, -45.302675}, 
 
  {-63.611515, -45.547465}, 
 
  {-65.199561, -45.742361}, 
 
  {-66.792327, -45.894092}, 
 
  {-68.389148, -45.989422}, 
 
  {-69.986322, -45.913703}, 
 
  {-71.558823, -45.625548}, 
 
  {-73.072593, -45.111904}, 
 
  {-74.494369, -44.381058}, 
 
  {-75.801778, -43.460694}, 
 
  {-76.987623, -42.387789}, 
 
  {-78.090404, -41.228551}, 
 
  {-79.204089, -40.079757}, 
 
  {-80.332115, -38.945038}, 
 
  {-81.472894, -37.823139}, 
 
  {-82.624892, -36.712761}, 
 
  {-83.786625, -35.612569}, 
 
  {-84.956653, -34.521201}, 
 
  {-86.133574, -33.437269}, 
 
  {-87.316018, -32.359364}, 
 
  {-88.502641, -31.286059}, 
 
  {-89.662006, -30.183974}, 
 
  {-90.710170, -28.976114}, 
 
  {-91.607478, -27.652752}, 
 
  {-92.309427, -26.216646}, 
 
  {-92.772766, -24.687142}, 
 
  {-92.970204, -23.101314}, 
 
  {-92.902345, -21.504445}, 
 
  {-129.502091, 180.180550}, 
 
  {-129.507482, 164.442770}, 
 
  {-129.513007, 148.705005}, 
 
  {-129.518513, 132.967252}, 
 
  {-129.523847, 117.229485}, 
 
  {-129.528855, 101.491718}, 
 
  {-129.533384, 85.753951}, 
 
  {-129.537280, 70.016183}, 
 
  {-129.540391, 54.278430}, 
 
  {-129.542563, 38.540675}, 
 
  {-129.543643, 22.802917}, 
 
  {-129.543478, 7.065147}, 
 
  {-129.541914, -8.672636}, 
 
  {-129.510250, -24.410276}, 
 
  {-128.922206, -40.135459}, 
 
  {-127.518102, -55.808502}, 
 
  {-125.221334, -71.375413}, 
 
  {-121.966708, -86.770227}, 
 
  {-117.706449, -101.917288}, 
 
  {-112.464760, -116.753698}, 
 
  {-106.223176, -131.197025}, 
 
  {-98.879381, -145.111265}, 
 
  {-90.364763, -158.340456}, 
 
  {-80.660813, -170.722832}, 
 
  {-69.780142, -182.082796}, 
 
  {-57.521073, -191.926997}, 
 
  {-58.772610, -185.584243}, 
 
  {-67.867493, -172.742816}, 
 
  {-76.128119, -159.351540}, 
 
  {-83.232804, -145.315234}, 
 
  {-88.701519, -130.574089}, 
 
  {-91.396571, -115.096454}, 
 
  {-90.763584, -99.402505}, 
 
  {-80.036844, -92.128944}, 
 
  {-64.313423, -91.457100}, 
 
  {-48.591017, -90.761965}, 
 
  {-32.870304, -90.029598}, 
 
  {-18.688792, -95.010335}, 
 
  {-6.490756, -104.952791}, 
 
  {7.097693, -99.136269}, 
 
  {20.286833, -90.562913}, 
 
  {35.920805, -89.863825}, 
 
  {51.657024, -90.078996}, 
 
  {67.389870, -90.469174}, 
 
  {82.866490, -91.885923}, 
 
  {83.592484, -107.469820}, 
 
  {82.098356, -123.128586}, 
 
  {78.826175, -138.512956}, 
 
  {73.710584, -153.385459}, 
 
  {66.795536, -167.511537}, 
 
  {58.231384, -180.704310}, 
 
  {48.064174, -192.693474}, 
 
  {56.484543, -188.494910}, 
 
  {68.265753, -178.083644}, 
 
  {78.744886, -166.351783}, 
 
  {88.011195, -153.638207}, 
 
  {96.142146, -140.168805}, 
 
  {103.159462, -126.086670}, 
 
  {109.081474, -111.509484}, 
 
  {113.961065, -96.550422}, 
 
  {117.876295, -81.309913}, 
 
  {120.822162, -65.853597}, 
 
  {122.772684, -50.239291}, 
 
  {123.930784, -34.545743}, 
 
  {124.381162, -18.815322}, 
 
  {124.415292, -3.077775}, 
 
  {124.363530, 12.659900}, 
 
  {124.556184, 28.396048}, 
 
  {124.916964, 44.129654}, 
 
  {125.200108, 59.864862}, 
 
  {125.426946, 75.600990}, 
 
  {125.618815, 91.337587}, 
 
  {125.797050, 107.074340}, 
 
  {125.982987, 122.811015}, 
 
  {126.142263, 138.547961}, 
 
  {126.306783, 154.284848}, 
 
  {126.637997, 170.018978}, 
 
  {126.998187, 185.752555}, 
 
  {123.113824, 192.106662}, 
 
  {113.081976, 179.980683}, 
 
  {103.050481, 167.854411}, 
 
  {93.021684, 155.725898}, 
 
  {82.992929, 143.597374}, 
 
  {72.969703, 131.464277}, 
 
  {63.030681, 119.262190}, 
 
  {49.152882, 121.381742}, 
 
  {34.321587, 126.606509}, 
 
  {18.920668, 129.793153}, 
 
  {3.251805, 131.194827}, 
 
  {-12.476601, 130.991172}, 
 
  {-28.067009, 128.918767}, 
 
  {-43.284620, 124.948457}, 
 
  {-57.811610, 118.931459}, 
 
  {-69.911034, 123.154878}, 
 
  {-79.780560, 135.413353}, 
 
  {-89.653501, 147.669061}, 
 
  {-99.526905, 159.924395}, 
 
  {-119.263262, 184.443480}, 
 
  {-129.361095, 195.914930}, 
 
  {-109.397811, 172.181740}
};
 
double[][] points2 =
  {
 
 
  {23.808966, -113.235216}, 
 
  {16.635916, -112.718379}, 
 
  {10.350569, -109.414393}, 
 
  {9.787917, -102.591103}, 
 
  {14.697923, -97.775923}, 
 
  {21.683358, -96.093647}, 
 
  {27.760598, -92.266242}, 
 
  {32.959011, -87.276243}, 
 
  {38.112019, -82.237850}, 
 
  {40.135701, -76.239025}, 
 
  {33.162074, -76.496060}, 
 
  {25.971810, -76.250705}, 
 
  {19.412552, -73.533725}, 
 
  {19.375470, -66.845310}, 
 
  {25.648075, -63.928877}, 
 
  {32.458588, -65.927568}, 
 
  {37.550441, -70.980427}, 
 
  {43.095733, -68.889276}, 
 
  {43.306455, -61.722080}, 
 
  {42.182402, -54.609678}, 
 
  {39.647631, -47.879381}, 
 
  {35.368905, -42.113381}, 
 
  {29.496984, -37.982276}, 
 
  {22.694314, -35.651093}, 
 
  {15.572475, -34.549303}, 
 
  {8.381446, -34.068737}, 
 
  {1.175449, -34.196535}, 
 
  {-5.995360, -34.920180}, 
 
  {-13.004710, -36.533705}, 
 
  {-19.331836, -39.942841}, 
 
  {-24.559522, -44.878857}, 
 
  {-28.394366, -50.961248}, 
 
  {-30.564968, -57.814209}, 
 
  {-30.806298, -64.995263}, 
 
  {-28.179931, -71.428779}, 
 
  {-22.504746, -68.424416}, 
 
  {-16.557793, -64.484394}, 
 
  {-9.470728, -64.501048}, 
 
  {-5.402746, -69.961212}, 
 
  {-9.237203, -75.334086}, 
 
  {-16.316738, -76.556345}, 
 
  {-23.509609, -76.213244}, 
 
  {-27.774878, -79.315776}, 
 
  {-22.801899, -84.446119}, 
 
  {-17.794330, -89.632110}, 
 
  {-12.273657, -94.247705}, 
 
  {-5.656351, -96.997920}, 
 
  {1.022123, -99.393558}, 
 
  {3.565160, -105.911456}, 
 
  {0.115215, -111.654576}, 
 
  {-6.944447, -113.001965}, 
 
  {-14.150145, -112.991888}, 
 
  {-15.991661, -115.214339}, 
 
  {-9.821899, -118.885535}, 
 
  {-2.922179, -120.935067}, 
 
  {4.229913, -121.784446}, 
 
  {11.430442, -121.590557}, 
 
  {18.519665, -120.324183}, 
 
  {25.245947, -117.769912}, 
 
  {31.006976, -113.495662}, 
 
  {61.769050, 0.148968}, 
 
  {60.506181, 0.298494}, 
 
  {59.258436, 0.543902}, 
 
  {58.034888, 0.890169}, 
 
  {56.846253, 1.341809}, 
 
  {55.705058, 1.902470}, 
 
  {54.625694, 2.574379}, 
 
  {53.624268, 3.357601}, 
 
  {52.718089, 4.249192}, 
 
  {51.924670, 5.242375}, 
 
  {51.260217, 6.326028}, 
 
  {50.737782, 7.484829}, 
 
  {50.365561, 8.700256}, 
 
  {50.145883, 9.952332}, 
 
  {50.075800, 11.221653}, 
 
  {50.169674, 12.489172}, 
 
  {50.434694, 13.732246}, 
 
  {50.862390, 14.929202}, 
 
  {51.439025, 16.062047}, 
 
  {52.148122, 17.117157}, 
 
  {52.972582, 18.084914}, 
 
  {53.896019, 18.958830}, 
 
  {54.903377, 19.734612}, 
 
  {55.981057, 20.409391}, 
 
  {57.116769, 20.981199}, 
 
  {58.299291, 21.448653}, 
 
  {59.518206, 21.810823}, 
 
  {60.763684, 22.067221}, 
 
  {62.026337, 22.217873}, 
 
  {63.297142, 22.263428}, 
 
  {64.567284, 22.202720}, 
 
  {65.827524, 22.033238}, 
 
  {67.068329, 21.755193}, 
 
  {68.279977, 21.369465}, 
 
  {69.452469, 20.877424}, 
 
  {70.575344, 20.280821}, 
 
  {71.637431, 19.581767}, 
 
  {72.626547, 18.782862}, 
 
  {73.529207, 17.887506}, 
 
  {74.330452, 16.900448}, 
 
  {75.013948, 15.828582}, 
 
  {75.562596, 14.681929}, 
 
  {75.959913, 13.474561}, 
 
  {76.192239, 12.224980}, 
 
  {76.252197, 10.955376}, 
 
  {76.155592, 9.687826}, 
 
  {75.905593, 8.441491}, 
 
  {75.501295, 7.236374}, 
 
  {74.947676, 6.092139}, 
 
  {74.255056, 5.026245}, 
 
  {73.437704, 4.052627}, 
 
  {72.512110, 3.181166}, 
 
  {71.495388, 2.417865}, 
 
  {70.404110, 1.765454}, 
 
  {69.253608, 1.224131}, 
 
  {68.057651, 0.792256}, 
 
  {66.828379, 0.466920}, 
 
  {65.576369, 0.244373}, 
 
  {64.310760, 0.120322}, 
 
  {63.039413, 0.090151}, 
 
  {23.145407, -16.569632}, 
 
  {31.407213, -22.473820}, 
 
  {39.364234, -28.808981}, 
 
  {46.229010, -36.313033}, 
 
  {51.846433, -44.792493}, 
 
  {56.216224, -53.980719}, 
 
  {59.670030, -63.554621}, 
 
  {62.255874, -73.398170}, 
 
  {64.431294, -83.314028}, 
 
  {73.583158, -84.001785}, 
 
  {82.405532, -79.001163}, 
 
  {89.120694, -71.413967}, 
 
  {93.196416, -62.118915}, 
 
  {95.246725, -52.156101}, 
 
  {95.989943, -42.007343}, 
 
  {95.838591, -31.829269}, 
 
  {95.231246, -21.666633}, 
 
  {98.822119, -12.569717}, 
 
  {105.572084, -4.960520}, 
 
  {113.730059, 1.081138}, 
 
  {122.570998, 6.031498}, 
 
  {127.963270, 14.533056}, 
 
  {129.967263, 24.488706}, 
 
  {129.978649, 34.660827}, 
 
  {136.481603, 40.896205}, 
 
  {145.954738, 44.575234}, 
 
  {154.409211, 50.210262}, 
 
  {161.481541, 57.509949}, 
 
  {167.108658, 65.980932}, 
 
  {171.581032, 75.123461}, 
 
  {175.353007, 84.577760}, 
 
  {178.487040, 94.262667}, 
 
  {181.043772, 104.116137}, 
 
  {183.046785, 114.095927}, 
 
  {181.275910, 123.614825}, 
 
  {171.317668, 124.193373}, 
 
  {161.295997, 122.400646}, 
 
  {151.331419, 120.314525}, 
 
  {141.449706, 117.866719}, 
 
  {131.685071, 114.988121}, 
 
  {122.080674, 111.614143}, 
 
  {112.688536, 107.688677}, 
 
  {103.567770, 103.169047}, 
 
  {94.724927, 98.125753}, 
 
  {86.179872, 92.593630}, 
 
  {78.010688, 86.520949}, 
 
  {70.303655, 79.872219}, 
 
  {63.147133, 72.634804}, 
 
  {55.084571, 66.560119}, 
 
  {45.106691, 66.299406}, 
 
  {35.222399, 68.505619}, 
 
  {25.098334, 67.633681}, 
 
  {16.411610, 62.855009}, 
 
  {13.323250, 53.275827}, 
 
  {13.293436, 43.111661}, 
 
  {14.657844, 33.024943}, 
 
  {16.483712, 23.009311}, 
 
  {18.393108, 13.008972}, 
 
  {19.988524, 2.954796}, 
 
  {20.893476, -7.182849}, 
 
  {-49.122441, 22.217810}, 
 
  {-47.860844, 22.067039}, 
 
  {-46.616729, 21.809128}, 
 
  {-45.399560, 21.444695}, 
 
  {-44.219091, 20.974835}, 
 
  {-43.085543, 20.401000}, 
 
  {-42.009847, 19.724966}, 
 
  {-41.003955, 18.948939}, 
 
  {-40.081149, 18.075825}, 
 
  {-39.256276, 17.109749}, 
 
  {-38.545743, 16.056828}, 
 
  {-37.967042, 14.926184}, 
 
  {-37.537513, 13.730982}, 
 
  {-37.272200, 12.489043}, 
 
  {-37.181056, 11.222393}, 
 
  {-37.259653, 9.954679}, 
 
  {-37.494533, 8.706459}, 
 
  {-37.884483, 7.497691}, 
 
  {-38.423085, 6.347414}, 
 
  {-39.099191, 5.272134}, 
 
  {-39.898479, 4.284898}, 
 
  {-40.805077, 3.395099}, 
 
  {-41.802878, 2.608830}, 
 
  {-42.876407, 1.929487}, 
 
  {-44.011289, 1.358393}, 
 
  {-45.194422, 0.895340}, 
 
  {-46.413987, 0.538990}, 
 
  {-47.659374, 0.287159}, 
 
  {-48.921096, 0.137011}, 
 
  {-50.190692, 0.085191}, 
 
  {-51.460735, 0.125786}, 
 
  {-52.724424, 0.258709}, 
 
  {-53.974083, 0.488573}, 
 
  {-55.200754, 0.819717}, 
 
  {-56.394032, 1.256000}, 
 
  {-57.541913, 1.800499}, 
 
  {-58.630707, 2.455079}, 
 
  {-59.645082, 3.219809}, 
 
  {-60.568363, 4.092235}, 
 
  {-61.383234, 5.066596}, 
 
  {-62.072924, 6.133165}, 
 
  {-62.622859, 7.278032}, 
 
  {-63.022482, 8.483619}, 
 
  {-63.266719, 9.730044}, 
 
  {-63.356550, 10.997059}, 
 
  {-63.291323, 12.265438}, 
 
  {-63.058264, 13.513884}, 
 
  {-62.662688, 14.720765}, 
 
  {-62.116354, 15.867389}, 
 
  {-61.434461, 16.939049}, 
 
  {-60.633519, 17.925015}, 
 
  {-59.729842, 18.817866}, 
 
  {-58.738729, 19.612637}, 
 
  {-57.674177, 20.306042}, 
 
  {-56.548906, 20.895909}, 
 
  {-55.374547, 21.380809}, 
 
  {-54.161861, 21.759882}, 
 
  {-52.920944, 22.032778}, 
 
  {-51.661371, 22.199695}, 
 
  {-50.392274, 22.261463}, 
 
  {-170.029712, 112.646242}, 
 
  {-167.878571, 102.750798}, 
 
  {-165.143284, 92.955007}, 
 
  {-161.988301, 83.287202}, 
 
  {-158.180015, 73.859166}, 
 
  {-153.539639, 64.812700}, 
 
  {-147.950196, 56.325429}, 
 
  {-140.854960, 49.074473}, 
 
  {-131.949641, 44.267443}, 
 
  {-122.617962, 40.342771}, 
 
  {-117.143744, 32.074879}, 
 
  {-116.810525, 21.942561}, 
 
  {-114.676831, 12.084432}, 
 
  {-107.922918, 4.673181}, 
 
  {-98.968563, -0.122670}, 
 
  {-91.171855, -6.627108}, 
 
  {-84.514767, -14.307625}, 
 
  {-82.460242, -24.008103}, 
 
  {-83.069300, -34.160061}, 
 
  {-83.062854, -44.328172}, 
 
  {-82.026737, -54.439867}, 
 
  {-79.569790, -64.296816}, 
 
  {-74.918582, -73.302787}, 
 
  {-67.681553, -80.378620}, 
 
  {-58.552911, -84.779207}, 
 
  {-50.814140, -81.202803}, 
 
  {-48.842995, -71.226384}, 
 
  {-46.140336, -61.424398}, 
 
  {-42.508198, -51.929298}, 
 
  {-37.795316, -42.923865}, 
 
  {-31.915224, -34.635452}, 
 
  {-24.893712, -27.289902}, 
 
  {-16.877927, -21.043334}, 
 
  {-8.837724, -14.968966}, 
 
  {-7.823433, -5.007337}, 
 
  {-6.894073, 5.115414}, 
 
  {-5.125987, 15.130290}, 
 
  {-3.157561, 25.108817}, 
 
  {-1.402295, 35.127041}, 
 
  {-0.208894, 45.222097}, 
 
  {-0.773757, 55.354816}, 
 
  {-4.757859, 64.499935}, 
 
  {-14.198983, 67.964996}, 
 
  {-24.335335, 68.166945}, 
 
  {-34.271283, 66.056079}, 
 
  {-44.001896, 67.288219}, 
 
  {-51.438635, 74.213193}, 
 
  {-58.878796, 81.147278}, 
 
  {-66.638185, 87.720472}, 
 
  {-74.825785, 93.751064}, 
 
  {-83.411227, 99.200610}, 
 
  {-92.339443, 104.068714}, 
 
  {-101.553467, 108.371995}, 
 
  {-110.998679, 112.141585}, 
 
  {-120.625822, 115.419562}, 
 
  {-130.392640, 118.255225}, 
 
  {-140.264313, 120.701829}, 
 
  {-160.228011, 124.577380}, 
 
  {-170.029712, 122.817151}, 
 
  {-150.213054, 122.814114}
 
};
 
 
 
 
// Template for KidzLabs/4M/Toysmith Animation Praxinoscope
// https://www.amazon.com/4M-3474-Animation-Praxinoscope/dp/B000P02HYC
// https://www.walmart.com/ip/Animation-Praxinoscope-Science-Kits-by-Toysmith-3474/45681503
// Developed for Processing 3.3.6 * http://processing.org
// 23 January 2018 * Golan Levin 
 
// See information about Processing PDF export at: 
// https://processing.org/reference/libraries/pdf/index.html
// PDF generated by Processing can be opened in Adobe Illustrator.
import processing.pdf.*;
boolean bRecordingPDF = false;
 
float inch = 72; 
float diamArtInner = inch * 1.50; 
float diamArtOuter = inch * 4.80; 
float diamCutInner = inch * 1.41; 
float diamCutOuter = inch * 4.875; 
float holeDy = inch * 0.23;
float holeDx = inch * 0.20;
float holeD = inch * 0.1;
 
final int nFrames = 10; 
int myFrameCount = 0;
int exportFrameCount = 0; 
boolean bAnimate = true; 
boolean bExportFrameImages = false;
 
 
 
 
//////////////////////////////////////////////////////////
 
int lenPoints = points2.length;
 
double[][] scaledPoints = new double [lenPoints][2];
 
double[][] squishedPoints = new double [lenPoints][2];
 
double[][] squishedDiff = new double [lenPoints][2];
 
double[][] repPoints = new double [lenPoints][2];
 
//-------------------------------------------------------
void setup() {
  size(792, 612); // 11x8.5" at 72DPI
  frameRate(15);
  smooth();
 
 
 
for (int j =0; j <points.length; j++) {
  double pointX = points2[j][0]*0.2;
  double pointY = -1*(points2[j][1]*0.2);
  scaledPoints[j][0] = pointX;
  scaledPoints[j][1] = pointY;
}
 
 
for (int i=0; i<points.length; i++) {
  double pointX = (points[i][0]*0.2);
  double pointY = (-1*(points[i][1]*0.2));
  squishedPoints[i][0] = pointX; 
  squishedPoints[i][1] = pointY;
}
 
for (int i=0; i<points.length; i++) {
  double squishedPointX = squishedPoints[i][0];
  double squishedPointY = squishedPoints[i][1];
 
  double scaledPointX = scaledPoints[i][0];
  double scaledPointY = scaledPoints[i][1];
 
  double diffX = squishedPointX-scaledPointX;
  double diffY = squishedPointY-scaledPointY;
  squishedDiff[i][0] = diffX;
  squishedDiff[i][1] = diffY;
}
 
for (int i=0; i<points.length; i++) {
  double pointX = scaledPoints[i][0];
  double pointY = scaledPoints[i][1];
 
  repPoints[i][0] = pointX;
  repPoints[i][1] = pointY;
}
} 
 
//-------------------------------------------------------
void draw() {
  background(240); 
  if (bRecordingPDF) {
    beginRecord(PDF, "praxinoscope-output.pdf");
  }
 
  // Do all the drawing. 
  pushMatrix(); 
  translate(width/2, height/2);
  drawCutLines(); 
  drawGuides(); 
  drawAllFrames();
  popMatrix();
 
  if (bExportFrameImages) {
    // If activated, export .PNG frames 
    if (exportFrameCount < nFrames) {
      String filename = "frame_" + nf((exportFrameCount%nFrames), 3) + ".png";
      saveFrame("frames/" + filename);
      println("Saved: " + filename); 
      exportFrameCount++;
      if (exportFrameCount >= nFrames) {
        bExportFrameImages = false;
        exportFrameCount = 0;
      }
    }
  }
 
  if (bRecordingPDF) {
    endRecord();
    bRecordingPDF = false;
  }
}
 
 
//-------------------------------------------------------
void keyPressed() {
  switch (key) {
  case ' ': 
    // Press spacebar to pause/unpause the animation. 
    bAnimate = !bAnimate;
    break;
 
  case 'p': 
  case 'P':
    // Press 'p' to export a PDF for the Praxinoscope.
    bRecordingPDF = true; 
    break;
 
  case 'f': 
  case 'F': 
    // Press 'f' to export .png Frames (to make an animated .GIF)
    myFrameCount = 0; 
    exportFrameCount = 0; 
    bExportFrameImages = true;
    bAnimate = true; 
    break;
  }
}
 
//-------------------------------------------------------
void drawCutLines() {
  fill(0); 
  textAlign(CENTER, BOTTOM); 
  text("Praxinoscope Template", 0, 0-diamCutOuter/2-6); 
 
  stroke(0); 
  strokeWeight(1.0);
 
  noFill(); 
  if (!bRecordingPDF) {
    fill(255);
  }
  ellipse(0, 0, diamCutOuter, diamCutOuter);
 
  noFill(); 
  if (!bRecordingPDF) {
    fill(240);
  }
  ellipse(0, 0, diamCutInner, diamCutInner);
 
  noFill(); 
  ellipse(diamCutOuter/2 - holeDx, 0-holeDy, holeD, holeD); 
 
  line (diamCutInner/2, 0, diamCutOuter/2, 0);
}
 
//-------------------------------------------------------
void drawGuides() {
  // This function draws the guidelines. 
  // Don't draw these when we're exporting the PDF. 
  if (!bRecordingPDF) {
 
    noFill(); 
    stroke(128); 
    strokeWeight(0.2); 
    ellipse(0, 0, diamArtInner, diamArtInner); 
    ellipse(0, 0, diamArtOuter, diamArtOuter);
 
    for (int i=0; i<nFrames; i++) {
      float angle = map(i, 0, nFrames, 0, TWO_PI); 
      float pxi = diamArtInner/2 * cos(angle);
      float pyi = diamArtInner/2 * sin(angle);
      float pxo = diamArtOuter/2 * cos(angle);
      float pyo = diamArtOuter/2 * sin(angle);
      stroke(128); 
      strokeWeight(0.2);
      line (pxi, pyi, pxo, pyo);
    }
 
    // Draw the red wedge outline, highlighting the main view.
    int redWedge = 7; // assuming nFrames = 10
    for (int i=redWedge; i<=(redWedge+1); i++) {
      float angle = map(i, 0, nFrames, 0, TWO_PI); 
      float pxi = diamArtInner/2 * cos(angle);
      float pyi = diamArtInner/2 * sin(angle);
      float pxo = diamArtOuter/2 * cos(angle);
      float pyo = diamArtOuter/2 * sin(angle);
      stroke(255, 0, 0); 
      strokeWeight(2.0);
      line (pxi, pyi, pxo, pyo);
    }
    noFill(); 
    stroke(255, 0, 0); 
    strokeWeight(2.0);
    float startAngle = redWedge*TWO_PI/nFrames;
    float endAngle = (redWedge+1)*TWO_PI/nFrames;
    arc(0, 0, diamArtInner, diamArtInner, startAngle, endAngle); 
    arc(0, 0, diamArtOuter, diamArtOuter, startAngle, endAngle); 
 
 
    for (int i=0; i<nFrames; i++) {
      float angle = map(i, 0, nFrames, 0, TWO_PI); 
 
      pushMatrix();
      rotate(angle); 
      float originY = ((diamArtOuter + diamArtInner)/2)/2;
      translate(0, 0-originY); 
 
      noFill(); 
      stroke(128); 
      strokeWeight(0.2);
      line (-inch/2, 0, inch/2, 0); 
      line (0, -inch/2, 0, inch/2); 
 
      popMatrix();
    }
  }
}
 
//-------------------------------------------------------
void drawAllFrames() {
  for (int i=0; i<nFrames; i++) {
    float angle = map(i, 0, nFrames, 0, TWO_PI); 
    float originY = ((diamArtOuter + diamArtInner)/2)/2;
 
    pushMatrix();
    rotate(angle); 
    translate(0, 0-originY); 
    scale(0.8, 0.8); // feel free to ditch this 
 
    int whichFrame = i; 
    if (bAnimate) {
      whichFrame = (i+myFrameCount)%nFrames;
    }
    drawArtFrame (whichFrame); 
    // drawArtFrameAlternate (whichFrame); 
 
    popMatrix();
  }
  myFrameCount++;
}
 
 
//-------------------------------------------------------
void drawArtFrame (int whichFrame) { 
  // Draw the artwork for a generic frame of the Praxinoscope, 
  // given the framenumber (whichFrame) out of nFrames.
  // NOTE #1: The "origin" for the frame is in the center of the wedge.
  // NOTE #2: Remember that everything will appear upside-down!
 
  // Draw the frame number
  fill(0); 
  noStroke(); 
  //textAlign(CENTER, CENTER); 
  //text (whichFrame, -1, -47);
 
 
 
  if (whichFrame<5) {
    for (int i=0; i<points.length; i++) {
      double[] curPoint = scaledPoints[i];
      double curX = curPoint[0];
      double curY = curPoint[1];
      double diffX = squishedDiff[i][0];
      double diffY = squishedDiff[i][1];
      double fMapped = map(whichFrame, 0, 5, 0, 1);
      double newX = curX+(diffX*fMapped);
      double newY = curY+(diffY*fMapped);
 
      repPoints[i][0] = newX;
      repPoints[i][1] = newY;
    }
  }
 
  else if (whichFrame>=5) {
    for (int i=0; i<points.length; i++) {
      double[] curPoint = squishedPoints[i];
      double curX = curPoint[0];
      double curY = curPoint[1];
      double diffX = squishedDiff[i][0];
      double diffY = squishedDiff[i][1];
      double fMapped = map(whichFrame, 5, 10, 0, 1);
      double newX = -1*((diffX*fMapped)-curX);
      double newY = -1*((diffY*fMapped)-curY);
 
      repPoints[i][0] = newX;
      repPoints[i][1] = newY;     
    }
  }
 
 
 
//if(whichFrame == 9){
//      pushMatrix();
//  fill(0);
//  beginShape();
//  for (int i=200; i<300; i++) {
//    float[] curPoint = repPoints[i];
//    //float[] nextPoint = repPoints[i+1];
//    vertex(curPoint[0], curPoint[1]);
//      //ellipse(curPoint[0],curPoint[1],2,2);
//  }
//  endShape();
//  popMatrix();
 
 
//  pushMatrix();
//  fill(0);
//  beginShape();
//  for (int i=0; i<100; i++) {
//    float[] curPoint = repPoints[i];
//    //float[] nextPoint = repPoints[i+1];
//    vertex(curPoint[0], curPoint[1]);
//      //ellipse(curPoint[0],curPoint[1],2,2);
//  }
//  endShape();
//  popMatrix();
 
//   pushMatrix();
//  fill(255);
//  beginShape();
//  for (int i=100; i<200; i++) {
//    float[] curPoint = repPoints[i];
//    //float[] nextPoint = repPoints[i+1];
//    vertex(curPoint[0], curPoint[1]);
//      //ellipse(curPoint[0],curPoint[1],2,2);
//  }
//  endShape();
//  popMatrix();
 
 
 
//}
 
 
 
//else if(whichFrame == 0){
//  pushMatrix();
//  fill(255);
//  beginShape();
//  for (int i=0; i<60; i++) {
//    float[] curPoint = repPoints[i];
//    //float[] nextPoint = repPoints[i+1];
//    vertex(curPoint[0], curPoint[1]);
//      //ellipse(curPoint[0],curPoint[1],2,2);
//  }
//  endShape();
//  popMatrix();
 
//   pushMatrix();
//  fill(0);
//  beginShape();
//  for (int i=60; i<120; i++) {
//    float[] curPoint = repPoints[i];
//    //float[] nextPoint = repPoints[i+1];
//    vertex(curPoint[0], curPoint[1]);
//      //ellipse(curPoint[0],curPoint[1],2,2);
//  }
//  endShape();
//  popMatrix();
 
//    pushMatrix();
//  fill(0);
//  beginShape();
//  for (int i=120; i<180; i++) {
//    float[] curPoint = repPoints[i];
//    //float[] nextPoint = repPoints[i+1];
//    vertex(curPoint[0], curPoint[1]);
//      //ellipse(curPoint[0],curPoint[1],2,2);
//  }
//  endShape();
//  popMatrix();
 
//      pushMatrix();
//  fill(0);
//  beginShape();
//  for (int i=180; i<240; i++) {
//    float[] curPoint = repPoints[i];
//    //float[] nextPoint = repPoints[i+1];
//    vertex(curPoint[0], curPoint[1]);
//      //ellipse(curPoint[0],curPoint[1],2,2);
//  }
//  endShape();
//  popMatrix();
 
 
//      pushMatrix();
//  fill(0);
//  beginShape();
//  for (int i=240; i<300; i++) {
//    float[] curPoint = repPoints[i];
//    //float[] nextPoint = repPoints[i+1];
//    vertex(curPoint[0], curPoint[1]);
//      //ellipse(curPoint[0],curPoint[1],2,2);
//  }
//  endShape();
//  popMatrix();
//}
 
 
  pushMatrix();
  fill(255);
  stroke(0);
  strokeWeight(1);
  //beginShape();
  for (int i=0; i<points.length-1; i++) {
    if ((i+1)%60==0 || (i+1)%100==0 ) {
      continue;
    }
    double[] curPoint = repPoints[i];
    double[] nextPoint = repPoints[i+1];
    //double[] nextNextPoint = repPoints[i+2];
 
    line((float)curPoint[0], (float)curPoint[1],(float)nextPoint[0],(float)nextPoint[1]);
    //vertex((float)curPoint[0],(float)curPoint[1]);
    //bezierVertex((float)nextPoint[0],(float)nextPoint[1],(float)nextNextPoint[0],(float)nextNextPoint[1],(float)nextNextNextPoint[0],(float)nextNextNextPoint[1]);
     // ellipse((float)curPoint[0],(float)curPoint[1],2,2);
 
  }
  //endShape();
popMatrix();
 
  //line(repPoints[0][0], repPoints[0][1], repPoints[repPoints.length-1][0], repPoints[repPoints.length-1][1]);
  //line( repPoints[repPoints.length-1][0], repPoints[repPoints.length-1][1],repPoints[0][0], repPoints[0][1]);
 
}
 
//-------------------------------------------------------
void drawArtFrameAlternate(int whichFrame) { 
  // An alternate drawing test. 
  // Draw a falling object. 
 
 
  // Draw a little splat on the frame when it hits the ground. 
  if (whichFrame == (nFrames-1)) {
    stroke(0, 0, 0); 
    strokeWeight(0.5); 
    int nL = 10;
    for (int i=0; i<nL; i++) {
      float a = HALF_PI + map(i, 0, nL-1, 0, TWO_PI);
      float cx = 12 * cos(a);
      float cy = 10 * sin(a); 
      float dx = 16 * cos(a);
      float dy = 13 * sin(a); 
      line (cx, 45+cy, dx, 45+dy);
    }
  }
 
  // Draw a little box frame
  fill(255); 
  stroke(0, 0, 0);
  strokeWeight(1); 
  rect(-5, -50, 10, 100); 
 
  // Make the puck accelerate downward
  float t = map(whichFrame, 0, nFrames-1, 0, 1); 
  float t2 = pow(t, 2.0); 
  float rh = 8 + whichFrame * 0.5; // wee stretch
  float ry = map(t2, 0, 1, 0, 100-rh) - 50; 
 
  noStroke(); 
  fill(0, 0, 0);
  rect(-5, ry, 10, rh);
}

harsh – AnimatedLoop

I started off with inspiration from D'arcy Thompson's "Theory of Transformations" - where he uses grid transformations to morph between different species of animals. I found his idea of being able to use simple mathematical equations to create transformations quite fascinating. So, I began to implement some of these systems, which included shear, scale, polar co-ordinate and exponential-scaling transformations. First, I tested this theory out on something simple - like a circle, before moving on to more complex geometries. I decided to keep my objects constructed as point clouds - as this kept my process of iteration quick, and the system scalable. By a sheer stroke of luck, I tried a polar coordinate transform before transforming it into a cartesian system - this created a really cool, point dissipation effect. I then began playing with these transformations, eventually closing in on using Mattise's Dancers - I thought the notion of an emergent composition from a seemingly random point cloud was quite interesting. It also connotated notions of the Gestalt and the border between familiarity and familiarity of a representation. I also thought that it made an interesting take on composition, referencing Mattise's methods in a digital medium. This was probably one the most iterations I have gone through in a week-long project, tweaking transformations, easing functions and point clouds numerous times before arriving at this result. I used the exponentialInOut and quinticInOut easing functions - both primarily to increase the time spent at the actual image and to speed up the transformation process. The process of crafting these transformations, both with morphing and easing functions was quite a novel one for me, having never really thought about computational craft before. Overall, I'm happy with the effect, and I think the easing and transformation functions work well. If I had more time on this, I would increase the complexity of the animation to emphasize this idea of composition - trying to recreate each object like pieces of paper cut by Mattise.

For this project, I did not really keep "sketches" - instead relying on Thompson's illustrations and descriptions as a means of generation:

 
 
 
//===================================================
// User-modifiable global variables.
var myNickname = "Harsh";
var nFramesInLoop = 120;
var bEnableExport = true;
 
 
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
 
 
var circVals = [];
for(var i=0; i<pointsVals.length; i++){
  var curPointVals = pointsVals[i];
  circVals.push([curPointVals[0],curPointVals[1]*-1]);
}
 
 
var polarVals = []
for(var i=0; i<circVals.length; i++){
  var polarRadius = 30;
  var curPointVals = circVals[i];
  var cosX = polarRadius*Math.cos(curPointVals[0]);
  var sinY = polarRadius*Math.sin(curPointVals[1])
  polarVals.push([cosX,sinY]);
}
 
 
var shearVals = [];
for(var i=0; i<circVals.length; i++){
  var curPointVals = polarVals[i];
  var newX = curPointVals[0]-200;
  var newY = curPointVals[1]+200;
  shearVals.push([newX,newY]);
}
 
var shearDifferencesCartesian = []
for(var i=0; i<pointsVals.length; i++){
  var curCartValx = circVals[i][0];
  var curCartValy = circVals[i][1];
  var curShearValx = shearVals[i][0];
  var curShearValy = shearVals[i][1];
  var curTotalDifferenceX = curShearValx-curCartValx;
  var curTotalDifferenceY = curShearValy-curCartValy;
  shearDifferencesCartesian.push([curTotalDifferenceX,curTotalDifferenceY]);
}
 
var shearDifferencesPolar = []
for(var i=0; i<pointsVals.length; i++){
  var curPolarValx = polarVals[i][0];
  var curPolarValy = polarVals[i][1];
  var curShearValx = shearVals[i][0];
  var curShearValy = shearVals[i][1];
  var curTotalDifferenceX = curPolarValx-curShearValx;
  var curTotalDifferenceY = curPolarValy-curShearValy;
  shearDifferencesPolar.push([curTotalDifferenceX,curTotalDifferenceY]);
}
 
var cartesianDifferences = []
for(var i=0; i<pointsVals.length; i++){
  var curCartValx = circVals[i][0];
  var curCartValy = circVals[i][1];
  var curPolarValx = polarVals[i][0];
  var curPolarValy = polarVals[i][1];
  var curTotalDifferenceX = curPolarValx-curCartValx;
  var curTotalDifferenceY = curPolarValy-curCartValy;
  cartesianDifferences.push([curTotalDifferenceX,curTotalDifferenceY]);
}
 
var repVals = [];
for(var i=0; i<pointsVals.length; i++){
  var curPointVals = pointsVals[i];
  repVals.push([curPointVals[0],curPointVals[1]]);
}
 
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
 
var circValsHead = [];
for(var i=0; i<headVals.length; i++){
  var curPointVals = headVals[i];
  circValsHead.push([curPointVals[0],curPointVals[1]*-1]);
}
 
 
var polarValsHead = []
for(var i=0; i<circValsHead.length; i++){
  var polarRadius = 30;
  var curPointVals = circValsHead[i];
  var cosX = polarRadius*Math.cos(curPointVals[0]);
  var sinY = polarRadius*Math.sin(curPointVals[1])
  polarValsHead.push([cosX,sinY]);
}
 
 
var shearValsHead = [];
for(var i=0; i<circValsHead.length; i++){
  var curPointVals = polarValsHead[i];
  var newX = curPointVals[0]+200;
  var newY = curPointVals[1]+200;
  shearValsHead.push([newX,newY]);
}
 
var shearDifferencesCartesianHead = []
for(var i=0; i<circValsHead.length; i++){
  var curCartValx = circValsHead[i][0];
  var curCartValy = circValsHead[i][1];
  var curShearValx = shearValsHead[i][0];
  var curShearValy = shearValsHead[i][1];
  var curTotalDifferenceX = curShearValx-curCartValx;
  var curTotalDifferenceY = curShearValy-curCartValy;
  shearDifferencesCartesianHead.push([curTotalDifferenceX,curTotalDifferenceY]);
}
 
var shearDifferencesPolarHead = []
for(var i=0; i<circValsHead.length; i++){
  var curPolarValx = polarValsHead[i][0];
  var curPolarValy = polarValsHead[i][1];
  var curShearValx = shearValsHead[i][0];
  var curShearValy = shearValsHead[i][1];
  var curTotalDifferenceX = curPolarValx-curShearValx;
  var curTotalDifferenceY = curPolarValy-curShearValy;
  shearDifferencesPolarHead.push([curTotalDifferenceX,curTotalDifferenceY]);
}
 
var cartesianDifferencesHead = []
for(var i=0; i<circValsHead.length; i++){
  var curCartValx = circValsHead[i][0];
  var curCartValy = circValsHead[i][1];
  var curPolarValx = polarValsHead[i][0];
  var curPolarValy = polarValsHead[i][1];
  var curTotalDifferenceX = curPolarValx-curCartValx;
  var curTotalDifferenceY = curPolarValy-curCartValy;
  cartesianDifferencesHead.push([curTotalDifferenceX,curTotalDifferenceY]);
}
 
var repValsHead = [];
for(var i=0; i<circValsHead.length; i++){
  var curPointVals = headVals[i];
  repValsHead.push([curPointVals[0],curPointVals[1]]);
}
 
 
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
 
 
// Other global variables you don't need to touch.
var nElapsedFrames;
var bRecording;
var theCanvas;
//===================================================
function setup() {
  theCanvas = createCanvas(900, 900);
  bRecording = false;
  nElapsedFrames = 0;
}
//===================================================
function keyTyped() {
  if (bEnableExport) {
    if ((key === 'f') || (key === 'F')) {
      bRecording = true;
      nElapsedFrames = 0;
    }
  }
}
//===================================================
function draw() {
  // Compute a percentage (0...1) representing where we are in the loop.
  var percentCompleteFraction = 0;
  if (bRecording) {
    percentCompleteFraction = float(nElapsedFrames) / float(nFramesInLoop);
  } else {
    percentCompleteFraction = float(frameCount % nFramesInLoop) / float(nFramesInLoop);
  }
  // Render the design, based on that percentage.
  // This function renderMyDesign() is the one for you to change.
  renderMyDesign (percentCompleteFraction);
  // If we're recording the output, save the frame to a file.
  // Note that the output images may be 2x large if you have a Retina mac.
  // You can compile these frames into an animated GIF using a tool like:
  if (bRecording && bEnableExport) {
    var frameOutputFilename = myNickname + "_frame_" + nf(nElapsedFrames, 4) + ".png";
    print("Saving output image: " + frameOutputFilename);
    saveCanvas(theCanvas, frameOutputFilename, 'png');
    nElapsedFrames++;
 
    if (nElapsedFrames >= nFramesInLoop) {
      bRecording = false;
    }
  }
}
//===================================================
function renderMyDesign (percent) {
 
  background(13, 60, 85);
  smooth();
  stroke(0, 0, 0);
  strokeWeight(2);
 
  //----------------------
  var e = new p5.Ease(); // easing function object
 
  // percentSig = e.quadraticInOut(percent);
  // console.log(percentSig);
 
  percentSig = percent;
  if(0<=percentSig && percentSig<0.1){
 
    for(var i=0; i<circVals.length; i++){
      var curVal = polarVals[i];
      var curX = curVal[0];
      var curY = curVal[1];
      var curDifferenceX = shearDifferencesPolar[i][0];
      var curDifferenceY = shearDifferencesPolar[i][1];
      var newPerc = map(percent,0,0.1,0,1);
      var e = new p5.Ease(); // easing function object
      newPerc = e.exponentialInOut(newPerc);
      var newX = -1*((curDifferenceX*newPerc)-curX)
      var newY = -1*((curDifferenceY*newPerc)-curY)
      repVals[i] = [newX,newY];
    }
 
 
    for(var i=0; i<circValsHead.length; i++){
      var curVal = polarValsHead[i];
      var curX = curVal[0];
      var curY = curVal[1];
      var curDifferenceX = shearDifferencesPolarHead[i][0];
      var curDifferenceY = shearDifferencesPolarHead[i][1];
      var newPerc = map(percent,0,0.1,0,1);
      var e = new p5.Ease(); // easing function object
      newPerc = e.exponentialInOut(newPerc);
      var newX = -1*((curDifferenceX*newPerc)-curX)
      var newY = -1*((curDifferenceY*newPerc)-curY)
      repValsHead[i] = [newX,newY];
    }
 
  }
 
  else if(.1<=percentSig&& percentSig<0.66){
 
    for(var i=0; i<circVals.length; i++){
      var curVal = shearVals[i];
      var curX = curVal[0];
      var curY = curVal[1];
      var curDifferenceX = shearDifferencesCartesian[i][0];
      var curDifferenceY = shearDifferencesCartesian[i][1];
      var newPerc = map(percent,0.1,0.66,0,1)
      var e = new p5.Ease(); // easing function object
      newPerc = e.quinticInOut(newPerc);
      var newX = -1*((curDifferenceX*newPerc) - curX)
      var newY =  -1*((curDifferenceY*newPerc) - curY)
      repVals[i] = [newX,newY];
    }
 
 
    for(var i=0; i<circValsHead.length; i++){
      var curVal = shearValsHead[i];
      var curX = curVal[0];
      var curY = curVal[1];
      var curDifferenceX = shearDifferencesCartesianHead[i][0];
      var curDifferenceY = shearDifferencesCartesianHead[i][1];
      var newPerc = map(percent,0.1,0.66,0,1)
      var e = new p5.Ease(); // easing function object
      newPerc = e.quinticInOut(newPerc);
      var newX = -1*((curDifferenceX*newPerc) - curX)
      var newY =  -1*((curDifferenceY*newPerc) - curY)
      repValsHead[i] = [newX,newY];
    }
  }
 
  else if(.66<=percentSig&& percentSig<1){
 
    for(var i=0; i<circVals.length; i++){
      var curVal = circVals[i];
      var curX = curVal[0];
      var curY = curVal[1];
      var curDifferenceX = cartesianDifferences[i][0];
      var curDifferenceY = cartesianDifferences[i][1];
      var newPerc = map(percent,0.66,1,0,1)
      var e = new p5.Ease(); // easing function object
      newPerc = e.quadraticInOut(newPerc);
      var newX = (curDifferenceX*newPerc) + curX
      var newY =  (curDifferenceY*newPerc) + curY
      repVals[i] = [newX,newY];
    }
 
    for(var i=0; i<circValsHead.length; i++){
      var curVal = circValsHead[i];
      var curX = curVal[0];
      var curY = curVal[1];
      var curDifferenceX = cartesianDifferencesHead[i][0];
      var curDifferenceY = cartesianDifferencesHead[i][1];
      var newPerc = map(percent,0.66,1,0,1)
      var e = new p5.Ease(); // easing function object
      newPerc = e.quadraticInOut(newPerc);
      var newX = (curDifferenceX*newPerc) + curX
      var newY =  (curDifferenceY*newPerc) + curY
      repValsHead[i] = [newX,newY];
    }
  }
 
 
  for(var i=0; i<repVals.length; i++){
    //console.log((oldVals[i][0]+50),(oldVals[i][1]+50))
    push();
    fill(19, 149, 186);
    stroke(19, 149, 186);
    ellipse((repVals[i][0]+450),(repVals[i][1]+450),2,2);
    pop();
  }
 
 
  for(var i=0; i<repValsHead.length; i++){
    //console.log((oldVals[i][0]+50),(oldVals[i][1]+50))
    push();
    fill(241, 108, 32);
    stroke(241, 108, 32);
    ellipse((repValsHead[i][0]+450),(repValsHead[i][1]+450),5,5);
    pop();
  }
 
  //----------------------
  // Include some visual feedback.
  // fill(255, 0, 0);
  // noStroke();
  // textAlign(CENTER);
  // var percentDisplayString = "" + nf(percent, 1, 3);
  // text(percentDisplayString, 100, 200 - 15);
}

02 – Reading

Here's a major major throwback: Craig Reynolds' Boids

I believe that this project is one of the earliest examples of effective complexity in digital and generative art - where simple rules create a generative behaviour that ends up becoming a good mixture between order and disorder. In the spectrum between total order and total randomness, I believe that this sits somewhere in the middle, which is what makes it so effective. Though this slide can be adjusted depending on the number of boids in the system, and the complexity of the rules being followed.

The Problem of Postmodernity

This problem hits closest to home for me, as someone who is an acute observer/believer in the postmodern phenomenon. The shift away from modernist top-down approaches (where the whole must resemble the parts, or the theory of composition) to the postmodern beliefs of bottom-up generation, complex systems and chaos theory hold more truth in the contemporary world, especially one where technology plays such a decisive role. The world unfortunately just is not that coherent anymore.