alchan-Looking Outwards 07

(an example of the July 12, 2013 “Manhattanhenge”)

NYCHenge, created by the Carto team in 2013, is a project that visualizes how the sun aligns with the streets of New York City, inspired by the two times a year the sun lines up with the midtown grid of streets (“Manhattanhenge”). Sun-alignment is indicated by orange or red colors; the more red the color gets the more in-line the sun will be with that particular street. Users can explore the entire city of New York (not just Manhattan) across the entire year to find other, mini-henges or just figure out when the sun will shine in their faces as they’re driving down certain streets. It’s created with Open Street Maps, CartoDB tools, and the SunCalc javascript library to figure out the sun position.

I was drawn to this project because of its interesting focus, and the way it’s both interactive and relatively easy to understand. One downside to the simplicity of the map is that non-New-Yorkers will probably have trouble identifying the unlabeled streets, but the general gist of the project is still obvious.

alchan-Project 06-abstract clock

abstract clock

function setup() {
    createCanvas(240, 480);
    angleMode(DEGREES);
    noStroke();
}

function draw() {
  var m = month();
  var d = day();
  // map the current hour, minute, & second
  // to an r, g, or b value
  var hr = map(hour(), 0, 23, 0, 255);
  var min = map(minute(), 0, 59, 0, 255);
  var sec = map(second(), 0, 59, 0, 255);
  var clock = {r: min, g: sec, b: hr};

  // assign colors to minute and second
  // (hour is present in both as the blue value)
  var minColor = color(clock.r, 0, clock.b);
  var secColor = color(0, clock.g, clock.b);

  // draw gradient; the top color represents the minute
  // & the bottom represents the second
  // (hour is the blue value)
  for (var c = 0; c <= height; c += 5) {
    var amt = map(c, 0, height, 0, 1);
    var gradient = lerpColor(minColor, secColor, amt);
    fill(gradient);
    rect(0, c, width, 5);
  }

  // draw a number of equally spaced lines dependant on month
  // (the month is how many sections the area is divided into)
  // day of month is represented by the y position of the lines
  for (var i = 0; i <= m; i++) {
    var monthDiv = width / m;
    var dayPos = map(d, 0, 31, 0, height-10);
    fill(255);
    rect(monthDiv + i*monthDiv, dayPos, 1, 10);
  }
}

I played around with a few different ideas in my sketches (I thought about doing something related to lunar phases, a clock that represented time by randomly scattering dots on a grid, and a more representational clock that showed time by the growth of a flower).

I really wanted to create a clock that was abstract enough to almost be without a focal point, and decided to play around with color as a representation of time. I originally just had the r, g, and b values of the background assigned to the hour, minute, and second. This was a little boring for anyone who didn’t watch the clock for a long period of time, so I decided to play around with gradients and also incorporate the day and month

In the final clock, the top color represents the current minute, while the bottom color represents the current second. The hour is the blue value present in both colors. Month is represented by the number of divisions created by the white lines, and the y-position of the lines is roughly equivalent to the day of the month.

alchan-Looking Outwards 06

John Pound’s Ran Dum LOOP (1999) is a collection of code that randomly generates comic- and cartoon-style art. (An example of one of the randomly-generated pieces is shown below).

Pound wrote the code entirely in PostScript. The program does have some elements that are not randomly determined, but I wasn’t able to find out what those were or what type of randomness Pound was using.

I chose this project because I was drawn to the idea of randomly generating something that doesn’t seem like it would work well as a randomly generated piece. The viewer has to try to make sense of the generated panels and images, and I like the idea of being able to “see” an overarching narrative in a random sequence of images.

alchan-Project 05-wallpaper

sharp

// palette
var dark = {r: 179, g: 191, b: 191}
var medium = {r: 203, g: 214, b: 214}
var light = {r: 217, g: 225, b: 225}

function setup() {
    createCanvas(480, 480);
    background(250);
    rectMode(CENTER);
    angleMode(DEGREES);
    noLoop();
}

function draw() {
    var offsetX = 50;
    var offsetY = 52;
    var rowNum;
    var slant = -20;
    var which = 1;

    for(var y = 0; y < 5; y++) {
      //check if the row is odd or even and offset odd rows
      if(y % 2 == 0) {
        offsetX = 10;
        rowNum = 6;
      } else {
        offsetX = 60;
        rowNum = 5;
      }
      for(var x = 0; x < rowNum; x++) {
        scratch(x*130 - offsetX, y*150 - offsetY);

        //determine which type of knife to draw
        which = nf(random(0,3)+1, 1, 0);
        if(which == 1) {
          sharp(x*100 + offsetX, y*100 + offsetY, slant);
        } else if(which == 2) {
          sharp2(x*100 + offsetX, y*100 + offsetY, slant);
        } else if(which == 3) {
          sharp3(x*100 + offsetX, y*100 + offsetY, slant);
        }
      }
    }
}

