chaine-viewing04

Spectacle vs. speculation: A spectacle is something commonly associated with the "higher end" while its purpose is more often than not profit-oriented and less about its own awareness. Speculation is more related to the social engagement that is more ambiguous with its goals, but it is focused on the actual content itself (radicality, relativity, disempowerment, etc.) rather than for an ulterior motive.

One of my previous looking outwards project describes the AIBO (or Artificial Intelligence Robot). Although at first, I assumed it would be more related to being a spectacle in its mass production and appeal to the crowd (design and functionality wise), I believe it is, in a way, both a spectacle and speculation. I think it's inherently tied with speculation in that the AIBO soccer matches were started as a way to further AI technology, with groups around the world participating on advancing their own AIBOs to improve and share information with others. Acceleration: The AIBO are constantly being renewed and improved not just from one company, but by other groups and individuals across the world. Visibility: They are creating events like the soccer tournaments to raise awareness of AI technology. Surplus: Each generation of AIBOs have the potential to be further renovated by others; nothing is "wasted". Commerce: Production of AIBOs were created with its introductory goal being commerce.

chaine-clock

My actual clock:

When I was working on sketching ideas for this assignment last Friday during class, I struggled quite a bit. I think I had too many ideas that were too different. I thought of incorporating trees and seasons, planets and its rotations, but I found myself constantly at a block that I couldn't get past. Throughout the week I pondered about time and I think I put too much pressure on time being a grandiose thing that needed a counterpart grandiose object to represent it. I took myself away from that thought and reflected upon my time spent living in a new building for the fall semester. My kitchen sink had had a leak in it and my parents and I had to put a container under it for the first few days to prevent it from spilling out everywhere. After it was filled, we'd empty it and the cycle began again. I decided to incorporate that as my clock to represent time in my own trivial, personal way.

Clock at 1:39 AM to 1:40 AM:

Clock at 10:02 PM:

Clock at 11:59 AM to 12 PM (you can see a small light green square forming on the lower middle with each new hour):

