John Legelis – Final Project

sketch

// John Legelis
// Section D
// FINAL

// Board dimensons
var b
var boardW = 200
var boardH = 350
var boardX = 10
var boardY = 10

// Oscillator dimensions/variables
var oscSpacing = boardH/4.1
var numberboxS = 20

// Dial dimensions/variables
var dR = 17
var dialStroke = 4
var dialSpacing = boardW/5
var theta = Math.PI/2
var overDial = false
var moving = false
var iy
var oldTheta
var thetaMin = -1/4*Math.PI
var thetaMax = 5/4*Math.PI

var pressed = false
var oscOn = false
var c = 2**(1/12) // Frequency diffrence between half steps
var cf = 2 **(1/100/12) // Frequency diffrence between cents
var volKnob = 0 // Index of volume knob
var pitchKnob = 1 // Index of pitch knob
var fineKnob = 2 // Index of fine knob

var wList = ["z", "x", "c", "v", "b", "n", "m", ",", ".", "/" ]
var bList = ["s", "d", false, "g", "h", "j", false, "l", ";"]



function setup() {
    createCanvas(600, 385);
    background(0);
    noFill()

    // Draw the board
    b = new ThreeWaveBoard(boardX, boardY, boardW, boardH)
    b.drawBoard()
}

function ThreeWaveBoard(X,Y,W,H) {
    // Board Dimensions
    this.bX = X
    this.bY = Y
    this.bW = W
    this.bH = H
    this.bStroke = 4
    this.oscillators = []

    // Draw board border ==> rectangle
    this.drawBoard = function() {
        stroke(255)
        strokeWeight(this.bStroke)
        rect(this.bX, this.bY, this.bW, this.bH)

        strokeWeight(2)
        rect(this.bW/2,this.bY + 50, 10,10)
        strokeWeight(1)
        textSize(15)
        text("FAT", this.bW/2 + 15, this.bY+60)
        textSize(29)
        text("3 Wave Oscillator", this.bX+8, this.bY+40)

        // Make 3 oscillators
        for (osc=0; osc<3; osc++){
            var oX = this.bX
            var oY = this.bY + oscSpacing*(osc+1)
            var oW = this.bW
            var oNum = osc + 1
            this.oscillators.push(new oscillator(oX, oY, oW, oNum))
            this.oscillators[osc].drawoscillator()
        }
    }

    // Update board
    this.updateBoard = function() {
        stroke(255)
        strokeWeight(this.bStroke)
        rect(this.bX, this.bY, this.bW, this.bH)

        strokeWeight(1)
        textSize(26)
        text("3 Wave Oscillator", this.bX+8, this.bY+40)

        // Update 3 oscillators
        for (osc=0; osc<3; osc++){
            this.oscillators[osc].updateOscillators()
        }
    }
}

function oscillator(X,Y,W,num) {
    // Oscillator Dimensions
    this.oX = X
    this.oY = Y
    this.oW = W
    this.oStroke = 4
    this.oTextStroke = 1
    this.oTextSize = 15
    this.number = num
    this.dials = []
    this.wave = new p5.Oscillator()
    this.f = false
    this.fine = 0
    this.volume = 0

    // Draw oscillator ==> line, number box, number
    this.drawoscillator = function() {
        //line and number box
        stroke(255)
        strokeWeight(this.oStroke)
        line(this.oX, this.oY, this.oX+this.oW, this.oY)
        rect(this.oX, this.oY, 20, 20)

        // Number text
        strokeWeight(this.oTextStroke)
        textSize(this.oTextSize)
        text(num, this.oX+5, this.oY+15)

        // Make volume dial
        var dX = this.oX + dR + this.oW/5 * (2)
        var dY = this.oY + oscSpacing/2
        this.dials.push(new Dial(dX, dY, dR, theta, -12, 12, "Volume"))
        this.dials[0].drawDials()

        // Make pitch dial
        var dX = this.oX + dR + this.oW/5 * (3)
        var dY = this.oY + oscSpacing/2
        this.dials.push(new Dial(dX, dY, dR, theta, -24, 24, "    Pitch"))
        this.dials[1].drawDials()

        // Make fine dial
        var dX = this.oX + dR + this.oW/5 * (4)
        var dY = this.oY + oscSpacing/2
        this.dials.push(new Dial(dX, dY, dR, theta, -12, 12, "    Fine"))
        this.dials[2].drawDials()
    }

    this.updateOscillators = function() {

        // Line and number box
        stroke(255)
        strokeWeight(this.oStroke)
        line(this.oX, this.oY, this.oX+this.oW, this.oY)
        rect(this.oX, this.oY, 20, 20)

        // Number text
        strokeWeight(this.oTextStroke)
        textSize(this.oTextSize)
        text(num, this.oX+5, this.oY+15)

        for (i=0; i<this.dials.length; i++){
            this.dials[i].drawDials()
        }
    }
}