// KNIFE 1
function sharp(xPos, yPos, angle) {
  var sharpX = 0;
  var sharpY = 0;

  var sharpW = 8;
  var sharpH = 30;
  var guardW = 10 + sharpW;
  var guardH = 3;
  var handleW = 6;
  var handleH = 20;

  noStroke();
  push();
  translate(xPos, yPos);
  rotate(angle);
  // blade 1
  fill(medium.r, medium.g, medium.b);
  rect(sharpX, sharpY, sharpW, sharpH);
  triangle(sharpX + sharpW/2, sharpY + sharpH/2,
    sharpX, sharpY + sharpH/2,
    sharpX, sharpY + sharpH/2 + 12);
  fill(light.r, light.g, light.b);
  rect(sharpX - sharpW/4, sharpY, sharpW/2, sharpH);
  triangle(sharpX - sharpW/2, sharpY + sharpH/2,
    sharpX, sharpY + sharpH/2,
    sharpX, sharpY + sharpH/2 + 12);

  // guard 1
  fill(dark.r, dark.g, dark.b);
  rect(sharpX, sharpY - sharpH/2 - guardH/2, guardW, guardH);
  ellipse(sharpX - guardW/2, sharpY - sharpH/2 - guardH/2, guardH * 1.5);
  ellipse(sharpX + guardW/2, sharpY - sharpH/2 - guardH/2, guardH * 1.5);

  // handle 1
  rect(sharpX, sharpY - sharpH/2 - handleH/2, handleW, handleH);

  // pommel 1
  ellipse(sharpX, sharpY - sharpH/2 - handleH, handleW + 2);
  pop();
}

// KNIFE 2
function sharp2(xPos, yPos, angle){
  var sharp2X = -5;
  var sharp2Y = -18;

  var sharp2W = 25;
  var sharp2H = 80;
  var handle2W = 6;
  var handle2H = 22;

  noStroke();
  push();
  translate(xPos, yPos, angle);
  rotate(angle);
  // blade 2
  fill(medium.r, medium.g, medium.b);
  arc(sharp2X, sharp2Y, sharp2W, sharp2H, 0, 90, PIE);
  fill(light.r, light.g, light.b);
  rect(sharp2X - 1, sharp2Y + sharp2H/4, 2, sharp2H/2);

  // handle 2
  fill(dark.r, dark.g, dark.b);
  rect(sharp2X + sharp2W/2 - handle2W/2, sharp2Y - handle2H/2,
    handle2W, handle2H);
  ellipse(sharp2X + sharp2W/2 - handle2W/2, sharp2Y - handle2H,
    handle2W);
  pop();
}

// KNIFE 3
function sharp3(xPos, yPos, angle) {
  var sharp3X = 0;
  var sharp3Y = 0;

  var sharp3W = 8;
  var sharp3H = 30;
  var handle3W = 6;
  var handle3H = 20;
  var guard3W = sharp3W + 4;
  var guard3H = 4;

  noStroke();
  push();
  translate(xPos, yPos);
  rotate(angle);

  // handle 3
  fill(dark.r, dark.g, dark.b)
  rect(sharp3X, sharp3Y - sharp3H/2 - handle3H/2,
    handle3W, handle3H);

  // guard 3
  rect(sharp3X, sharp3Y - sharp3H/2 - guard3H/2-1,
    guard3W, guard3H);
  // pommel 3
  ellipse(sharp3X, sharp3Y - sharp3H/2 - handle3H,
    handle3W+3);
  fill(light.r, light.g, light.b);
  ellipse(sharp3X, sharp3Y - sharp3H/2 - handle3H,
    handle3W-2);

  // blade 3
  fill(light.r, light.g, light.b);
  quad(sharp3X - sharp3W/2, sharp3Y - sharp3H/2,
    sharp3X + sharp3W/2, sharp3Y - sharp3H/2,
    sharp3X + sharp3W/2, sharp3Y + sharp3H/2 + 8,
    sharp3X - sharp3W/2, sharp3Y + sharp3H/2);
  // highlights
  fill(medium.r, medium.g, medium.b);
  quad(sharp3X - sharp3W/2, sharp3Y,
    sharp3X + sharp3W/2, sharp3Y + 8,
    sharp3X + sharp3W/2, sharp3Y + 4,
    sharp3X - sharp3W/2, sharp3Y - 4);
    quad(sharp3X - sharp3W/2, sharp3Y - 8,
      sharp3X + sharp3W/2, sharp3Y,
      sharp3X + sharp3W/2, sharp3Y - 16,
      sharp3X - sharp3W/2, sharp3Y - 16);
    pop();
}