function setup(){
// Simple p5.js Clock Template
// Golan Levin, 2016
 
var prevSec;
var prevMin;
var prevHour;
var millisRolloverTime;
var secRolloverTime;
var hourRolloverTime;
var cubeList;
var x = [];
var squareSize;
 
//--------------------------
function setup() {
  createCanvas(400, 650);
  millisRolloverTime = 0;
  secRolloverTime = 0;
  hourRolloverTime = 0;
  cubeList = [];
  squareSize = 15;
  for (var k = 0; k < 24; k++){
    randomX = int(random(35, width - squareSize - 20));
    randomY = int(random(200, height - squareSize - 20));
    append(x, randomX);
    append(x, randomY);
    append(x, int(random(0,230)));
    append(x, int(random(0,230)));
    append(x, int(random(0,230)));
    append(x, int(random(1, 9)));
    append(cubeList, x);
    x = [];
  }
  print(cubeList);
}
//--------------------------
 
//--------------------------
function draw() {
  background(255,255,255,150); // My favorite pink
 
  // Fetch the current time
  var H = hour();
  var M = minute();
  var S = second();
 
  // Reckon the current millisecond, 
  // particularly if the second has rolled over.
  // Note that this is more correct than using millis()%1000;
  if (prevSec != S) {
    millisRolloverTime = millis();
  }
  prevSec = S;
 
  if (prevMin != M) {
    secRolloverTime = millis();
  }
  prevMin = M;
 
  if (prevHour != H) {
    hourRolloverTime = millis();
  }
  prevHour = H;
 
  var smoothMin = floor(millis() - secRolloverTime);
  var mils = floor(millis() - millisRolloverTime);
  var smoothHour = floor(millis() - hourRolloverTime);
 
  //var leftMinDiv = map(height, 0, 800, 
 
 
  //fill(128,100,100);
  //text("Hour: "   + H, 10, 22);
  //text("Minute: " + M, 10, 42);
  //text("Second: " + S, 10, 62);
  //text("Millis: " + mils, 10, 82);
  //text("SmoothHour: " + smoothHour, 10, 102);
 
  var hourBarWidth   = map(H, 0, 23, 0, width);
  var minuteBarWidth = map(M, 0, 59, 0, width);
  var secondBarWidth = map(S, 0, 59, 0, width);
 
  // Make a bar which *smoothly* interpolates across 1 minute.
  // We calculate a version that goes from 0...60, 
  // but with a fractional remainder:
  var secondsWithFraction   = S + (mils / 1000.0);
  var secondsWithNoFraction = S;
  var secondBarWidthChunky  = map(secondsWithNoFraction, 0, 60, 0, width);
  var secondBarWidthSmooth  = map(secondsWithFraction,   0, 60, 0, width);
  var smoothMinFraction = M + secondsWithFraction;
  var smoothMinBar = map(smoothMinFraction, 0, (M*60) + 60, 0, width);
 
  //////////
 
  //noStroke();
  //fill(40);
  //rect(0, 100, hourBarWidth, 50);
  //fill(80);
  //rect(0, 150, minuteBarWidth, 50);
  //fill(120);
  //rect(0, 200, secondBarWidthChunky, 50);
  //fill(160);
  //rect(0, 250, secondBarWidthSmooth, 50);
  //fill(200);
  //rect(0, 50, smoothMinBar, 50);
  noStroke();
  var circleSize = 20;
 
  if (mils >= 300){
    var mapping2 = map(mils, 300, 999, 15, (height - (M * 10) - 10));
    fill(255, 153, 153);
    ellipse(width/2, mapping2, circleSize, circleSize);
  }
 
  var hourMap = map(smoothHour, 0, 3600000, height, 190);
  var minMap = map(smoothMin, 0, 60000, 10, 0);
  var minAdj = map(M, 0, 59, height - 15, 180);
 
  beginShape();
  for (var i = 0; i <= width+1; i++) {
    var mapWidth = map(i, i, width, PI, 2*PI); 
    var x = float(i);
    var mapping = map(mils, 0, 500, -PI, 0);
    var bounce = map(mils, 0,999, 9, 0);
    var y = 10 * sin(bounce * mapWidth * 0.1 * mapping) + (height - (M * 10) - 10);
    if (x >= 0 && x <= width+1){
      vertex(x, y);
    }
  }
 
 
  mapTankColR = map(M, 0, 60, 204, 255);
  mapTankColG = map(M, 0, 60, 255, 200);
  mapTankColB = map(M, 0, 60, 255, 200);
 
  fill(mapTankColR, mapTankColG, mapTankColB, 150);
  vertex(width, height);
  vertex(0, height);
  endShape();
 
  var minCount = 5;
 
  //255,200,200
  for (var j = height - 45; j > 50; j -= 50) {
    push();
    fill(128, 100, 100);
    text(minCount, 15, j);
    minCount += 5;
    pop();
  }
 
  for (var j = height - 10; j > 50; j -= 10) {
    push();
    stroke(0,0,0);
    strokeWeight(1);
    line(0, j, 10, j);
    pop();  
  }
 
  if (M == 59 && S == 59) {
    if (H == 23) {
      cubeAppear(0, mils);
    }
    else{
      cubeAppear(H+1, mils);
    }
  }
  for (var hor = 0; hor < H; hor++){
    push();
    var mapRotate = map(mils, 0, 999, 0, 2*PI);
    noFill();
    stroke(cubeList[hor][2],cubeList[hor][3],cubeList[hor][4]);
    rect(cubeList[hor][0] + (squareSize*cos(mapRotate * cubeList[hor][5]))/4, cubeList[hor][1] + (squareSize*sin(mapRotate * cubeList[hor][5]))/4,squareSize,squareSize);
    pop();
  }
  //0 0 153
}
 
function cubeAppear(hour, mils){
  if (hour == 0){
    setup();
    return;
  }
  else{
    noFill();
    strokeWeight(1);
    mapOpp = map(mils, 0, 800, 0, 255);
    stroke(cubeList[hour - 1][2],cubeList[hour - 1][3],cubeList[hour - 1][4], mapOpp);
    rect(cubeList[hour - 1][0],cubeList[hour - 1][1],squareSize,squareSize);
  //for (var cube = 0; cube < cubeList.length; cube++){
  //  push();
  //  noFill();
  //  stroke(cubeList[cube][2],cubeList[cube][3],cubeList[cube][4]);
  //  rect(cubeList[cube][0],cubeList[cube][1],squareSize,squareSize);
  //  pop();
  //}
  }
}

chaine-LookingOutwards02

"Amoeba Dance" by Memo Akten is an interactive sound-reactive installation which features an amoeba-like 3D life form responding to sound in real time. Although the year of creation is ambiguous, a video of the dance was published by Akten in March 2008. I really admire the fact that this project is happening in real-time and it can be a continuous life form until powered off. "Amoeba Dance" is known to use 1ch HD video, a microphone, and custom software.

Although the methods of its algorithmic creations are unknown, I can suppose that Akten played around a lot with geometrics and reflections. In the artist's own words, this was an "exploration of abstract anthropomorphism and unconventional computer generated visuals and 3D aesthetics." Throughout the amoeba's transformations, it still has a sense of balance and likeness even while rotating and changing shape. It's movements, while sometimes rigid and seemingly unpredictable, are actually just following the sound patterns. Loud noises jerk the amoeba forward while it has a constant, slower rotation it follows. Therefore, I would place this piece nearer to being balanced. It moves and transforms in a way that is predictable--less dictated by chaos.

Link to dance below:

http://www.memo.tv/portfolio/amoeba-dance/

chaine-Reading03

I definitely agree with the thinking that there is both first word art and last word art. In my opinion, the two feed off of each other in a way. Variations of already "invented" last word art can evolve to maybe create first word art. Further studies into the field of first word art can generate new interest for new branches of art. The interest in something new and exciting appealing to new artists--the cycle continues.

The new technologies constantly arising may be revolutionary in innovation, convenience, or entertainment. Since those three fields have such dominance over everyone's lives, it is not surprising to see why technologies shape culture. For example, today's prevalence of convenient taxi systems such as Uber or Lyft have almost a culture of its own. Furthermore, technological development can also be shaped by culture. Using the same example as before, the culture today seems to be busier and faster than it used to be. There are always things to do and places to be. Inventions like the Uber was created directly to combat that; being affordable, able to get a ride quickly, and using a trustworthy review system.

 

chaine-AnimatedLoop

When I was first brainstorming ideas for my looping gif, I wanted to involve something "gobstopper-esque" just because of its simple but striking colors. I also somehow wanted to convey bursts of "flavor" and change into my gif, so I already knew from the start that I wanted to use the mapping function a lot on the colors. Looking back, I thought my sketches were very basic and almost too simple. I ended up making it more complicated both to make my gif more interesting and also to test myself. I started off with the given double exponential sigmoid function to drag my gobstopper down from the top to the center of the canvas, but I decided that starting straight from the center looked better because the circle wasn't chopped up in the beginning. Then I used the bounce in, bounce out, and bounce in and out functions to make my gobstoppers pop, and I thought that this function suited how they tasted. And finally, I used the exponential for the circle directly in the center to overtake the canvas as the frames went on. I think I did alright with the color palettes and color changes, but I would have liked to incorporate more functions and more elements to this gif. I also think the way the white circle grows larger is awkward and would like to make it maybe so that it "bounces" like its other circular counterparts and finds a more natural way of clearing the canvas.

// This is a template for creating a looping animation in p5.js (JavaScript). 
// When you press the 'F' key, this program will export a series of images into
// your default Downloads folder. These can then be made into an animated gif. 
// This code is known to work with p5.js version 0.6.0
// Prof. Golan Levin, 28 January 2018
 
// INSTRUCTIONS FOR EXPORTING FRAMES (from which to make a GIF): 
// 1. Run a local server, using instructions from here:
//    https://github.com/processing/p5.js/wiki/Local-server
// 2. Set the bEnableExport variable to true.
// 3. Set the myNickname variable to your name.
// 4. Run the program from Chrome, press 'f'. 
//    Look in your 'Downloads' folder for the generated frames.
// 5. Note: Retina screens may export frames at twice the resolution.
 
 
//===================================================
// User-modifiable global variables. 
var myNickname = "chaine";
var nFramesInLoop = 240;
var bEnableExport = true;
 
// Other global variables you don't need to touch.
var nElapsedFrames;
var bRecording;
var theCanvas;
 
//===================================================
function setup() {
  theCanvas = createCanvas(640, 640);
  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 &amp;&amp; bEnableExport) {
    var frameOutputFilename = myNickname + "_frame_" + nf(nElapsedFrames, 4) + ".png";
    print("Saving output image: " + frameOutputFilename);
    saveCanvas(theCanvas, frameOutputFilename, 'png');
    nElapsedFrames++;
 
    if (nElapsedFrames &gt;= nFramesInLoop) {
      bRecording = false;
    }
  }
}
 
