nerual-Clock

 

Between 1am and 8am, BERT-O-CLOCK sleeps, but he can be woken to give you the time. Between 8am and 10am, he sleeps, and he won't wake up. Otherwise, he's awake and keeping time.

And at a very particular time, BERT-O-CLOCK likes to have some fun.

I was really interested in the notion of using hands and fingers to count time, like how small children learn math. This lead me on this path of a childish aesthetic and manner of interaction with the piece. I thought it would be interesting to have this snarky little entity that "keeps" the time. So it "keeps time" by keeping track of what time it is, but sometimes it sleeps, and keeps the time from you that way, and sometimes it sleeps and refuses to wake up. I wanted to capture this sense of time being out of your control, something that seems to act on its own accord. And I think that although this is rather apparent to children, it's something we tend to forget as we grow older.

I think I made the right choice following the whim that lead down this hole. It has some liveliness to it, and I think the tick tock animation at the top was a good touch. I personally think it's fun to interact with, especially if you had this as a small app on your mobile device. It doesn't involve much more than basic javascript functions, and my style ended up being guided by what I could figure out in p5.js. The color scheme is an attempt at something, but the success of that attempt is questionable. The binary representation with the fingers was done more out of practicality than purpose, but it contributes to the frustration I intended the viewer to have with the small creature. Whether that frustration translates to anything, I can't say.

Future Work:

  • make Bert into a mobile app
  • animate his hands going up and down
  • animate his mouth

Sketches:

Code:

var r = 175;
var cx,cy;
var e = 60;
var bop = 3;
var state; //"sleep","snark"
var nappyTime = [1,8];
var snarkTime = [8,9];
var funTime = [2,34,60];
var bodyColor = '#f7786b';
var clicked;
var snarked;
 
var H, M, S, mil;
 
function setup() {
  createCanvas(400,600);
  cx = width/2;
  cy = height;
  console.log("setup complete");
  state = "sleep";
  colorBody();
  clicked = false;
  var snarked = false;
}
 
function draw() {
  H = hour();
  M = minute();
  S = second();
  mil = millis();
  background('#00f5eb');
  //debug();
  if (H==funTime[0] && M==funTime[1])
    party();
  updateState();
  drawBert();
  drawText();
  if (snarked)
    snark();
}
 
function debug(){
  text((S >>> 0).toString(2),width/2, 100);
  text(H + ":" + M + ":" + S ,width/2, 120);
  text(bin(H,2) ,width/2, 140);
}
 
function drawText(){
  var def= "This is a \n BERT-O1-CLOCK.\nHe keeps the time."
  var sleep = "Bert is asleep right now. \nI wonder when he'll wake up...\n Maybe you should poke him?";
  var wake = "He's a 1's and 0's\n kind of guy. Have fun.";
  textFont("Courier New");
  stroke('#fdff5c'); fill('#fdff5c');
  //colorBody();
  textSize(30);
  textAlign(CENTER);
  text(def, width/2, height/5);
 
  stroke('#0'); fill('#0');
  textSize(20);
  if (state=="sleep" || (state=="snark" && !snarked)){
    text(sleep, width/2, height/2);
  }
  else{
    text(wake, width/2, height/2 - 50);
  }
 
  if(S%2==1)
    text("tick", 60,60);
  else
    text("tock", width-60, 60);
 
}
 
function colorBody(){
  fill('#f7786b');
    //fill('#ff5147');
  //fill(255,153,153);
}
 
function getTime(){
  return [hour(), minute(), second()];
}
 
function snark(){
  stroke(255); fill(255);
  textSize(20);
  var snark = "BERT-O1-CLOCK wakes up \n when he damn well pleases."
  text(snark, width/2,height/2);
  snarked = true;
}
 
 
function updateState(){
  var t = getTime();
  var yay = false;
  if (nappyTime[0]<=t[0] && t[0]<=nappyTime[1]){
    if(!clicked)
      state = "sleep";
      snarked = false;
  }
  else if (snarkTime[0]<=t[0] && t[0]<=snarkTime[1]){
    state = "snark";
  }
  else{
    state = "wake";
    snarked = false;
  }
  console.log(state);
}
 
function mousePressed(){
  console.log("click");
  if (state=="wake")
    state="sleep";
  else if (state=="snark"){
    if (!snarked)
      snark();
    else
      snarked = false;
  }
  else
    state="wake";
  clicked = true;
}
 