// LINES
function scratch(xPos, yPos) {
  var spacing = 20;

  noFill();
  stroke(255);
  strokeWeight(4);
  line(xPos, yPos, xPos + 100, yPos + 100);
  line(xPos, yPos + spacing, xPos + 100, yPos + 100 + spacing);
  line(xPos, yPos + spacing*2, xPos + 100, yPos + 100 + spacing*2);

}

I wanted to play around with creating functions and more complex shapes, so the elements themselves are more complicated than the repetition. The type of knife is also randomly generated, so the pattern is slightly different every time.

alchan-Looking Outwards 05

I’ve really enjoyed the small 3d-modeled pieces created by Agatha Yu as part of a year-long, “make something everyday” project (the particular piece pictured is “Crystal Shore,” from February 21, 2017). They’re mostly modeled and animated in Blender. The pieces are usually low-poly or made of smooth, simple forms, which work well with the soft color palettes the creator normally uses. I think these aspects, as well as the subject matter, combine to create a specific, calming mood that really drew me into each of the pieces. I also appreciate how the style of the work is not necessarily aiming for photorealism or some other theme normally associated with computer-generated graphics, but is rather branching out in a style of its own.

alchan-Project04-string art

alchan project 04

//line properties
var startX;
var startY = 200;
var endX = 150;
var endY;
var startDist = 20;
var endDist = 20;

//adjust background color
var backColor = 100;

//check whether lines should move back or forth
var shouldMove = true;

function setup() {
    createCanvas(400,300);
    stroke(256);
    strokeWeight(2);
    frameRate(30);
}

function draw() {
  background(backColor, backColor, 200);


    //top left corner
    startX = 0;
    startY = 150;
    endX = 200;
    endY = 0;
    for(var i = 0; i < 10; i++) {
        line(startX, startY + startDist, endX + endDist, endY);
        startY -= 10;
        endX += 10;
    }

    //top right corner
    startX = 400;
    startY = 150;
    endX = 200;
    endY = 0;
    for(var i = 0; i < 10; i++) {
        line(startX, startY + startDist, endX - endDist, endY);
        startY += 10;
        endX += 10;
    }

    //bottom left corner
    startX = 0;
    startY = 150;
    endX = 200;
    endY = 300;
    for(var i = 0; i < 10; i++) {
        line(startX, startY - startDist, endX + endDist, endY);
        startY -= 10;
        endX -= 10;
    }

    //bottom right corner
    startX = 400;
    startY = 150;
    endX = 200;
    endY = 300;
    for(var i = 0; i < 10; i++) {
        line(startX, startY - startDist, endX - endDist, endY);
        startY -= 10;
        endX += 10;
    }

    //check whether the lines have reached a certain position
    //and change the value of shouldMove to switch direciton
    if (startDist >= 300) {
        shouldMove = false;
    } else if (startDist <= 0) {
        shouldMove = true;
    }

    //move the position of the lines' endpoints
    //changing direction depending on shouldMove
    if (shouldMove === true) {
        startDist += 10;
        endDist -= 10;
      backColor += 5;
    } else if (shouldMove === false) {
        startDist -= 10;
        endDist += 10;
        backColor -= 5;
    }
}

I wanted to try making an animated piece (without mouse interaction), so once I figured out how to calculate and draw the lines I played around with moving all of the points to animate the entire drawing. The final piece wasn’t quite what I had originally planned to make, as I had wanted to incorporate rotation again somehow, but I also learned a lot in figuring out how to create a back-and-forth motion.

alchan-Looking Outwards 04

Chelpa Ferro is a multimedia art group whose work primarily revolves around sound, in one form or another. One of their installations, Acusma (2008), combines recorded sound and traditional Brazilian pottery spread throughout a space. Though I wasn’t able to find much information on the actual process behind the work, the sounds used in the work appear to have been originally recorded, then manipulated by an algorithm to play back with various modifications or repetitions. The result is a chorus of sounds that are voice-like, but is just removed enough to be not quite just a group of human voices.

I really appreciate the juxtaposition between this process and the other main part of the work, traditionally made pottery. This combination of new and old, as well as that of the sounds themselves coming from such unexpected places, also seem to be typical of how the artists are trying to explore sound—making both the sources of sounds and the sounds themselves unfamiliar to the viewers/ listeners.

alchan-Project 03-dynamic drawing

alchan project 03