//===================================================
function renderMyDesign (percent) {
  //
  // THIS IS WHERE YOUR ART GOES. 
  // 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. 
  // Use, modify, or delete whatever you prefer from this example. 
  // This example uses several different graphical techniques. 
  // Remember to SKETCH FIRST!
 
  //----------------------
  // here, I set the background and some other graphical properties
  background(255);
  smooth();
  stroke(0, 0, 0);
  strokeWeight(2);
 
  //----------------------
  // Here, I assign some handy variables. 
  var cx = 320;
  var cy = 320;
  noStroke();
  var arcSize = 20;
  var topY = 0 - arcSize - 2;
  var botY = height + 2;
 
    push();
 
    //I ended up not using this because it looked better starting centered
    //var eased = doubleExponentialSigmoid ((percent), 0.7); 
    //eased = (eased)%1.0; 
    //var yPosition2 = map(eased, 0, 1, topY, botY/2); 
 
    var eased2 = exponential (percent*1.2);
    var circleGrow = map(eased2, 0, 2, 0, 600);
    //ellipse (width/2, yPosition2, 20, 20);
 
    var eased3 = bounceInOut (percent * 0.5);
    var circle2Grow = map(eased3, 0, 1, 0, 2000);
 
    var eased4 = bounceInOut (percent * 0.5);
    var circle3Grow = map(eased4, 0, 1, 0, 1500);
 
    var eased5 = bounceInOut (percent * 0.5);
    var circle4Grow = map(eased5, 0, 1, 0, 1000);
 
    var easedLast = exponential (percent);
    var easedGrow = map(easedLast, 0, 1, 0, 1000);
 
    //black arc
    var test = map(percent, 0, 1, 0, 2*PI);
    //neon green arc
    var test1 = map(percent, 0, 1, 0, (3 * PI)/2);
    //light green arc
    var test2 = map(percent, 0, 1, 0, PI);
    //pink arc
    var test3 = map(percent, 0, 1, 0, PI/2);
 
 
    var arcCol1 = map(percent, 0.2, 1, 255, 204);
    var arcCol11 = map(percent, 0.2, 1, 204, 0);
    var arcCol111 = map(percent, 0.2, 1, 229, 102);
 
    //arc 1 light pink 255 204 229 -&gt; 204 0 102
    fill (arcCol1,arcCol11,arcCol111);
    arc(width/2, height/2, 1100*percent,1100*percent,0,test);
 
    var arcCol2 = map(percent, 0.2, 1, 204, 76);
    var arcCol22 = map(percent, 0.2, 1, 255, 153);
    var arcCol222 = map(percent, 0.2, 1, 229, 0);
 
    //arc 2 light green 204 255 229 -&gt; 76 153 0
    fill (arcCol2, arcCol22, arcCol222);
    arc(width/2, height/2, 1100*percent,1100*percent,0,test1);
 
 
    var arcCol3 = map(percent, 0.2, 1, 200, 0);
    var arcCol33 = map(percent, 0.2, 1, 255, 102);
    var arcCol333 = map(percent, 0.2, 1, 200, 102);
 
    //arc 3 200 255 200 -&gt; 0 102 102
    fill (arcCol3, arcCol33, arcCol333);
    arc(width/2, height/2, 1100*percent,1100*percent,0,test2);
 
    var arcCol4 = map(percent, 0.2, 1, 204, 76);
    var arcCol44 = map(percent, 0.2, 1, 229, 0);
    var arcCol444 = map(percent, 0.2, 1, 255, 153);
 
    //arc 4 light blue 204 229 255 -&gt; 76 0 153
    fill (arcCol4, arcCol44, arcCol444);
    arc(width/2, height/2, 1100*percent,1100*percent,0,test3);
 
 
    var circleCol1 = map(eased3, 0, 0.5, 102, 0);
    var circleCol11 = map(eased3, 0, 0.5, 178, 0);
    var circleCol111 = map(eased3, 0, 0.5, 255, 0);
 
    //center circle 1 pink 255 102 178
    fill (circleCol111,circleCol1,circleCol11); 
    ellipse (width/2, height/2, circle2Grow, circle2Grow); 
 
    var circleCol2 = map(eased4, 0, 0.75, 255, 0);
    var circleCol22 = map(eased4, 0, 0.75, 102, 0);
    var circleCol222 = map(eased4, 0, 0.75, 255, 0);
 
    //center circle 2 lighter pink 255 102 255
    fill (circleCol2, circleCol22, circleCol222); 
    ellipse (width/2, height/2, circle3Grow, circle3Grow); 
 
    var circleCol3 = map(eased5, 0, 1, 255, 0);
    var circleCol33 = map(eased5, 0, 1, 204, 0);
    var circleCol333 = map(eased5, 0, 1, 255, 0);
 
    //center circle 2 lightest pink 255 204 255
    fill (circleCol3, circleCol33, circleCol333); 
    ellipse (width/2, height/2, circle4Grow, circle4Grow); 
 
 
    var circleCol0 = map(easedLast, 0.1, 0.15, 200, 255);
    var circleCol00 = map(easedLast, 0.1, 0.15, 200, 255);
    var circleCol000 = map(easedLast, 0.1, 0.15, 200, 255);
 
    //center circle 2 white
    fill (circleCol0, circleCol00, circleCol000); 
    ellipse (width/2, height/2, easedGrow, easedGrow); 
 
 
    pop();
 
}
 
 
// Symmetric double-element sigmoid function ('_a' is the slope)
// See https://github.com/IDMNYU/p5.js-func/blob/master/lib/p5.func.js
// From: https://idmnyu.github.io/p5.js-func/
//===================================================
function doubleExponentialSigmoid (_x, _a){
  if(!_a) _a = 0.75; // default
 
  var min_param_a = 0.0 + Number.EPSILON;
  var max_param_a = 1.0 - Number.EPSILON;
  _a = constrain(_a, min_param_a, max_param_a);
  _a = 1-_a;
 
  var _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);
}
 
