nannon-LookingOutwards02

I had completely forgotten I had come across Mokafolio years before until Golan presented his work again a couple weeks ago. I had loved the artful, analog quality of his work then, and I still do love it. When I first encountered his work, I had no idea that there was so much technology behind the pieces. I especially love the vending machine pieces because not only are they generative, they are so in a very engaging way. Vending machines are great because the user never knows exactly what they're getting, yet they choose to receive something anyway.

In a lot of the generative art examples, there's a certain "generative art" aesthetic that is extremely telling of how the results are made. I love Mokafolio's work because it's decidedly not that--not that any aesthetic is better or worse than another, I just think in terms of uniqueness, this work stands out (going back to Galanter's Problem of Uniqueness).

nannon-03-clock

 

This is a 24 hour clock that grows back into itself. I actually had a hard time coming up with a solid concept for this project, and it definitely impacted the work. I originally wanted to do a "clock" based on the days of the user's life, with multiple spheres representing each day--spheres would alter in size and color, with different layers representing amount of fulfillment in relationships, work, etc. I had the sphere code from the beginning, but it became hard to scrape data and/or create user input in processing, at which point I decided to scope down. I'm not totally satisfied with =the simplification of the representation of multiple days to just a single day with a sphere, since it falls to close to just a normal clock. However, I like the emphasis on the regrowth visual/symbolism in the piece. Definitely need to focus on scoping down and making sure I have the capabilities for my vision in the next project thank you for the real talk @golan!!

 

 

 

--Process --

playing around with adding spheres (layers) on key pressed (earlier idea).

import peasy.*;
 
PeasyCam cam;
 
int time = 6;
int time2;
 void keyPressed() {
   if (keyCode == UP) {
     time2 = time++%24;
     println(time2);
   }
   if (keyCode == DOWN) {
     time2 = time--%24;
   }
 }
 
 
PVector[][] globe;
int total = 72;
float[][] firsts = new float[total+1][3];
float[][] lasts =  new float[total+1][3];
 
 
 
void setup() {
  size(640, 640, P3D);
  cam = new PeasyCam(this, 500);
  globe = new PVector[total+1][total+1];
 
 
}
 
void draw() {
 
 
 
  //println(hour());
  background(255);
  pushMatrix();
  textSize(20);
 
  fill(100);
 
  text(str(time2)+":00", -30,300);
  popMatrix();
  noFill();
  stroke(240);
  lights();
  float smallRad = map(time2*3, 0, 72,0,200);
  sphere(smallRad);
 
  float r = 200;
  for (int i = 0; i < total+1; i++) {
    float lat = map(i, 0, total, 0, PI);
    for (int j = 0; j < total+1; j++) {
      float lon = map(j, 0, total, 0, TWO_PI);
      float x = r * sin(lat) * cos(lon);
      float y = r * sin(lat) * sin(lon);
      float z = r * cos(lat);
      globe[i][j] = new PVector(x, y, z);
    }
  }
 
  for (int i = 0; i < total; i++) {
    beginShape(TRIANGLE_STRIP);
    int curHour= 72-(time2*72)/24;
    //println(curHour);
    for (int j = 0; j < curHour; j++) {
 
      PVector v1 = globe[i][j];
      vertex(v1.x, v1.y, v1.z);
      PVector v2 = globe[i+1][j];
      vertex(v2.x, v2.y, v2.z);
      if (j==0) {
        firsts[i][0] = v1.x;
        firsts[i][1] = v1.y;
        firsts[i][2] = v1.z;
      }
      if (j==curHour-1) {
        lasts[i][0] = v2.x;
        lasts[i][1] = v2.y;
        lasts[i][2] = v2.z;
      }
 
    }
    endShape();
  }
 
  fill(100);
  beginShape();
  vertex(0,0,0);
  for (int i=0; i < total; i++) {
    vertex(firsts[i][0], firsts[i][1], firsts[i][2]);
  }
   vertex(0,0,cos(72)*200);
  endShape();
 
  fill(100);
  beginShape();
  vertex(0,0,0);
 vertex(firsts[0][0], firsts[0][1], firsts[0][2]);
  for (int i=0; i < total; i++) {
    vertex(lasts[i][0], lasts[i][1], lasts[i][2]);
  }
  //vertex(firsts[0][0], firsts[0][1], firsts[0][2]);
  vertex(0,0,cos(2*PI)*r);
  endShape();
 
 
}

nannon-Reading-02

1A: Effective Complexity--Kyuha Shim's Generative Typography