function party(){
  push();
  background('#f000eb');
  textSize(45);
  textStyle(BOLD);
  colorBody();
  text("IT IS THE HOUR",width/2,60);
  stroke(255); fill(255);
  text("IT IS THE HOUR",width/2+5,60+5);
  rotate(PI/4);
  translate(width/2,-height/2);
  pop();
}
 
 
function calcBop(){
  var t = map(mil, 0, 999, 0, 1);
  var yPos = map(cos(t * TWO_PI), -1, 1, 0, bop);
  translate(0,yPos);
}
 
function drawBert(){
  if (state=="wake")
    drawHands();
  push();
    calcBop();
    drawBody();
  pop();
}
 
function drawBody(){
  //draw boi
  noStroke();
  colorBody();
  ellipse(cx, cy, 2*r, 2*r);
  //draw eyes
  drawEyes();
  drawMouth();
  //nose
  stroke(255);
  strokeWeight(5);
  colorBody();
  var nose = 100;
  arc(cx,cy-r/2+10,nose/2,nose,0,PI);
}
 
function drawEyes(){
  if (state=="wake"){
    noStroke();
    fill(255);
    ellipse(cx-r/2, cy-r/2, e, e/2);
    ellipse(cx+r/2, cy-r/2, e, e/2);
    fill(0);
    ellipse(cx-r/2, cy-r/2, e/2, e/2);
    ellipse(cx+r/2, cy-r/2, e/2, e/2);
  }
  else{
    stroke(255);
    strokeWeight(5);
    noFill();
    arc(cx-r/2, cy-r/2, e, e/2, 0, PI);
    arc(cx+r/2, cy-r/2, e, e/2, 0, PI);
  }
}
 
 
//add to this
function drawMouth(){
  //mouth
  stroke(255);
  strokeWeight(5);
  fill(255);
  if (state=="wake")
    ellipse(cx,cy-r/4+10, r, r/10);
  else
    line(cx-r/4,cy-r/4,cx+r/4,cy-r/4);
 
}
 
function drawHands(){
  rectMode(CENTER);
  noStroke();
      colorBody();
  //left
  push();
  translate(cx-r/3,cy);
  drawHand(1,2); //hr1
  translate(-r/3-10, 0);
  drawHand(1,3); //hr2
  pop();
  //right
  push();
  translate(cx+r/3,cy);
  drawHand(-1, 1);  //min2
  translate(r/3+10,0);
  drawHand(-1, 0); //min1
  pop();
}
 
function bin(p, i){
  var b = (p >>> 0).toString(2);
  if (i >= b.length)
    return '0';
  else
    return b.charAt(b.length-i-1);
}
 
var cap = 10;
var w = 50;
var fw = 10; //finger width
var fcap = 5;
var fl = 60;
var arml = r*3
function drawHand(side, place=5){
  //place=0 - min1
  //place=1 - min2
  //place=2 - hr
  colorBody();
  //arm
  rect(0, 0, w, arml, cap);
  switch (place) {
    case 0:
      drawFinger(3, bin(M,3)==1);
      drawFinger(2, bin(M,2)==1);
      drawFinger(1, bin(M,1)==1);
      drawFinger(0, bin(M,0)==1);
      break;
    case 1:
      drawFinger(3, bin(M,7)==1);
      drawFinger(2, bin(M,6)==1);
      drawFinger(1, bin(M,5)==1);
      drawFinger(0, bin(M,4)==1);
      break;
    case 2:
      drawFinger(3, bin(H,3)==1);
      drawFinger(2, bin(H,2)==1);
      drawFinger(1, bin(H,1)==1);
      drawFinger(0, bin(H,0)==1);
      break;
    case 3:
      drawFinger(3, bin(H,7)==1);
      drawFinger(2, bin(H,6)==1);
      drawFinger(1, bin(H,5)==1);
      drawFinger(0, bin(H,4)==1);
      break;
    case 4:
      drawFinger(3, bin(S,3)==1);
      drawFinger(2, bin(S,2)==1);
      drawFinger(1, bin(S,1)==1);
      drawFinger(0, bin(S,0)==1);
      break;
    default:
      drawFinger(3);
      drawFinger(2);
      drawFinger(1);
      drawFinger(0);
      break;
  }
  //thumb
  push();
  translate(side*w/2,fw-arml/2);
  rotate(-PI/2);
  rect(0,0, fw, fl/2, fcap);
  pop();
}
 