function exponential (_x){
  return((_x == 0.0) ? _x : pow(2, 10 * (_x - 1)));
}
 
function bounceIn (_x){
  return(1 - this.bounceOut(1 - _x));
}
 
function bounceOut (_x){
    if(_x &lt; 4/11.0)
    {
      return((121 * _x * _x)/16.0);
    }
    else if(_x &lt; 8/11.0)
    {
      return((363/40.0 * _x * _x) - (99/10.0 * _x) + 17/5.0);
    }
    else if(_x &lt; 9/10.0)
    {
      return((4356/361.0 * _x * _x) - (35442/1805.0 * _x) + 16061/1805.0);
    }
    else
    {
      return((54/5.0 * _x * _x) - (513/25.0 * _x) + 268/25.0);
    }
}
 
function bounceInOut (_x){
      if(_x &lt; 0.5)
    {
      return(0.5 * this.bounceIn(_x*2));
    }
    else
    {
      return(0.5 * this.bounceOut(_x * 2 - 1) + 0.5);
    }
}
 
function exponentialEmphasis (_x, _a){
    if(!_a) _a = 0.25; // default
 
    var min_param_a = 0.0 + Number.EPSILON;
    var max_param_a = 1.0 - Number.EPSILON;
    _a = constrain(_a, min_param_a, max_param_a);
 
    if (_a &lt; 0.5) {
      // emphasis
      _a = 2*(_a);
      var _y = pow(_x, _a);
      return(_y);
    }
    else {
      // de-emphasis
      _a = 2*(_a-0.5);
      var _y = pow(_x, 1.0/(1-_a));
      return(_y);
    }
}