function Dial(X, Y, R, theta, min, max, kind) {
    // Dial dimensions
    this.dialX = X
    this.dialY = Y
    this.dialR = R
    this.stroke = 4
    this.l1X = X
    this.l1Y = Y
    this.l2X = X + R*cos(theta)
    this.l2Y = Y - R*sin(theta)
    this.theta = theta
    this.over = false
    this.kind = kind
    // Ranges of each dials
    this.min = min
    this.max = max
    this.val = 0 // value of dial initialized to 0
    
    // Turns a decimal radian angle into a number rounded to a specific fration of the circle related to the ticks of the dial
    this.inc = function(dec) {
        this.range = (this.max - this.min)/2
        var increment = 3/4*Math.PI/(this.range)
        var d = dec/increment
        var r = round(d)
        var num = r * increment
        return num // Returns radian value along tick marker
    }

    // Draw dial shape and text
    this.drawDials = function() {
        this.l2X = X + R*cos(this.theta)
        this.l2Y = Y - R*sin(this.theta)
        strokeWeight(this.stroke)
        stroke(255)
        ellipse(this.dialX, this.dialY, this.dialR * 2, this.dialR * 2) // Dial circle
        line(this.l1X, this.l1Y, this.l2X, this.l2Y) // Dial line
        strokeWeight(1)
        text(this.val, this.dialX - 4, this.dialY + 32)
        text(this.kind, this.dialX - 25, this.dialY - 22)
        stroke(0)
        
    }
}