function drawFinger(n,up=true) {
  colorBody();
  noStroke();
  var yPos = -arml/2;
  if (!up) 
    yPos=yPos + 2*fl/5;
  switch(n){
    case 3:
      rect(-w/2+fw/2, yPos, fw, fl, fcap);
      break;
    case 2:
      rect(-w/4+fw/2, yPos, fw, fl, fcap);
      break;
    case 1:
      rect(w/4-fw/2, yPos, fw, fl, fcap);
      break;
    case 0:
      rect(w/2-fw/2, yPos, fw, fl, fcap);
      break;
    default:
      fill(0);
      elllipse(width/2,height/2,100,100);
  }
}

nerual-LookingOutwards02

This project by Melanie Hoff is called "15,000 Volts", showcased in 2015. She hooks a a few alligator clips to  a sheet of wood, and sends (presumably) 15,000 volts through them, letting the electricity generate branching patterns as it find its way through the trees veins. I thought it was interesting because the action of creating it was very simple(just sending ludicrous amounts of electricity through wood), and it was an application of the spirit of generative art to a traditional or craftsman kind of material.  Looking at there other works, this doesn't seem to fit in with their style and interests, but I assume the call back to old craftsmanship, with the sepia tones and material itself, was intentional.

In this project, the algorithm or computer is nature, which means surrendering even more control over what is created. Part of appreciating the work is seeing it be created too. You see the rate at which the branches grow. Who grows first, and in what direction? And eventually some branches thicken as the wood essentially melts. There was an attempt to exercise control in intentionally spacing the clips out, and probably picking out the certain type of wood. For the most part it's a kind of predictable randomness; you know what the general shape looks like, but the subtitles are much more difficult to predict.

Later extensions of this project involve non-conductive materials which force the branches into more specific shapes, using the randomness more for texture than as the main feature.

nerual-Reading03

I have developed a particular fondness for the word "muscular," and I think it is a great way to describe last word art. Perhaps the technique or framework is not novel, but the result it achieves is what ultimately makes it longer lasting and impactful. Yet, I think today's short-attention span with regard to which technologies are "trending," is a good thing. If there are enough ideas out there that are that enticing, then they certainly shouldn't be overlooked. It's like we're in the sketching brainstorming. We haven't explored everything enough to decide which ones are worth really diving super deep into.

I see Homestuck as an example of both first and last word art that has fallen victim to changing times. It is essentially a pseudo text adventure on the internet. The webcomic makes use of gifs, flash animations and games, and convoluted narrative paths to follow through hyperlinks. It wasn't the first of it's kind, but I believe it's one of the most significant because of its scale and fanbase. And at the time it was a pretty novel idea. But today, the time for that kind of sensibility and aesthetic has passed, as evidenced in the direction Homestuck itself is moving now, toward the sleek indie game scene. In that way, I think culture almost holds technology and art hostage, because these things (usually) require an audience, and if you're audience is moving in one direction, how can you not follow them? Perhaps sometimes new technology holds itself hostage in this way, sending the masses in one direction, and being compelled to follow it thereafter.

nerual-Reading02

Question 1A.
I really like clouds. It's interesting that it can be easily represented, but they seem very difficult to model. The cloud itself is a collection of gas molecules distinctly different from the molecules around them, and that system interacts with the weather system, to change the shape of the cloud based on wind, temperature, and humidity. It falls more on the total randomness side, but it isn't quite as random as gas molecules alone.

The Problem of Postmodernity intrigues me because I'm personally a greater fan of more traditional art, and I disagree with the notion that the future of art means neglecting or leaving traditional mediums behind. I'm often more impressed with art that uses old techniques in new ways, rather than new techniques in new ways. But I accept that the prospect of a completely new framework to explore literally any aspect of life is exciting,and part of my reason for taking this class is to become more familiar with that.

nerual-AnimatedLoop

"a cursory moment" (get it?)

Perhaps it isn't worthy of a title, but I would like to informally dub it "A Cursory Moment."

The Process:

Some sketches:

 