chaine-Scope

My zoetrope was the main reason behind my looping gif. I wanted to mostly play around with circles and how multiple circles can create different illusions. For example, a growing and shrinking circle can look like a person blinking. Incorporating multiple circles growing at different speeds can give off an alien feel and it could look like a signal receiver. I decided to use part of the template of the elongating ellipse to create the shadow at the base depending on the "growth" of the circle while it was bouncing and being enveloped by two larger circles.

/*
// 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 p5.js, September 2018 * Golan Levin 
 
*/
 
var inch = 72.0; 
var diamArtInner = inch * 1.50; 
var diamArtOuter = inch * 4.80; 
var diamCutInner = inch * 1.41; 
var diamCutOuter = inch * 4.875; 
var holeDy = inch * 0.23;
var holeDx = inch * 0.20;
var holeD = inch * 0.1;
 
var nFrames = 10; 
var myFrameCount = 0;
var exportFrameCount = 0; 
 
var bAnimate = true;
var bExportFrameImages = false;
var bRecordingSinglePNG = false;
 
//-------------------------------------------------------
function setup() {
  createCanvas(792, 612); // 11x8.5" at 72DPI
  frameRate(20);
  smooth();
} 
 
 
//-------------------------------------------------------
function draw() {
  background(240); 
 
  // Do all the drawing. 
  push(); 
  translate(width/2, height/2);
  drawCutLines(); 
  drawGuides(); 
  drawAllFrames();
  pop();
 
 
  if (bExportFrameImages){
    // Note that myFrameCount is incremented elsewhere.
    var filename = "myZoetrope_" + nf(myFrameCount,2) + ".png";
    saveCanvas(filename, 'png');
    if (myFrameCount &gt;= nFrames){
      bExportFrameImages = false;
    }
  }
 
 
  if (bRecordingSinglePNG) {
    saveCanvas('myPraxinoscope.png', 'png');
    bRecordingSinglePNG = false;
  }
}
 
 
//-------------------------------------------------------
function keyPressed() {
  switch (key) {
  case ' ': 
    // Press spacebar to pause/unpause the animation. 
    bAnimate = !bAnimate;
    break;
 
  case 'p':
    case 'P':
      // Press 'p' to export a single PNG for the Zoetrope. 
      // Note: This is for 17x11" paper! 
      // Be sure to print at 100%!
      bRecordingSinglePNG = true;
      break;
 
    case 'f':
    case 'F':
      // Press 'f' to export multiple frames 
      // (in order to make an animated .GIF)
      // such as with http://gifmaker.me/
      myFrameCount = 0;
      exportFrameCount = 0;
      bExportFrameImages = true;
      bAnimate = true;
      break;
  }
}
 
//-------------------------------------------------------
function drawCutLines() {
  fill(0); 
  textAlign(CENTER, BOTTOM); 
  text("Praxinoscope Template", 0, 0-diamCutOuter/2-6); 
 
  stroke(0); 
  strokeWeight(1.0);
 
  noFill(); 
  if (!bRecordingSinglePNG) {
    fill(255); 
  }
  ellipse(0, 0, diamCutOuter, diamCutOuter);
 
  noFill(); 
  if (!bRecordingSinglePNG) {
    fill(240); 
  }
  ellipse(0, 0, diamCutInner, diamCutInner);
 
  noFill(); 
  ellipse(diamCutOuter/2 - holeDx, 0-holeDy, holeD, holeD); 
 
  line (diamCutInner/2, 0, diamCutOuter/2, 0);
}
 