function draw() {

    stroke(255)
    noFill()
    background(0)
    b.updateBoard()
    drawPiano(230,20)

    // If a key is being pressed freq is its frequnncy
    if (keyIsPressed & !oscOn && typeof whichKey() == "string" && whichKey() == key) {
        oscOn = true

        for(waves = 0; waves < b.oscillators.length; waves++) {
            // Math for adjusting pitch and volume according to knobs
            b.oscillators[waves].f = frequencyfunc(whichKey()) * (c ** (b.oscillators[waves].dials[pitchKnob].val)) * (cf ** (b.oscillators[waves].dials[fineKnob].val))
            b.oscillators[waves].volume = 0.5 + map(b.oscillators[waves].dials[volKnob].val, -12, 12, -0.5 ,0.5)

            // Update oscilator parameters
            b.oscillators[waves].wave.amp(b.oscillators[waves].volume)
            b.oscillators[waves].wave.freq(b.oscillators[waves].f)
            b.oscillators[waves].wave.start()
        }
    }

    if (oscOn){
        // If another key is pressed while one is already down, priortize newest key
        if (whichKey != key){
            for(waves = 0; waves < b.oscillators.length; waves++) {
                b.oscillators[waves].f = frequencyfunc(whichKey()) * (c ** (b.oscillators[waves].dials[pitchKnob].val)) * (cf ** (b.oscillators[waves].dials[fineKnob].val))
                b.oscillators[waves].wave.freq(b.oscillators[waves].f)

                b.oscillators[waves].volume = 0.5 + map(b.oscillators[waves].dials[volKnob].val, -12, 12, -0.5 ,0.5)
                b.oscillators[waves].wave.amp(b.oscillators[waves].volume)

            }
        }

        if (!keyIsPressed){
            oscOn = false
        }
    }
    // Turn sounds off if oscillator is off --> no key is pressed
    if (!oscOn) {
        for(waves = 0; waves < b.oscillators.length; waves++) {
            b.oscillators[waves].wave.stop()
        }
    }

    // Check each dial in each oscillator
    for(osc=0; osc < b.oscillators.length; osc++){
        for(d=0; d < b.oscillators[osc].dials.length; d++){

            // If clicked / dragged on dial adjust the angle of specific dial respectively
            if ((dist(mouseX, mouseY, b.oscillators[osc].dials[d].dialX, b.oscillators[osc].dials[d].dialY)) <= (dR) & (mouseIsPressed) && !moving) {
                b.oscillators[osc].dials[d].over = true
                moving = true
                iy = mouseY
                oldTheta = b.oscillators[osc].dials[d].theta
            }
            if (!mouseIsPressed) {
                b.oscillators[osc].dials[d].over = false
                moving = false
            }
            if (b.oscillators[osc].dials[d].over == true) {
                var rawTheta = (oldTheta - map((iy - mouseY)*3, 0, height, 0, 2*Math.PI)) // Smooth theta from mouse
                var cTheta = constrain(rawTheta, thetaMin, thetaMax)    // Constrained theta based on min and max
                var iTheta = b.oscillators[osc].dials[d].inc(cTheta)    // Theta chopped to increment
                b.oscillators[osc].dials[d].val = round((map(iTheta, thetaMin, thetaMax, b.oscillators[osc].dials[d].max, b.oscillators[osc].dials[d].min)))
                b.oscillators[osc].dials[d].theta = iTheta
            }
        }
    }
}


// Return string value of a keyboard key, otherwise false
function whichKey(){
    if ( keyIsDown(90) || keyIsDown(83) || keyIsDown(88) || keyIsDown(68) || keyIsDown(67) || keyIsDown(86) || keyIsDown(71) || keyIsDown(66) || keyIsDown(72) || keyIsDown(78) || keyIsDown(74) || keyIsDown(77) || keyIsDown(188)|| keyIsDown(76) || keyIsDown(190)|| keyIsDown(186)|| keyIsDown(191) ) {
        k = key
    }
    if ((keyIsPressed) && (key == k)) {
        return str(k)
    }

    else{
        return false 
    }
}

// Function that draws the piano shapes and text
function drawPiano(x,y){
    var whiteW = 35
    var whiteH = 200
    var blackW = 20
    var blackH = 115

    // White Keys
    for (i=0; i<10; i++){
        push()
        translate(x,y)
        fill(255)
        rect(i*whiteW, 0, whiteW, whiteH)
        
        fill(0)
        textSize(25)
        text(wList[i],i*whiteW+ whiteW/2 - 6, whiteH - 30)
        pop()
    }

    // Black Keys
    for (j=0; j<9; j++){
        if ((j != 2) & (j != 6)) { // Exclude black key between E and F, and B and C
            push()
            translate(x,y)
            fill(0)
            rect((j+1) * whiteW - blackW/2, 0, blackW, blackH)

            fill(255)
            textSize(22)
            text(bList[j],(j+1) * whiteW - blackW/2 + 6 , blackH - 15)

            pop()
        }
    }
    fill(255)
    stroke(255)
    textSize(30)
    text("Click and Drag Dials!", 250,290)
    text("Play piano with keyboard!", 250, 340)
    noFill()
    strokeWeight(5)
    stroke(255)
    rect(240,250,340,110)
}