//Scarlet Tong
//sntong@andrew.cmu.edu
//Section A
// Project 5: Wallpaper

//x and y coordinates the tip of the tear drops
var x = 0;
var y = 0;
// scale
var Large = 25;
var Medium = Large-1;
var Small = Large-5;
// for loop coordinates
var transY = 0;
var transX = 30;

function setup() {
    createCanvas(480, 480);
    background (243,117,117);//hot pink!
}

function draw() {
  //array the pattern on the odd rows
  for (var transY = 0; transY < width; transY+= Large*6+15) {
    for (var transX = 0; transX < width+30; transX+= Large*2+10) {
      pattern(transX,transY);
    }
  }
  // array the pattern for even rows and offset them so they fill the gap
  for (var transY = -Large*3-8; transY < width; transY+= Large*6+15) {
    for (var transX = Large+5; transX < width; transX+= Large*2+10) {
      pattern(transX,transY);
    }
  }
}

function pattern(transX,transY){
  stroke(255);
  strokeWeight(1);
  //deep blue tear drop, aka large drop
  push();
  translate(transX,transY);
  fill(48,78,109);
  beginShape();
  curveVertex(x,y);
  curveVertex(x,y);
  curveVertex(Large,Large*3);
  curveVertex(x,Large*4);
  curveVertex(x-Large, y+Large*3);
  curveVertex(x,y);
  curveVertex(x,y);
  endShape();
  pop();
  //pale orange tear drop, medium drop
  push();
  translate(transX,transY+Large*6);
  fill(237,168,131);
  angleMode(DEGREES);
  rotate(180);
  beginShape();
  curveVertex(x,y);
  curveVertex(x,y);
  curveVertex(Medium,Medium*3);
  curveVertex(x,Medium*4);
  curveVertex(x-Medium, y+Medium*3);
  curveVertex(x,y);
  curveVertex(x,y);
  endShape();
  // teal tear drop, small drop
  fill(43,188,177);
  beginShape();
  curveVertex(x,y+10);
  curveVertex(x,y+10);
  curveVertex(Small,Small*3+10);
  curveVertex(x,Small*4+10);
  curveVertex(x-Small, y+Small*3+10);
  curveVertex(x,y+10);
  curveVertex(x,y+10);
  endShape();
  //yellow circle
  fill(253,185,74);
  ellipse(x,Small*5,Large,Large);
  //small dark blue circle on the tip of the shape
  fill(48,78,109);
  ellipse(0,0,10,10);
  pop();
}

I wanted to play around with rotation for this project and was inspired by stylized/ simplified representations of the solar system (or atoms). I did a few quick sketches of how I wanted the drawing to change as the mouse moved, and from there figured out how I was going to implement the design.

I think the trickiest part of this was figuring out how to change the size of all of the components with the movements of the mouse without making them too large or too small.

 

alchan-Looking Outwards 03

GLASS II from Mediated Matter Group on Vimeo.

GLASS II, by The Mediated Matter Group at MIT Media Labs, is a series of 3d-printed glass columns, each internally lit to produce “kaleidoscope-like patterns” of light and shadow. Each column was generated with a different shape, determined both by how the characteristics of the shape affected light passing through it and the limitations of the 3d-printing system itself. The internal lighting within each column also moved up and down, creating dynamic patterns of light projected onto the floors and walls of the exhibit.

I was initially drawn to the project because of its unusual production method: generative forms aside, figuring out how to 3d-print glass is a feat in itself. I also admire how the installation itself didn’t just rely on the 3d-printed material, but also incorporated light and how the material affected it.

 

alchan-Project 02-variable face

alchan project 02

//face shape
var faceShade = 100;
var faceWidth = 150;
var faceHeight = 200;
var faceAngle1 = 10;
var faceAngle2 = 10;
var faceAngle3 = 10;
var faceAngle4 = 10;

//eyes
var eyeSize = 50;
var eyeStroke = 4;
var eyeNumber = 2;
var eyeX = 320;
var eyeY = 210;
var eyeDistance = 30;

//antlers
var antlerX = 50;
var antlerY = 120;
var antlerLeft1 = 80;
var antlerLeft2 = 180;
var antlerLeftSize = 100;
var antlerRight1 = 0;
var antlerRight2 = 100;
var antlerRightSize = 100;
var antlerStroke = 8;

//determine whether to show/hide
var crestType = 1;
var showEars = 0;

//ears
var earX = 320;
var earY = 100;
var earWeight = 50;

//spike
var spikeX = 320;
var spikeY = 240;
var spikeWidth = 20;
var spikeHeight = 100;

//specimen label
var n1 = 0;
var n2 = 0;
var n3 = 0;