//-------------------------------------------------------
function drawGuides() {
  // This function draws the guidelines. 
  // Don't draw these when we're exporting the PNG. 
  if (!bRecordingSinglePNG) {
 
    noFill(); 
    stroke(128); 
    strokeWeight(0.2); 
    ellipse(0, 0, diamArtInner, diamArtInner); 
    ellipse(0, 0, diamArtOuter, diamArtOuter);
 
    for (var i=0; i&lt;nFrames; i++) {
      var angle = map(i, 0, nFrames, 0, TWO_PI); 
      var pxi = diamArtInner/2 * cos(angle);
      var pyi = diamArtInner/2 * sin(angle);
      var pxo = diamArtOuter/2 * cos(angle);
      var pyo = diamArtOuter/2 * sin(angle);
      stroke(128); 
      strokeWeight(0.2);
      line (pxi, pyi, pxo, pyo);
    }
 
    // Draw the red wedge outline, highlighting the main view.
    var redWedge = 7; // assuming nFrames = 10
    for (var i=redWedge; i&lt;=(redWedge+1); i++) {
      var angle = map(i, 0, nFrames, 0, TWO_PI); 
      var pxi = diamArtInner/2 * cos(angle);
      var pyi = diamArtInner/2 * sin(angle);
      var pxo = diamArtOuter/2 * cos(angle);
      var 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);
    var startAngle = redWedge*TWO_PI/nFrames;
    var endAngle = (redWedge+1)*TWO_PI/nFrames;
    arc(0, 0, diamArtInner, diamArtInner, startAngle, endAngle); 
    arc(0, 0, diamArtOuter, diamArtOuter, startAngle, endAngle); 
 
 
    for (var i=0; i&lt;nFrames; i++) {
      var angle = map(i, 0, nFrames, 0, TWO_PI); 
 
      push();
      rotate(angle); 
      var 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); 
 
      pop();
    }
  }
}
 
//-------------------------------------------------------
function drawAllFrames() {
  for (var i=0; i&lt;nFrames; i++) {
    var angle = map(i, 0, nFrames, 0, TWO_PI); 
    var originY = ((diamArtOuter + diamArtInner)/2)/2;
 
    push();
    rotate(angle); 
    translate(0, 0-originY); 
    scale(0.8, 0.8); // feel free to ditch this 
 
    var whichFrame = i; 
    if (bAnimate) {
      whichFrame = (i+myFrameCount)%nFrames;
    }
    drawArtFrame (whichFrame); 
    // drawArtFrameAlternate (whichFrame); 
 
    pop();
  }
  myFrameCount++;
}
 
 
//-------------------------------------------------------
function drawArtFrame ( 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!
 
  push();
  fill(0); 
  noStroke(); 
 
  // Draw a pulsating ellipse
 
  //draw the shadow
  noStroke();
  fill(150,150,150);
  var t = map(whichFrame, 0, nFrames, 0, 1); 
  var shadow = map(cos(t*TWO_PI), 1, -1, 10, 30); 
  ellipse(0, 45, shadow, shadow*0.5);
 
 
  noFill(); 
  stroke(0);
  strokeWeight(1); 
 
  var diam = map(cos(t*TWO_PI), -1, 1, -30, 50); 
 
  //first circle (biggest)
  var ell1 = map(cos(t * TWO_PI), 1, -1, 17, (30*(whichFrame/3)));
  ellipse(0, diam, ell1, ell1);
 
  //second circle (second biggest)
  var ell2 = map(cos(t * TWO_PI), 1, -1, 16, (30*(whichFrame/4)));
  ellipse(0, diam, ell2, ell2);
 
  //center black circle
  fill(0);
  var diam2 = map(cos(t * TWO_PI), 1, -1, 15, 30);
  ellipse(0, diam, diam2, diam2);
  pop();
 
}
 
//-------------------------------------------------------
function drawArtFrameAlternate( 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); 
    var nL = 10;
    for (var i=0; i&lt;nL; i++) {
      var a = HALF_PI + map(i, 0, nL-1, 0, TWO_PI);
      var cx = 12 * cos(a);
      var cy = 10 * sin(a); 
      var dx = 16 * cos(a);
      var 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
  var t = map(whichFrame, 0, nFrames-1, 0, 1); 
  var t2 = pow(t, 2.0); 
  var rh = 8 + whichFrame * 0.5; // wee stretch
  var ry = map(t2, 0, 1, 0, 100-rh) - 50; 
 
  noStroke(); 
  fill(0, 0, 0);
  rect(-5, ry, 10, rh);
}