// Return the frequency of a keyboard key given string of key pressed
function frequencyfunc(str) {
    if (str == "z") {
        f = 523.25 // C5
    } else if (str == "s") {
        f = 554.37 // C#5
    } else if (str == "x") {
        f = 587.33 // D5
    } else if (str == "d") {
        f = 622.25 // Eb5
    } else if (str == "c") {
        f = 659.25 // E5
    } else if (str == "v") {
        f = 698.46 // F5
    } else if (str == "g") {
        f = 739.99 // F#5
    } else if (str == "b") {
        f = 783.99 // G5
    } else if (str == "h") {
        f = 830.61 // Ab5
    } else if (str == "n") {
        f = 880.00 // A5
    } else if (str == "j") {
        f = 932.33 // Bb5
    } else if (str == "m") {
        f = 987.77 // B5
    } else if (str == ",") {
        f = 1046.50 // C6
    } else if (str == "l") {
        f = 1108.73 // C#6
    } else if (str == ".") {
        f = 1174.66 // D6
    } else if (str == ";") {
        f = 1244.51 // Eb6
    } else if (str == "/") {
        f = 1318.51 // E6
    }
    
    else {
        f = false
    }

    return f
}

 

Click within the project to start!

My final project took a lot of effort on the back end side especially on the dial interaction. In order to make them clickable and draggable and easy to interface with, a lot of thinking and debugging had to be done in order for them to behave properly. Then the p5.Oscillators were used as a basis of the sound of my Oscillator. That package took some troubleshooting but eventually I worked out how to create this monophonic synthesizer. I am very proud of this instrument as it is highly functional and can be used as a real live instrument. It was lots of fun to work on and see it come together.

John Legelis – Final Project Proposal

The goal for my final project is to make an oscillator/synthesizer with a record and playback function. The user interface will resemble the following sketch.

The components of this software are a keyboard as well as a drum machine. I will aim to automatically quantize the rhythms in order to give the playback a better sound and buff out difficulty with keyboard delay etc.

The keyboard functionality will be linked to actual keys on the computer of the user and the pitch bend function will be actuated by the mouse. The drum pad will be actuated in a similar way to the keyboard with the number keys. I am a bit apprehensive about all the levels of interaction the user is intended to have in the end in terms of clickable buttons etc. I hope this product will be fully functional as a fun musical instrument.

Looking Outwards 12, John Legelis

The MiniMoog and the Casio VL-1 are two synthesizers from the 1970’s. The MiniMoog is an analog synthesizer while the Casio VL-1 is a digital synthesizer. They are both some of the first of their respective kinds. The MiniMoog was a instrument that became an instant success and was used by well known performers of every genre and defined the sound of an era. The VL-1 on the other hand was developed 9 years after the MiniMoog. By this time, synthesizers were less novel and were ready to enter the consumer market and Casio decided to develop a product to fill this market. The VL-1, unlike the MiniMoog, was digital and therefore was not competitive with the MiniMoog. Instead the VL-1 synthesizer took advantage of developments in computing with digital synthesis that allowed miniaturization and portability. Some argue that the Casio product is moreso a toy rather than a practical instrument.

The MiniMoog (left) and the Casio VL-1 (right)

For my final project I am aiming to emulate something of the nature of these instruments, I think it is likely that I will end up creating something closer to the toy-like  LV-1 rather than the professional revolutionary MiniMoog

Project 11 – Turtle Freestyle – John Legelis

sketch

// John Legelis
// Section D


var t // turtle
var yF = 273// Winning Y value
var w // State of play (Play, Win, or Lose)
var s // osilator incriment

//load background image
function preload() {
    maze = loadImage("https://i.imgur.com/OPGsUjg.png")
}

function setup() {
    createCanvas(400, 300);
    background(0);
    image(maze,0,0)
    
    fill(0,255,0)
    noStroke()
    rectMode(CORNER)
    rect(361, yF, 33,10)

    // initialize t
    t = makeTurtle(20,0)
    t.setWeight(4)
    mouseX = 20
    mouseY = 1 
    s = 0
    w = 0
    yF = 263
}