In the past two years (mostly), I've become very interested in typography, how it moves and how it scales. However, it wasn't until last year that I really encountered Kyu's work as his student in his Computational Design class. Kyu's work in generative typography has greatly effected and also falls in line with broad movements towards parametric design in the visual design world. I love this work because it gives the very language and content of our world character and movement, engages the viewer in completely new ways. In terms of Galanter's article, I would say that this kind of generative typography, that is, typography that changes based on external input(s), still definitely leans towards order (crystal lattice). No matter what, typography is still driven by language/linguistics, and whatever alphabet its shape is taking. That line is extremely concrete. However, I love that it finally is offering a source of variation within the previously static world of type.

Peep it here: http://generativetypography.com/

1B: The problem of uniqueness

"Whether in the context of market value or cultural value, traditional works of art have been treasured as unique and thus rare objects. "

"Digital generative art introduces a completely new problem: rather than offering an endless supply of copies, it provides an endless supply of original and unique artifacts. "

Generative art is by nature repetitive in some way, and I don't believe the same problem of uniqueness that might arise in non-generative art can apply, at least without differentiation. When it comes to generative art, I believe that the more important point/source of uniqueness is the generator (code, etc), not the generated content.

nannon-AnimatedLoop

end of semester edit:

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

Final:

A few iterations:

 

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

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

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

// This is a template for creating a looping animation in Processing/Java. 
// When you press the 'F' key, this program will export a series of images
// into a "frames" directory located in its sketch folder. 
// These can then be combined into an animated gif. 
// Known to work with Processing 3.3.6
// Prof. Golan Levin, January 2018
import geomerative.*;
 
RFont f;
RShape fire;
RPoint[] points;
RShape[] letterShapes;
//===================================================
// Global variables. 
String  myNickname = "nannon"; 
int     nFramesInLoop = 120;
int     nElapsedFrames;
boolean bRecording; 
 
//===================================================
void setup() {
  size (640, 640, P3D); 
  lights();
  background(0);
  bRecording = false;
  nElapsedFrames = 0;
 
  RG.init(this);
  fire = RG.getText("x", "Optimo.ttf", 72, CENTER);
 
  RG.setPolygonizer(RG.UNIFORMLENGTH);
  RG.setPolygonizerLength(1);
  fill(255);
 
  letterShapes = fire.children;
 
 
  smooth();
}
//===================================================
void keyPressed() {
  if ((key == 'f') || (key == 'F')) {
    bRecording = true;
    nElapsedFrames = 0;
  }
}
 
//===================================================
void draw() {
 
  // Compute a percentage (0...1) representing where we are in the loop.
  float percentCompleteFraction = 0; 
  if (bRecording) {
    percentCompleteFraction = (float) nElapsedFrames / (float)nFramesInLoop;
  } else {
    percentCompleteFraction = (float) (frameCount % nFramesInLoop) / (float)nFramesInLoop;
  }
 
  // Render the design, based on that percentage. 
  renderMyDesign (percentCompleteFraction);
 
  // If we're recording the output, save the frame to a file. 
  if (bRecording) {
    saveFrame("frames/" + myNickname + "_frame_" + nf(nElapsedFrames, 4) + ".png");
    nElapsedFrames++; 
    if (nElapsedFrames >= nFramesInLoop) {
      bRecording = false;
    }
  }
}
 