chaine-Reading02

Question 1A: I had already known before reading this that there was a complexity to biological life that seemed generated or highly ordered, but I really enjoyed reading about this scale of total order and randomness. When thinking of an example, my mind automatically goes to the appearance of the golden ratio in nature. For example, these flower heads:

And plenty of other examples from https://io9.gizmodo.com/5985588/15-uncanny-examples-of-the-golden-ratio-in-nature.

In terms of its effective complexity, disregarding its microscopic, structured atoms, it also displays a highly structured form. This example would be closer to total order, near crystal lattices.

Question 1B: "The Problem of Dynamics" is something I am currently struggling with. I always question what defines a certain subset within art. I always feel like generative art is art that is constantly "generating" itself, but I think that generation can also happen behind the scenes. For example, while a piece of code is in the process of generating art, it is still generating. 

 

chaine-Interruptions

  1.  The lines' centers can be split into a grid system
  2.  All angles are randomized
  3.  White or light grayish background with black lines
  4. The overall shape of the canvas is a square but some lines may protrude a bit more
  5.  There are clutters of gaps that seem to happen in random locations
  6.  The gaps are usually clumped together and are missing more than one line per gap
  7.  Each gap seem to form into random shapes (not just a circle, square, etc.)
  8.  The gaps are of varying sizes
  9.  The length of each line is the same
  10.  There is a very small margin surrounding the lines

Image from Gyazo

 

var boolDoRefresh;
var size = 40;
var gridSpacing = 12; 
var lineLength = 20;
var angleList = [];
var startAngle = 0;
 
//Things to consider while creating "gaps":
//how many gaps?
//how large are the gaps?
//which row/col are the gaps located?
 
var gapList = [];
 
function setup(){
  createCanvas(720,720);
  boolDoRefresh = true;
  var slant = random(0,1);
  var isVertical = random(0,1);
  for (var i = 0; i &lt; width + lineLength; i += gridSpacing){
    for (var j = 0; j &lt; height + lineLength; j += gridSpacing){
    if (isVertical &lt; 0.5){
      append(angleList, random(-1*PI, PI)); //angle of line horizontal
    }
    else{
      append(angleList, random(-1*PI, PI) + (PI)); //angle of line vertical
    }
  }
  }
  createGaps();
}
 
function createGaps(){
  var gridSlots = sq(round(((width + lineLength + 1)/gridSpacing)))
  var numGap = int(random(3,15));
  for (var k = 0; k < numGap; k += 1){
    gapList = append(gapList, int(random(1, gridSlots)));
    gapSize = int(random(10,80));
    for (var m = 1; m < gapSize; m += 1){
      chance = random(0,1);
      if (random(0,1) < 0.8){
        if (chance < 0.4){
          append(gapList, gapList[m-1] + 1);
        }
        else{
          append(gapList, gapList[m-1] - 1);
        }
      }
      else{
        if (chance < 0.6){
          append(gapList, gapList[m-1] + 59);
        }
        else{
          append(gapList, gapList[m-1] - 59);
        }
      }
      for (var n = 0; n < gapList.length; n += 1){
        angleList[gapList[n]] = 1000;
      }
    }
    gapList = [];
  }
}
 
function draw(){
  if (boolDoRefresh){
    for (var i = lineLength; i &lt; width - lineLength; i += gridSpacing){
      for (var j = lineLength; j &lt; height - lineLength; j += gridSpacing){
        strokeWeight(1);
        //ellipse(i,j, 5,5);
        var angle = angleList[startAngle];
        if (angle &lt; 999){
          //I gave each line their own little "squares" on a grid of W x H
          //Each grid consists of two lines, one line is a reflection of the other line
          //Both lines start at the center of their "squares"
          //Thus, the two lines together look like one line
          line(i, j , i+(lineLength/2)*cos(angle), j+(lineLength/2)*sin(angle));
          line(i, j , i+(lineLength/2)*cos(angle+PI), j+(lineLength/2)*sin(angle+PI));
        }
        startAngle += 1;
      }
    }
  }
  boolDoRefresh = false;
}
 
function mousePressed(){
  boolDoRefresh = true;
  angleList = [];
  startAngle = 0;
  gapList = [];
  setup();
}