function draw() {
    //Oscilate between colors at winning and loosing screens
    s = s + 1
    if (s % 3 == 1){
        var lcol = [255,255,255]
        var wcol = [0,255,0]
    }
    else {
        var lcol = [255,0,0]
        var wcol = [255,255,255]
    }

    // retrive brightness at turtle location
    var p = maze.get(t.x, t.y)
    var Tbright = brightness(p)
    // If in "play" mode, move turtle towards the mouse
    if (w == 0) {
        theta = t.angleTo(mouseX, mouseY)
        t.right(theta)
        t.forward(1)
    }


    //if hit wall, lost
    if (Tbright < 100){
        w = -1
    }
    // if below "win line", won
    if (t.y > yF) {
        w = 1
    }
   
    // if lost...
    if (w == -1){
        background(lcol)
        stroke(255)
        textSize(50)
        text("G A M E O V E R", 10, 150)
        textSize(25)
        text("mouse in box to restart", 40, 30)
        noStroke()
        fill(0)
        rectMode(CENTER)
        rect(25,25, 10,10)
    }
    //if won...
    if (w == 1){
        background(wcol)
        stroke(255)
        textSize(50)
        text("! Y O U W O N !", 10, 150)
        stroke(255)
        textSize(25)
        text("mouse in box to restart", 40, 30)
        noStroke()
        fill(0)
        rectMode(CENTER)
        rect(25,25, 10,10)
    }

    //If lost or won and mouse is in box initialize and go back to "play" mode
    if (((w==-1) || w==1) & (mouseX > 25 - 10) && (mouseX < 25 + 10) && 
    (mouseY > 25 - 10) && (mouseY < 25 + 10)) {
        w = 0
        setup()
    }

    if (mouseIsPressed){
        w = 1
    }
}


function turtleLeft(d) {
    this.angle -= d;
}


function turtleRight(d) {
    this.angle += d;
}


function turtleForward(p) {
    var rad = radians(this.angle);
    var newx = this.x + cos(rad) * p;
    var newy = this.y + sin(rad) * p;
    this.goto(newx, newy);
}


function turtleBack(p) {
    this.forward(-p);
}


function turtlePenDown() {
    this.penIsDown = true;
}


function turtlePenUp() {
    this.penIsDown = false;
}


function turtleGoTo(x, y) {
    if (this.penIsDown) {
      stroke(this.color);
      strokeWeight(this.weight);
      line(this.x, this.y, x, y);
    }
    this.x = x;
    this.y = y;
}


function turtleDistTo(x, y) {
    return sqrt(sq(this.x - x) + sq(this.y - y));
}


function turtleAngleTo(x, y) {
    var absAngle = degrees(atan2(y - this.y, x - this.x));
    var angle = ((absAngle - this.angle) + 360) % 360.0;
    return angle;
}


function turtleTurnToward(x, y, d) {
    var angle = this.angleTo(x, y);
    if (angle < 180) {
        this.angle += d;
    } else {
        this.angle -= d;
    }
}


function turtleSetColor(c) {
    this.color = c;
}


function turtleSetWeight(w) {
    this.weight = w;
}


function turtleFace(angle) {
    this.angle = angle;
}


function makeTurtle(tx, ty) {
    var turtle = {x: tx, y: ty,
                  angle: 0.0, 
                  penIsDown: true,
                  color: color(128),
                  weight: 1,
                  left: turtleLeft, right: turtleRight,
                  forward: turtleForward, back: turtleBack,
                  penDown: turtlePenDown, penUp: turtlePenUp,
                  goto: turtleGoTo, angleto: turtleAngleTo,
                  turnToward: turtleTurnToward,
                  distanceTo: turtleDistTo, angleTo: turtleAngleTo,
                  setColor: turtleSetColor, setWeight: turtleSetWeight,
                  face: turtleFace};
    return turtle;
}