function setup() {
    createCanvas(640, 480);
    rectMode(CENTER);
    angleMode(DEGREES);
    smooth();
}

function draw() {
    background(237, 234, 218);

    //antlers
    noFill();
    stroke(0);
    strokeWeight(antlerStroke);
    arc(320 - faceWidth/2, antlerY, antlerLeftSize, antlerLeftSize, antlerLeft1, antlerLeft2, OPEN);
    arc(320 + faceWidth/2, antlerY, antlerRightSize, antlerRightSize, antlerRight1, antlerRight2, OPEN);

    //determine additional crest type: antlers, ears, spike
    if(crestType === 1) {
      strokeWeight(antlerStroke - 2);
      arc(320 - faceWidth/2, antlerY - 20, antlerLeftSize - 50, antlerLeftSize - 50, antlerLeft1, antlerLeft2, OPEN);
      arc(320 + faceWidth/2, antlerY - 20, antlerRightSize - 50, antlerRightSize - 50, antlerRight1, antlerRight2, OPEN);
    } else if (crestType === 2) {
      noStroke();
      fill(50);
      triangle(spikeX - spikeWidth/2, 245 - faceHeight/2, spikeX + spikeWidth/2,
        245 - faceHeight/2, spikeX, spikeHeight);
    }

    //determine whether or not to draw ears
    if(showEars >= 0.5) {
      stroke(faceShade);
      strokeWeight(earWeight);
      line(earX - faceWidth/2, antlerY + earY, earX + faceWidth/2, antlerY + earY);
    }

    //face
    noStroke();
    fill(faceShade);
    rect(320, 240, faceWidth, faceHeight,
      faceAngle1, faceAngle2, faceAngle3, faceAngle4);

    //eyes: determine how many, then draw
    stroke(256);
    strokeWeight(eyeStroke);
    fill(0);
    if(eyeNumber === 1) {
      ellipse(eyeX, eyeY, eyeSize, eyeSize);
    } else if(eyeNumber === 2) {
      ellipse(eyeX - eyeDistance, eyeY, eyeSize, eyeSize);
      ellipse(eyeX + eyeDistance, eyeY, eyeSize, eyeSize);
    } else if (eyeNumber === 3) {
      ellipse(eyeX - eyeDistance, eyeY, eyeSize, eyeSize);
      ellipse(eyeX + eyeDistance, eyeY, eyeSize, eyeSize);
      ellipse(eyeX, eyeY - eyeDistance, eyeSize, eyeSize);
    }

    //caption: specimen number
    noStroke();
    textFont('Georgia');
    textSize(16);
    textAlign(CENTER);
    textStyle(ITALIC);
    text('specimen no. ' + n1 + n2 + n3, 320, 440);
}

function mousePressed() {
    // when the user clicks, these variables are reassigned
    // to random values within specified ranges. For example,
    // 'faceWidth' gets a random value between 75 and 150.
    faceWidth = random(180, 250);
    faceHeight = random(200, 250);
    faceAngle1 = random(10, 60);
    faceAngle2 = random(10, 60);
    faceAngle3 = random(10, 60);
    faceAngle4 = random(10, 60);
    faceShade = random(80, 150);

    eyeSize = random(30, 70);
    eyeStroke = random(3, 10);
    eyeNumber = Math.floor((random() * 3) + 1); //need a whole number
    eyeX = random(290, 350);
    eyeY = random(180, 240);
    eyeDistance = eyeSize/2 + random(5,30);

    antlerX = random(90, 125);
    antlerY = random(100, 180);
    antlerLeft1 = random(70, 90);
    antlerLeft2 = random(170, 200);
    antlerLeftSize = random(80, 120);
    antlerRight1 = random(-20, 10);
    antlerRight2 = random(90, 110);
    antlerRightSize = random(80, 120);
    antlerStroke = random(4, 15);

    crestType = Math.floor((random() * 2) + 1); //need a whole number
    showEars = random();

    earY = random(80, 120);
    earWeight = random(40, 80);

    spikeX = random(260, 380);
    spikeY = random(50, 100);
    spikeWidth = random(10, 40);
    spikeHeight = random(25, 80);

    n1 = Math.floor((random() * 9) + 1); //need a whole number
    n2 = Math.floor((random() * 9) + 1);
    n3 = Math.floor((random() * 9) + 1);
}

I first figured out which elements of my face I wanted to be randomized. I then decided which elements would be constant (antlers, eyes) and which would only be drawn for some faces (2nd set of antlers, ears, horn, number of eyes). From there it was just working out dimensions, coordinates, and ranges for the randomly generated variables.