I started this project by realizing that there was some sort of grid system with a randomized, angled line in each grid unit. I first decided to code the overall grid without any gaps, but realized that too many of the lines started to look like they were forming messy clusters. (e.g. one grid unit had a line pointing to the right and the very next grid unit to the right was pointing left and it just looked like two lines on top of each other) Therefore, I decided to give each line their own square "space" by drawing two lines to look like one. I first drew half of a line starting from the center of a grid unit and reflected it to draw the other half. That worked out much better. Meanwhile, for randomizing the gaps, I sketched out what I needed to know: how many gaps, how large each gap is, where the gap is. I learned that what I thought was random was clearly showing that it didn't feel as random in real life. There were sometimes columns of missing lines and I struggled to find the right proportion of hiding the aforementioned patterns. I learned through this that coding was a test of trial and error and logic. What may seem logically sound on paper may not look it in the actual product. The fact that Vera Molnár created this piece fascinated and inspired me, especially given the time period in which she created this.

 

chaine-Intersections

Image from Gyazo
Image from Gyazo

  var boolDoRefresh;
  var size = 40;
  var lineLength = 300;
  var numLines = 12;
  var lineList = [];
  var x = [];
  //var circleCoords = [];
  //var circleList = [];
  //var foo = 0;
 
  function setup(){
    createCanvas(728, 480);
    background(255,255,255);
    boolDoRefresh = true;
    for (var i = 0; i &lt; numLines; i ++){
      append(x, int(random(150, width - 150))); //starting x
      append(x, int(random(150, height - 150))); //starting y
      append(x, int(random(0, 361))); //angle of line
      append(lineList, x);
      x = [];
    }
  }
 
  function draw(){
    if (boolDoRefresh == true){
      for (var j = 0; j &lt; lineList.length; j++){ //drawing where the circles should be
        var a1 = lineList[j][0];
        var b1 = lineList[j][1];
        var angle2 = lineList[j][2];
        var a2 = a1+lineLength*cos(angle2);
        var b2 = b1+lineLength*sin(angle2);
        for (var k = 0; k &lt;lineList.length; k++){ 
          var a3 = lineList[k][0];
          var b3 = lineList[k][1]; 
          var angle3 = lineList[k][2]; 
          var a4 = a3+lineLength*cos(angle3); 
          var b4 = b3+lineLength*sin(angle3); 
          //This long formula was taken from http://www-cs.ccny.cuny.edu/~wolberg/capstone/intersection/Intersection%20point%20of%20two%20lines.html 
          //Paul Bourke's paper 
          if (((b4-b3)*(a2-a1)-(a4-a3)*(b2-b1))!=0){ 
            var ta = ((a4-a3)*(b1-b3)-(b4-b3)*(a1-a3))/((b4-b3)*(a2-a1)-(a4-a3)*(b2-b1)); 
            var tb = ((a2-a1)*(b1-b3)-(b2-b1)*(a1-a3))/((b4-b3)*(a2-a1)-(a4-a3)*(b2-b1)); } 
          else { 
            ta = -1; tb = -1;
          } 
          if (ta &gt;= 0 &amp;&amp; ta &lt;= 1 &amp;&amp; tb &gt;= 0 &amp;&amp; tb &lt;= 1){
            fill(204,229, 255);
            strokeWeight(0);
            ellipse((a1+ta*(a2-a1)),(b1+ta*(b2-b1)), 20);
          }
          else{
            continue;
          }
        }
 
	fill(255,255,255);
	strokeWeight(0.1);
	for (var i = 0; i &lt; numLines; i++){
          var x1 = lineList[i][0];
          var y1 = lineList[i][1];
          var angle = lineList[i][2];
          //below formula from https://stackoverflow.com/questions/48525583/get-a-points-position-from-an-angle-and-the-length-of-the-line
          line(x1, y1, x1+lineLength*cos(angle), y1+lineLength*sin(angle));
          //append(lineList[i], x1+lineLength*cos(angle));
          //append(lineList[i], y1+lineLength*sin(angle));
	}
        //print(a2,b2);
        //print(lineList);
        //print(ta, tb);
      }
    }
    boolDoRefresh = false;
  }
 
  function mousePressed(){
    boolDoRefresh = true;
    x = [];
    lineList = [];
    setup();
  }

chaine-IterationExercise

Image from Gyazo

var boolDoRefresh;
var size = 40;
 
function setup(){
  createCanvas(400,400);
  boolDoRefresh = true;
}
 
function draw(){
  if (boolDoRefresh){
    for (var i = 40; i < height-40; i+=40){
      for (var j = 40; j < width-40; j+=40){
        if (random(1) < 0.1){
	  stroke('#fae');
	  strokeWeight(2);
          ellipse(i+18,j+18,30,30);
	  stroke('rgba(0,255,0,0.25)');
	  ellipse(i+18,j+18,15,15);
        }
        else{
	  stroke(color(102, 178, 255));
	  strokeWeight(1);
          rect(i,j,35,35);
	  stroke(color(0, 204, 204));
	  rect(i+7.5,j+7.5,20,20);
        }
      }
    }
  }
  boolDoRefresh = false;
}
 
function mousePressed(){
  boolDoRefresh = true;
}