When approaching this project I had an idea instantly to use the turtle to make some sort of maze game. Given our recent experience in using brightness and get image I was able to analyze a maze image and detect the walls very efficiently. I polished the game with a win and lose screen and a quick restart function based on mouse position.

John Legelis – Looking Outwards 11, Computer Music

Teenage Engineering OP-1 Synthesizer/Sampler/Sequencer

Teenage Engineering is a young company from Stockholm Sweden. They developed the OP-1 instrument in response to the creativity-stifling environment of a completely unstructured Digital Audio Workspace.

The OP-1 as a digital instrument is far more restrictive to the user that creating music on a computer would be. The creators claim that “…[the] limits boost the creativity. Limitations are OP-1’s biggest feature.”

The device draws inspiration from retro 80’s synthesizers such as the Casio VL-1, which some developers grew up with and discovered that the physical barriers of older syths spurred unconventional ideas and creativity.

Sample of OP-1 in use.

There are 11 separate synthesizer chips in the device that use varying methods to create different types of sounds.

JJ Legelis Project 10

Boats and Waves

sketch

// John Legelis
// Section D

var boat = []

function setup() {
    createCanvas(480, 480);
    background(0);

}

function draw() {

    background(135, 206, 250)

    //Land terrain
    var land = 0.003;
    var landS = 0.00005;
    stroke("green");
    beginShape(); 
    for (i = 0; i < width; i++) {
        var h = (millis() * landS) + (i * land);
        var y = map(noise(h), 0, 1, 100, 0);
        line(i, y, i, height);
    }
    endShape();

    // Rear wave
    var back = 0.0051;
    var backS = 0.0002;
    stroke(0,142,170);
    beginShape(); 
    for (i = 0; i < width; i++) {
        var h = (millis() * backS) + (i * back);
        var y = map(noise(h), 0, 1, 200, 0);
        line(i, y, i, height);
    }
    endShape();

    //probablity that determines if boat is drawn
    if (random() < 0.03){
        boat.push(makeBoat())
    }
    //Draw and move the boat if made
    for (var h = 0; h < boat.length; h++){
        boat[h].draw()
        boat[h].move() 
    }


    //middle wave terrain
    var mid = 0.0054;
    var midS = 0.0004;
    stroke(0,153,183);
    beginShape(); 
    for (j = 0; j < width; j++) {
        var h = (millis() * midS) + (j * mid);
        var y = map(noise(h), 0, 1, 300, 200);
        line(j, y, j, height);
    }
    endShape();

    //foreground wave
    var fore = 0.006;
    var foreS = 0.0007;
    stroke(0,172,206);
    beginShape(); 
    for (j = 0; j < width; j++) {
        var h = (millis() * foreS) + (j * fore);
        var y = map(noise(h), 0, 1, height, 300);
        line(j, y, j, height);
    }
    endShape();


}

//object containig boat
function makeBoat(){
    var bo = {x:480, y: 230, move: moveBoat, draw: drawBoat}
    return bo
}

//what boat looks like
function drawBoat(){
    var randsailH = random(30,50)
    noStroke()
    fill("brown")
    rect(this.x, this.y, 60,20)
    fill("white")
    triangle(this.x + 10, this.y, this.x + 35, this.y - randsailH, this.x + 25, this.y)
    triangle(this.x + 40, this.y, this.x + 65, this.y - randsailH, this.x + 55, this.y)
    }

// Move that boat
function moveBoat(){
    this.x = this.x - 4 
}



This week’s sketch was a rather large undertaking as it involved using objects on our own for the first time. It took quite some time to be able to properly implement an object without having my hand held through the lab but I eventually succeeded. I stumbled upon the random sail movement by accident but I loved the effect of billowing sails in the wind.

John Legelis – Looking Outwards, Week 10