I was going to follow up the idea of the mouse and pop signs by making the mouse "click" on a place and then bounce off it, like the force of the click sent it flying.  I got as far as making it move in the right physics-like snapping motion with the elastic function, but I didn't get the mouse to rotate, so I decided to play with contrast and repetition to make it look more interesting instead.

This was actually where I was going to stop:

I thought it looked like the James Bond opening, so I wanted to rotate the finger to make it a finger gun. I ended up with the rotated lines of circles lining up on accident and with some tweaking, I got all circles to line up. I thought it looked more interesting that way.

I felt like this work definitely turned out a lot better than expected(although I expected very little at that point). I like the way the repetition and the appearance of the hand go with the elastic movement. It's kind of rhythmic.

It definitely lacks a lot of the mathematical complexity that I would have liked to explore. The black and white was partially an aesthetic choice and mostly a practical one. The elastic movement is rather sloppy. Overall it's very simple. Way back in the beginning I had hoped to made something more along the lines of, well, lines, and I was really disappointed I couldn't manage to incorporate that at all. I think that with more time however, I definitely could have expanded on the concept or at least made the final product smoother.

I later went back and tweaked it a bit more:

Code (easing function from p5.func):

// based on p5.func examples - easing3_animation
// the sound is from the example
// I<3DM rld 


var ease = new p5.Ease();
var speed = 0.02;
var t = 0.;
var doclear;
var x, y, tx, ty, x1, y1;
var osc, rev;
var pause = 0;
var pauseTime = 60;
var fc=0;
var padding = 20;
var ex1,ey1,ex2,ey2,ex3,ey3,ex4,ey4;
var left,right;
var phase;
var startx,starty;
var radius, mr;
var debug = false;

function setup()
{
  frameRate(70);
  createCanvas(640, 640);
  
  radius = 120;
  mr = radius*0.1;
  
  ex1 = left;
  ey1 = height/5;
  ex2 = right;
  ey2 = height/3 + height/6;
  ex3 = left;
  ey3 = ey2 + height/;
  ey4 = 700;
  
  left = width/4;
  right = 3*left;
  phase = 0;
  
  background(255);

  startx = left;
  starty = -radius;
  x = startx;
  y = starty;
  tx = startx;
  ty = starty;
}

function draw()
{
  background(0);
  drawTheThing();
  if (debug){
    push();
    background(255);
    stroke(255);
    text(frameCount, 20,20);  
    pop();
  }
  if (frameCount > 30 && frameCount < 100 && (frameCount%4 ==0)){
    var filename = "myZoetrope_" + nf(frameCount,2) + ".png";
    saveCanvas(filename, 'png');
  }
}

function doPhase(){
    switch(phase){
      case 0:
        ty = starty;
        tx = left;
        phase++;
        break;
      case 1:
        ty = ey1;
        tx = left;
        phase++;
        break;
      case 2:
        ty = ey2;
        tx = right;
        phase++;
        break;
      case 3:
        ty = ey3;
        tx = left;
        phase++;
        break;
      case 4:
        ty = ey4;
        tx = right;
        phase=0;
        phase++;
        break;
      default:
        ty += height/6;
        if (tx==left) tx=right;
        else if(tx==right) tx=left;
        else tx = left;
        phase=0;
        redraw();
        break;
    }
}

function drawTheThing(){
  var func = "elasticOut";
  var q = ease[func](t*2.5);

  var diff = frameCount - fc;
  if (diff > pauseTime){
    doPhase();
    t = 0.;
    fc = frameCount;
  }
  else if (phase==0)
    doPhase();

  x1 = map(q, 0., 1., x, tx);
  y1 = map(q, 0., 1., y, ty);

  fill(255);
  stroke(0);
  ellipse(x1, y1, radius,radius);
  ellipse(x1+left, y1, radius,radius);
  ellipse(x1-left, y1, radius,radius);

  drawMouse(width-x1, height-y1, mr);
  drawMouse(width-x1+left, height-y1, mr);
  drawMouse(width-x1-left, height-y1, mr);

  t+=speed;
  if(t>1.) {
    t=1.;
    x = tx;
    y = ty;
  } 
}