//===================================================
void renderMyDesign (float percent) {
  //
  background(0);
  translate(320, 320, 200);
  rotateX(PI);
  rotateY(map(percent,0,1,0,PI/2));
  rotateZ(sin(PI));
  stroke(255);
  noFill(); 
 
 
  int r= 100;
  int nSlices = 50;
  int zA = -20;
  int zB = 20;
 
 
 
 
 
  rotateY(PI/2);
  rotateX(PI/2);
  noFill();
 
  // draw a cylinder
  noFill(); 
  stroke(255); 
  beginShape(TRIANGLE_STRIP);
  for (int i=0; i<=nSlices; i++) {
    float theta = map(i, 0, nSlices, 0, 2*PI);
    float pX = r*cos(theta);
    float pY = r*sin(theta);
    vertex(pX, pY, zA);
    vertex(pX, pY, zB);
  }
  endShape();
 
  // print("x1:"+points[0].x+" "+"y:"+ points[0].y+"    ");
  // print("x2:"+points[points.length-1].x+" "+"y:"+ points[points.length-1].y+"    ");
 
 
 
   //beginShape();
   //for (int i=0; i<points.length; i++) {
   //  float newX = map(points[i].x, -187, 189, 0, 0.6*(2*PI));
   //  float newZ = map(points[i].y, -24, 0, 0, 0.6*(2*PI));
   //  vertex(r*cos(newX), points[i].y, abs(r*cos(newZ)));
 
   //  endShape();
   //}
 
 
 
  noFill(); 
  stroke(255); 
  //int nLetters = 16; 
  //for (int i=0; i<nLetters; i++) {
 
 
 
 
    //int nPointsInThisContour = 16;
    for (int k=0; k<10; k++) {
      pushMatrix();
      float letterTheta = k* radians(45.0);
 
 
      float letterX = r * cos(letterTheta);
      float letterY = r * sin(letterTheta); 
 
 
      //float eased = function_DoubleExponentialSigmoid(percent, 0.7);
      //float newletterY = map(eased, 0,1,0,PI);
 
      translate(letterX, letterY);
      rotateX( radians(90)); 
      rotateY(letterTheta+ radians(90));
 
      fill(255);
      stroke(255);
      beginShape();
      RPoint[] points = letterShapes[0].getPoints();
      for (int j=0; j<points.length; j++) {
 
        //print(points[j].x);
        //float ht = map(j, 0, nPointsInThisContour, 0, TWO_PI); 
        float hpx = points[j].x; 
        float hpy =  points[j].y; 
        float hpz =0;
 
 
        vertex(hpx, hpy, hpz);
 
        //ellipse(hpx,hpy,10,10);
      }
      endShape();
      popMatrix();
    }
 
}
float function_DoubleExponentialSigmoid (float x, float a) {
  // functionName = "Double-Exponential Sigmoid";
 
  float min_param_a = 0.0 + EPSILON;
  float max_param_a = 1.0 - EPSILON;
  a = constrain(a, min_param_a, max_param_a); 
  a = 1-a;
 
  float y = 0;
  if (x<=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;
}

nannon-Scope

Kit Kat Scope

 

Originally, I wanted to do an animation using eyes for my Looping Gif assignment, but I ultimately decided not to. However, since I had a lot of sketches left over from that idea, I put them to use here instead. After drawing the eyes, and having them animate side to side, it actually reminded me a lot of the Kit Kat clocks, which I was belatedly inspired by. The starter code was super helpful, and this assignment was a fun break for the Looping Gif.

 
/*
// 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 >= nFrames){
      bExportFrameImages = false;
    }
  }
 
 
  if (bRecordingSinglePNG) {
    saveCanvas('myPraxinoscope.png', 'png');
    bRecordingSinglePNG = false;
  }
}
 
 
//-------------------------------------------------------
function mouseClicked() {
  console.log(mouseX, mouseY);
}
 
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(250); 
  strokeWeight(1.0);
 
 
  if (bRecordingSinglePNG) {
    fill(0); 
  }
  ellipse(0, 0, diamCutOuter, diamCutOuter);
 
 
  if (bRecordingSinglePNG) {
    fill(0); 
  }
  ellipse(0, 0, diamCutInner, diamCutInner);
 
  fill(255); 
  ellipse(diamCutOuter/2 - holeDx, 0-holeDy, holeD, holeD); 
 
  stroke(240)
  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<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<=(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<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<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!
 
  // Draw the frame number
  fill(0); 
  noStroke(); 
  textAlign(CENTER, CENTER); 
  text (whichFrame, 0, -45);
 
  // Draw eyes
  fill(255); 
  stroke(255);
  strokeWeight(1); 
 
  ellipse(-18, -48, 28,28); 
  ellipse(18, -48, 28,28); 
  ellipse(0,-33,15,10);
 
 
  //draw eye balls
  fill(0);
  noStroke();
  var xAxis = map(whichFrame, 0,nFrames, 0,PI)
  arc(sin(xAxis)*16-18-14+6, -48, 12,12,PI/6,(11*PI)/6, PIE);
 
  arc(sin(xAxis)*16-18-14+6+36 , -48, 12,12,PI/6,(11*PI)/6, PIE);
 
  //clock
  fill(255);
  stroke(255);
  rect(-25,-23, 50, 70, 10);
 
//clock tix
  stroke(0);
  strokeWeight(2 );
  line (0, -13, 0, -18);
 
  line (0, -13, 0, -18);
  line (0, 35, 0, 40);
  line (-18,12, -13,12);
 
   line (18,12, 13,12);
 
  //whiskers 
  stroke(255)
  line (-20,-30, -45,-35);
  line (-20,-25, -45,-20);
  line (20,-30, 45,-35);
  line (20,-25, 43,-20);
 
 
 
 
 
  // Draw some rotating spokes
    var cx = 0; 
    var cy = 12; 
    var u = 0 - map(whichFrame, 0, nFrames, 0, 1);
    var sx = cx + 15 * cos(u * TWO_PI); 
    var sy = cy + 15 * sin(u* TWO_PI); 
    stroke(0); 
 
    line (cx, cy, sx, sy);
 
 
  	var dx = 0; 
    var dy = 12; 
    var u2 = 0 - map(whichFrame, 0, nFrames/2, 0, 1);
    var vx = dx + 20 * cos(u2 * (TWO_PI+1.2)); 
    var vy = dy + 20 * sin(u2* (TWO_PI+1.2)); 
    stroke(0); 
    strokeWeight(1);
    line (dx, dy, vx, vy);
}

nannon-Reading-01

2. The Critical Engineer raises awareness that with each technological advance our techno-political literacy is challenged.

This document struck me immediately as extremely idealistic, though also extremely desirable and hopeful. Though the tone acknowledges the power of computing, it also implies that the original authors know how far technology can take us.

What stood out to me is that about half the tenets could explicitly applied to many other fields, but particularly design. These tenets, including 2,3,6 and 8 especially, are very close to the philosophy over in the School of Design. It's an emphasis on how our built (designed) world is converging more and more with the engineered (digital) world. A huge majority of college graduates in this decade will work in some kind of technological field, and this manifesto applies to anyone who will influence a new product or object.

I believe that engineers who are on the front line literally writing the code that powers almost all our products today should hold these tents close at hand, but others who will be involved with building products should be self-aware of their actions + consequences as well.

The second tenet rings so true in 2018, especially in light of GDPR and the Facebook testimonies. The tech-literacy gap is going to be a shattering crisis soon (if not already), and it's very clear in how government is interacting with private tech companies.

nannon-LookingOutwards-01

 

Deus Ex Machina

Last year, I came across this book Soft & Cuddly, in which Jared Kobek talks about his experience playing his first bootleg video games on a ZX Spectrum. I went home, spent the next few days googling this amazingly intriguing, but now mostly obsolete, system, and found out about a specific game called Deus Ex Machina.

Before getting into DEM specifically, I wanted to mention that I became momentarily obsessed with ZX Spectrum--as someone who's never really played that many video games, I was intrigued by how much had been done by such minimal engineering (relative to today). The artwork was so communicative with just 6 neon bright colors, and the music, as well as creative, unique storytelling was clearly industry-changing (creating?).

Image result for deus ex machina zx spectrum gif

Deux Ex Machina was made in the time when "video game" was still being defined--thus, it functions less as a playable game, and more of an interactive narrative. What inspires most about this game is that it pushed the boundaries of its time by focusing on the narrative and executing that through syncing an audio tape that the player has to pause at critical points throughout. In today's perspective (and even back then), the gameplay is actually quite boring, since you don't actually need to do anything. However, I believe there have been remake(s) of the game since then that are more player-oriented.

The creator of the project, Mel Croucher, had already been known at the time to be quite innovative. He had already had other more successful games under his belt, but felt that the industry over all was "derivative" and that the "concepts were all stale".

nannon-Interruptions

// Starter Code for "Embedded Iteration + Randomness"
var boolDoRefresh;
 
function setup() {
  createCanvas(744, 744);
  background(255,255,255)
  boolDoRefresh = true;
 
}
function findpointcircle(i,j) {
 
    var margin=48
    var square=12
    var r = 8
    // console.log(i,j)
    var midx=margin+((j*square)-(0.5*square))
    var midy=margin+((i*square)-(0.5*square))
 
    var slope = map(i*j, 0,25,0,10)
 
    var deg = randomGaussian(2*PI, 0.7);
 
    var x = midx+(r*sin(deg))
    var y= midy+(r*cos(deg))
    //(x – h)2 + (y – k)2 = r2
    var endx = midx+(r*sin(deg+PI))
    var endy = midy+(r*cos(deg+PI))
    return [x, y, endx, endy]
}
 
 
function draw() {
  if (boolDoRefresh) {
    setup()
    noiseSeed();
    var size=56
    for (i=0; i<size;i++) {
        for (j=0; j<size;j++) { // noiseDetail(5,0.5); var blank = noise(i*0.1+10,j*0.1) var blank2 = noise(i*3+10,j*0.1) // console.log(i*0.02+10, j*0.02, blank) strokeWeight(1); var points =findpointcircle(i,j) if (blank>0.32) {
								line(points[0], points[1], points[2], points[3])
						}
          	else if (blank<=0.25 &&blank2<=0.5) {
              	line(points[0], points[1], points[2], points[3])
            }
        }
    }
    boolDoRefresh = false;
  }
}
 
function mousePressed() {
  boolDoRefresh = true;
}

Observations:
1. The artwork is square.
2. The artwork consists of many short black lines, on a white background.
3. The lines all have the same length
4. It is 56 x 56 lines (I think)
5. The lines have varying random degrees of rotation
6. There is like 3-5% chance of no line drawn
7. The lines don't take up their own space, there is a lot of overlap
8. some of the artworks are "mostly vertical" lines and some are "mostly horizontal" lines
9. There are random blobs of blankness
10. There is a small gradation towards blankness

Reflection:

Gaussian distribution and perlin noise have been words I've been hearing around for a long time now, but have never understood. What was especially hard about this was getting the blanks in the Vera drawings correct. At the end, I still feel like my blanks are shaped a bit too round...to be honest, I still don't really understand how the noise distributions are made. I spent a lot of time inserting random numbers as my "noise scale." I understand the general concept of noise, but will need to technically understand it more. Edit: After posting this, I actually realized that I had forgotten to make sure that the mean angle of the lines changes--every time, the lines in my piece are mostly vertical. However it was satisfying to see how Gaussian distributions are utilized.

nannon-IterationExercise

var boolDoRefresh;
 
function setup() {
  createCanvas(400, 400);
	background(240,240,255);
  boolDoRefresh = true;
}
 
function rando(min, max) {
  min = Math.ceil(min);
  max = Math.floor(max);
  return Math.floor(Math.random() * (max - min)) + min; 
}
 
console.log(rando(0,100))
 
 
 
function draw() {
  if (boolDoRefresh) {
    //margins = 16px
		//box size= 32
		//spacer=16
		setup()
		var margin =16
		var spacer=16
		var boxsize=32
		for (i=0; i<8; i++) {
			for (j=0;j<8;j++) {
				var randomint=rando(0,100)
				var randopercent = rando(5,12)
				var x=margin+j*(spacer+boxsize)
				var y=margin+i*(spacer+boxsize)
				if (randomint<randopercent) {
					ellipse(x+16, y+16, 28,28)
				}
 
				else {
					rect(x, y, boxsize, boxsize)
				}
			}
		}
 
    boolDoRefresh = false;
  }
}
 
function mousePressed() {
  boolDoRefresh = true;
}

nannon-Intersections

 
var boolDoRefresh;
var linelist=[]
var numSlider
 
function setup() {
  createCanvas(720,480);
  boolDoRefresh = true;
}
 
function rando(min, max) {
  min = Math.ceil(min);
  max = Math.floor(max);
  return Math.floor(Math.random() * (max - min + 1)) + min; //The maximum is inclusive and the minimum is inclusive 
}
 
// function findintersection(line1, line2) {
//     return math.intersect(line1[0], line1[1], line2[0], line2[1])
// }
 
function intersect(x1, y1, x2, y2, x3, y3, x4, y4) {
  if ((x1 === x2 &amp;&amp; y1 === y2) || (x3 === x4 &amp;&amp; y3 === y4)) {
    return false
  }
  denominator = ((y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1))
  if (denominator === 0) {
    return false
  }
  let ua = ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / denominator
  let ub = ((x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)) / denominator
  if (ua &lt; 0 || ua &gt; 1 || ub &lt; 0 || ub &gt; 1) {
    return false
  }
  let x = x1 + ua * (x2 - x1)
  let y = y1 + ua * (y2 - y1)
 
  return [x, y]
}
 
function draw() {
  if (boolDoRefresh) {
    var numLines= 15
    background("#FFE6E6");
    linelist=[]
    for (i=0;i&lt;numLines;i++){ var startx= rando(0, width) var starty= rando(0, height) var endx = rando(0, width) var endy = rando(0, height) stroke("#FF0000"); strokeWeight(2); line(startx, starty, endx,endy) linelist.push([[startx,starty],[endx,endy]]) if (linelist.length &gt;1) { 
          for (j=0;j&lt;i; j++) {
            var inter = intersect(linelist[i][0][0], linelist[i][0][1], linelist[i][1][0], linelist[i][1][1], linelist[j][0][0], linelist[j][0][1], linelist[j][1][0], linelist[j][1][1],)
            if (inter) {
              strokeWeight(2)
              fill('rgba(255,0,0, 0.25)')
              ellipse(inter[0], inter[1], 20,20)
            }
          }
      }
    }
    boolDoRefresh = false;
  }
}
 
function mousePressed() {
  boolDoRefresh = true;
}
 
//random function from: 
//https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random
 
//intersect function from:
//http://paulbourke.net/geometry/pointlineplane/javascript.txt