Recently I visited the Carnegie Museum of Art down the road for the first time since before this summer. There have been several new installations since I last visited the museum but one stuck out specifically which was an exhibit by the Guerrilla Girls. The Guerrilla Girls are a self defined as a group of “feminist activist artists”. The aim to target discrepancies in the art world between representation of women’s works vs men’s. Among the groups tactics for bring attention to these sexist discrepancies are absurdism and borderline threatening. One of their favorite facts to demonstrate the underrepresentation of female artist is as follows:

An example of the Guerrilla Girls Activist Art

The group consists of an ever changing flux of people who remain anonymous in order to keep the attention on the issues instead of the members. I admire this group because of their frankness, aggression, and successful unorthodox methods.

John Legelis – Project 09 Portrait

sketch

// John Legelis
// Section D

var imgH = 480
var pR = 10
var colorList = []
var cWidth = 360
var cHeight = 480
var sourceimg = "https://i.imgur.com/PHP8Htm.jpg"
var pimg = "https://i.imgur.com/R1D8XFS.jpg"
var Ploaded
var Sloaded;

function preload() {
    Sloaded = loadImage(sourceimg)
    Ploaded = loadImage(pimg)
}
function setup() {
    createCanvas(360, 480);
    background(0);
    Sloaded.loadPixels()
}
function draw() {
    for (x=0; x < cWidth/pR; x++){
        colorList[x] = []
        for (y=0; y < cHeight/pR; y++){
            colorList[x][y] = Sloaded.get(x*pR, y*pR)
            noStroke(0)
            tint(colorList[x][y])
            image(Ploaded, x*pR, y*pR, pR, pR)
        }
    }
    noLoop()
}

This week’s project seemed at first a bit intimidating but after thinking about it, I decided creating a mosaic representation of a portrait using “tiles” of another image would be an approachable yet interesting approach. The portrait photo this project is based on is a photo I took of my friend in a car holding her small dog named Rocky. The tile photo I used for the mosaic was a close up of Rocky’s face.

The Tile Image
Screenshot of mosaic with tile size 40 pixels.
Screenshot of mosaic with tile size 4 pixels.

Looking Outwards 09 – John Legelis

While browsing previous week’s looking outwards responses, I stumbled upon Jessica’s article from Week 7 on data visualizations. She chose to write about a New York Times Graph that displays how different demographics spend their time throughout the day.

A still photo of the interactive New York Times graph representing how time is spent by different demographics

I agree that the creator’s artistic touch was manifested in the composition and intrinsic complexity of the data being represented. Though the graph doesn’t look extraordinarily eye catching, the data it represents is fascinating and the way it has been organized makes it intuitive to understand. It is difficult to have the results displayed in a data visualization obvious at first glance. As more facets are added to the data, the more information and variables must be squished into one visual, and things can get messy. The creator of this visualization elegantly combined a huge amount of data in a way that can be understood immediately.

John Legelis – Looking Outwards 08 Eyeo

Professor Meejin Yoon is the head of the architecture department at the Massachusetts Institute of Technology and she is the first woman to hold this post. She was born in Seoul, Korea and lived and studied in the United States. She has degrees from Cornell and Harvard in urban architecture.

Yoon’s work has often revolved around lighting and the impacts of light pollution  on the environment. I am personally supportive of these types of projects because I believe that as society has become more nocturnal, we need to be conscious of our impacts on the environment in non-obvious ways such as light pollution. Her particular work on projects in boston (my hometown) are very inspiring due to their benefits seen to the public space.

Design Competition Winner for Boston Bridge by Meejin Yoon

In her presentation Yoon rarely if ever had slides with text on them. Instead when she was using her slideshow to accompany her talk, she showed visuals that went along with what she was talking about. This caused the listener to not only pay attention to what Yoon was saying, but also created attention grabbing slides that kept the listener engaged. This method of presenting caused Yoon to be a key part of the presentation instead of simply a reader for the slides.