function drawMouse(y,x,s) {
  push(); 
  stroke(255);
  noFill();
  strokeWeight(10);
  ellipse(x,y, 9*s,9*s);
  
  stroke(0);
  strokeWeight(5);
  translate(-1.5*s,0,5);
  rect(x,y,4*s,3*s,5);
  rect(x,y-3.5*s,s,3.5*s,5,5,0,0);
  rect(x+s,y-s,s,s,5,5,0,0);
  rect(x+2*s,y-s,s,s,5,5,0,0);
  rect(x+3*s,y-s,s,s,5,5,0,0);
  rect(x-s,y,s,2*s,5);
  pop();
}

}

nerual-Scope

Process:

I really liked the aesthetics of the line pop explosion thing, so I wanted to make use of it somehow. I was also fixated on making something meta, in preparation for the GIF project.

Actual Code:

function drawArtFrame(whichFrame) {
  // Draw the artwork for a generic frame of the Zoetrope, 
  // given the framenumber (whichFrame) out of nFrames.

  drawMyArtFrame(whichFrame);
}
  
function drawMyArtFrame(whichFrame){
  noFill();
  stroke(0);
  strokeWeight(1);
  var padding = 30;
  var pos = map(whichFrame, 0, nFrames, artAreaHeight-padding, padding);
  var t = map(whichFrame, 0, nFrames, 0, 1);
  var diam = map(cos(t * TWO_PI), -1, 1, artAreaHeight-padding, padding+10);
  //ellipse(0, pos, 10, 10);
  var dir = map(whichFrame, 0, nFrames, -1, 1);
  if(whichFrame > 9 || whichFrame < 3) 
    drawPop(0, padding-10, 5, 10);
  drawMouseScaled(0, diam, 5);
}

 

neural-reading01

The Critical Engineer deconstructs and incites suspicion of rich user experiences.

The Critical Engineer doesn't assume that entertainment exists only for entertainment. There are complex historical, political, economic, cultural, personal, etc. factors involved, that are worth examining to determine underlying intentions or implications of its creations, experience, and existence.

An example that comes to mind: when you buy a ticket to see that new Star Wars movie, you're interacting in some way, however tangential, with the interests Hollywood higher-ups that funded that movie, and likely had a say in the casting and writing. Their motivations are tinged by the masses, the netizens ranting or raving about the casting or plot. And by engaging in the whole theater going "experience"(the popcorn, the booming sounds, and a meal because there's probably a mall nearby)which has been part of the popular consciousness for a very long time and continuously been shaped by capitalism and consumerism.

I find it interesting that analysis can lead you down this winding chain of buzzwords and that we end up in interesting places when we ask why this chain exists, and why those particular words are there.

nerual-lookingoutwards01

Hermit

"A man. A horse. A nature." By Lingdong Huang

This Python game was a term project for the Fall 2015 15-112 course here at CMU. It seems like most of it was made from scratch, from the procedural generation, use of its own internal time or some global time for the night/day transitions, and all the animations.

I really admire the commitment to making the animations from scratch, because I find that a lot of projects that make use of borrowed material don't have a very polished, cohesive feeling to it. And of course it must have been a lot of work. I also admire the way they used their limitations to their advantage--it seems like they used pixel art to keep procedural generation and game rendering smooth, but they did it in a way that looks very impressive and has a unique style, like an 8-bit zen journey. It makes me want to try to create something with procedural generation, and try applying retro looking pixel art to other unexpected things.

GitHub Repo

nerual-Intersections

var boolDoRefresh;
var lineArr;
var bkgrd = 255;
var canvasW = 600;
var canvasH = 600;
var numLines = 12;
 
function setup() {
  createCanvas(canvasW, canvasH);
  boolDoRefresh = true;
  background(bkgrd);
  lineArr = [];
  //noFill();
}
 
function draw() {
  var x1,x2,x3,x4,y1,y2,y3,y4;
  if (boolDoRefresh) {
    for (var i = 0; i < numLines; i++) {
      createLine();
    }
    
    for (i = 0; i+1 < numLines; i++){
      for (j = i+1; j < numLines; j++){
        var a = lineArr[i];
        var b = lineArr[j];
        drawIntersect(a,b);
      } 
    }
    
    boolDoRefresh = false;
  }
}

function createLine() {
  x1 = random(canvasW);
  y1 = random(canvasH);
  x2 = random(canvasW);
  y2 = random(canvasH);
  stroke(0);
  line(x1,y1,x2,y2);
  lineArr.push([x1,y1,x2,y2]);
}

function drawIntersect(a, b){
  x1 = a[0]; y1 = a[1]; x2 = a[2]; y2 = a[3];
  x3 = b[0]; y3 = b[1]; x4 = b[2]; y4 = b[3];

  var denom = (y4-y3)*(x2-x1) - (x4-x3)*(y2-y1);
  if (denom == 0) {
    return;
  }
  
  var ua = ((x4-x3)*(y1-y3) - (y4-y3)*(x1-x3))/denom;
  var ub = ((x2-x1)*(y1-y3) - (y2-y1)*(x1-x3))/denom;
      
  var ix = x1 + ua*(x2-x1);
  var iy = y1 + ua*(y2-y1);
        
  if (ua < 0 || ua > 1 || ub < 0 || ub > 1) {
    return;
  }
  noStroke();
  fill(random(256),random(256),random(256),150);
  ellipse(ix, iy, 20, 20);
  fill(255,255,255,200);
  ellipse(ix,iy,5,5);
  resetProps();
}

function resetProps(){
  stroke(0);
}
 
function mousePressed() {
  lineArr = [];
  background(bkgrd);
  boolDoRefresh = true;
}

neural-Interruptions

Observations:
  1. The artwork is square.
  2. There is a border of white along the edges.
  3. The lines all tend to have a bias toward vertical or horizontal in each piece, from a further away view.
  4. Very few individual lines are rotated anywhere near horizontal(for the vertically oriented pieces).
  5. Open areas between lines seem to have fairly uniform, if random shapes.
  6. The lines look like they line up in a grid, with each line rotated about its midpoint.
  7. The lines are all short and have the same length
  8. The lines are black. The background is white.
  9. The larger open spaces have irregular shapes and are fairly sparse.
  10. Some of the large open spaces occur at the 'edges' and there are no lines in that part of the edge.
  11. There are lots of small parallelograms, triangles, and sometimes pentagons formed by adjacent lines.
  12. There are at least fifty lines in a row/column.

var boolDoRefresh;
var boolDoRefresh;
var bkgrd = 255;
var canvasW = 650;
var canvasH = 650;
var border = 30;
var gridSize = 56;
var baseAngle = 90; //change to 0 for horizontal orientation
var lineRadius = 9;
 
function setup() {
  createCanvas(canvasW, canvasH);
  boolDoRefresh = true;
  background(bkgrd);
  noFill();
  angleMode(DEGREES);
}
 
function draw() {
  if (boolDoRefresh) {
    drawTheThing();
    boolDoRefresh = false;
  }
}
 
function drawTheThing(){
  var div = (width - 2*border)/gridSize;
  var noiseVal;
  var noiseScale=0.01;
    for (var x = border; x &lt; width - border; x += div){
      for (var y = border; y &lt; width - border; y += div){ 
        noiseDetail(3,0.7); 
        noiseVal = noise((x) * noiseScale, (y) * noiseScale); 
        if(noiseVal &gt; 0.75) stroke(255);
        else stroke(0);
        drawLineCenteredAt(x,y);
      }
    }
}
 
function drawLineCenteredAt(x,y){
  var angle, dx, dy, bias;
  bias = 65;
  angle = baseAngle - random(bias);
  var half = random(2);
  var neg;
  if (half &lt; 1) neg = -1;
  else neg = 1;
  dx = neg*lineRadius*cos(angle);
  dy = lineRadius*sin(angle);
  line(x+dx,y+dy, x-dx,y-dy);
}
 
function mousePressed() {
  noiseSeed(random(100));
  background(bkgrd);
  boolDoRefresh = true;
}
Some Thoughts

I started with the general form, a grid of randomly rotated lines, then added in noise, then fine-tuned the lines' randomness. The vertical/horizontal bias was interesting. The angle rotated definitely had to be less than 90 degrees, but I wasn't sure if the angle deviation was constant or formed a kind of bell curve around a point(ultimately it made little difference).  The noise was also difficult because understanding what the different settings meant didn't translate to imagining what the overall effect would be, so it was a lot of testing and close comparison. I learned to appreciate examining an art piece in extremely great detail and seeing what kind of fiddling went into achieving that specific impression. I think I made a good copy at a glance, although I think the noise could have been less harsh.