Week 7 (due Oct 16)

The readings, assignments, and projects below constitute the Week 7 Deliverables and are due by 11:59pm EDT on Saturday, October 16th:

  1. Technical Readings
  2. Looking Outwards 07 [Autolab & Blog]
  3. Assignment-07-A (Planting the Flag) [Autolab]
  4. Project-07: (Composition with Curves) [Autolab & Blog]
  5. Handin Instructions


1. Technical Readings


2. Looking Outwards 07: Information Visualization

Our Looking Outwards topic for this week is computational information visualization. We ask you to select a project in which an artist, designer or other researcher has created custom software in order to collect and/or visualize a dataset.

We particularly recommend the work of Aaron Koblin, Amanda Cox, Ben Fry & Fathom, Fernanda Viegas, Ingrid Burrington, Jen Lowe, Jer Thorp, Jonathan Harris, Kim Rees, Lev Manovich, Lisa Jevbratt, Martin Wattenberg, Moritz Stefaner, Nicholas Felton, Rachel Binx, Stamen Design, Santiago Ortiz, Nand.io, Stephanie Posavec, Wes Grubbs, or CMU’s own Chris Harrison, among others. (Many of these people also have given stimulating lecture presentations at the Eyeo Festival, which are available online.)

There are also a number of prominent blogs specifically devoted to documenting computational and interactive information visualization, including:

Identify a particular project or work which you find intriguing or inspirational. In a blog post of about 150-200 words,

  • Please discuss the project. What do you admire about it, and why do you admire these aspects of it?
  • What do you know (or what do you suppose) about the algorithms that generated the work?
  • It what ways are the creator’s artistic sensibilities manifest in the final form?
  • Link (if possible) to the work. To the best of your abilities, be sure to provide the creator’s name, title of the work, and year of creation.
  • Embed an image and/or a YouTube/Vimeo video of the project.
  • Create a descriptive caption for each image or video.
  • Label your blog post with the Categories LookingOutwards-07 and your section, e.g. SectionB.
  • REMEMBER: Also include your blog paragraph in your Autolab submission for full credit.


3. Assignment-07-A: Planting the Flag

In this Assignment, which should be uploaded to Autolab, you will create a random, scrolling terrain with flags at each peak. Study the stock market example from lab since there are some similarities between that example and this assignment.

Your job is to write code which automatically plants small flags on the hills of this landscape. Here’s an example of what your flags (or trees, street signs, cell towers, etc.) might look like:

terrain

For this Assignment, how your flags look is entirely up to you. However, what is crucially important is where they are placed. You must ensure that your flags are placed at the tops of the terrain’s hills.

Here are some guidelines for your assignment:

  • You should use the noise() function to create an array of vertical coordinates that will make up the terrain. The coordinates will be spaced 5 pixels at a time across the canvas horizontally, just like the stock market example.
  • Instead of drawing a series of lines across the canvas like in the stock market example, you will need to create a green shape made up of all of the points along with (width, height) and (0, height). (HINT: Use beginShape(), vertex() calls and endShape() to create the terrain.)
  • After you draw the terrain, you should go through the array of coordinates, and place a flag on top of each peak. Think about what condition must be true in order to see a peak on the canvas. You do not need to test for a peak on the edges of the canvas.
  • You should write a separate function to draw the flag. You should pass into this function as arguments the x, y position of the base of the flag.
  • Once you have the terrain and flags drawn, remove the first coordinate from the array and append a new random coordinate at the end of the array. Thus, when the draw function repeats, the terrain will appear to scroll, just like the stock market tracker did.
  • Make sure that your code accesses correct indices for the array. Javascript doesn’t crash if you access an invalid location, but we will look at your code to make sure you don’t have invalid array accesses.
  • Don’t forget to comment your code, and please give attention to code style.

4. Project 07: Composition with Curves

spirograph-640x480
The Spirograph was a toy with pens and gears for drawing curve patterns.

Mathematical curves allow for unique, expressive and surprising ways of generating and controlling graphics. This open-ended Project invites you to you experiment and play with the aesthetics of curves.

  • Browse the Mathworld curves site.
  • Select a curve from the site. In a canvas no larger than 480 x 480 pixels, develop an interactive composition using this curve. Feel free to use any graphical primitives, colors, and visual strategies you wish. You can layer the curve with other elements if you wish. Play.
  • Please note that not every Mathworld curve comes with a helpful diagram or an easy-to-implement equation. We recommend selecting curves whose equations take one of the following standard forms:
    • the standard explicit form y = f(x),
    • or curves which take the parametric form y = f(t), x = g(t).
    • or curves with the polar form r = f(theta). For some easy starters, check out the Spirograph-like roulette curves.
  • View the examples below for some sample code that deals with polar and parametric curves.
  • Create a simple interaction in which the mouseX and mouseY are used to continuously govern at least one (and preferably at least two) parameters of the curve. For this purpose (see the example below) we highly recommend you use the p5.js map() and constrain() functions.
  • When you’re done, embed your p5.js sketch in a WordPress blog post on this site, using the (usual) instructions here.
  • Ensure that your p5.js code is visible and attractively formatted in the post.
  • In your blog post, write a paragraph or two (~100-150 words) reflecting on your process and product.
  • Document your work by embedding a screenshot or two of your project in different states.
  • Label your project’s blog post with the Category Project-07-Curves.
  • Label your project’s blog post with the Category referring to your lab section.
  • Your code should adhere to our style guidelines.
  • REMEMBER: You must also submit your project code to Autolab for full credit.

Try clicking in the example below, to switch between an epitrochoid and a cranioid:

polar

var nPoints = 100;
var EPITROCHOID = 0; // Cartesian Parametric Form  [x=f(t), y=g(t)]
var CRANIOID = 1; // Polar explicit form   [r =f(t)]

var titles = ["1. Epitrochoid", "2. Cranioid"];
var curveMode = EPITROCHOID;


function setup() {
    createCanvas(400, 400);
    frameRate(10);
}


function draw() {
    background(255);
    
    // draw the frame
    fill(0); 
    noStroke();
    text(titles[curveMode], 20, 40);
    stroke(0);
    noFill(); 
    rect(0, 0, width-1, height-1); 
    
    // draw the curve
    push();
    translate(width / 2, height / 2);
    switch (curveMode) {
    case EPITROCHOID:
        drawEpitrochoidCurve();
        break;
    case CRANIOID:
        drawCranioidCurve();
        break;
    }
    pop();
}

//--------------------------------------------------
function drawEpitrochoidCurve() {
    // Epicycloid:
    // http://mathworld.wolfram.com/Epicycloid.html
    
    var x;
    var y;
    
    var a = 80.0;
    var b = a / 2.0;
    var h = constrain(mouseY / 8.0, 0, b);
    var ph = mouseX / 50.0;
    
    fill(255, 200, 200);
    beginShape();
    for (var i = 0; i < nPoints; i++) {
        var t = map(i, 0, nPoints, 0, TWO_PI);
        
        x = (a + b) * cos(t) - h * cos(ph + t * (a + b) / b);
        y = (a + b) * sin(t) - h * sin(ph + t * (a + b) / b);
        vertex(x, y);
    }
    endShape(CLOSE);
    
}

//--------------------------------------------------
function drawCranioidCurve() {
    // http://mathworld.wolfram.com/Cranioid.html
    
    // NOTE: given a curve in the polar form  r = f(theta),
    // 1. sweep theta from 0...TWO_PI,
    // 2. then compute r as a function of theta,
    // 3. then compute x and y using the circular identity:
    //    x = r * cos(theta);
    //    y = r * sin(theta);
    
    var x;
    var y;
    var r;
    var a = 40.0;
    var b = 10.0;
    var c = 100.0;
    
    var p = constrain((mouseX / width), 0.0, 1.0);
    var q = constrain((mouseY / height), 0.0, 1.0);
    
    fill(200, 200, 255);
    beginShape();
    for (var i = 0; i < nPoints; i++) {
        var t = map(i, 0, nPoints, 0, TWO_PI);
        
        // cranioid:
        r =
            a * sin(t) +
            b * sqrt(1.0 - p * sq(cos(t))) +
            c * sqrt(1.0 - q * sq(cos(t)));
        
        x = r * cos(t);
        y = r * sin(t);
        vertex(x, y);
    }
    endShape(CLOSE);
}

//--------------------------------------------------
function mousePressed() {
    curveMode = 1 - curveMode;
}

Please note that there are an infinity of different ways that you can render your curve(s)! For example, below are five different ways of rendering a circle. Also, please note that many curves on MathWorld are “open” (such as spirals and parabolas), and can’t be “closed” (like a circle); those curves are totally great and just fine too!

circles

function setup() {
    createCanvas(750, 200);
    frameRate(10);
}

function draw() {
    background(255, 200, 200);
    fill(255, 255, 255, 64);
    var nPoints = 20;
    var radius = 50;
    var separation = 125;
    
    // draw the circle normally
    push();
    translate(1*separation, height / 2);
    beginShape();
    for (var i = 0; i < nPoints; i++) {
        var theta = map(i, 0, nPoints, 0, TWO_PI);
        var px = radius * cos(theta);
        var py = radius * sin(theta);
        vertex(px,py); 
        ellipse(px, py, 3,3);
    }
    endShape(CLOSE);
    pop();
    
    // draw the circle as a sequence of little elements
    push();
    translate(2*separation, height / 2);
    for (var i = 0; i < nPoints; i++) {
        var theta = map(i, 0, nPoints, 0, TWO_PI);
        var px = radius * cos(theta);
        var py = radius * sin(theta);
        rect(px - 5, py - 5, 10, 10);
    }
    pop();
    
    // draw the circle as a starburst
    push();
    translate(3 * separation, height / 2);
    for (var i = 0; i < nPoints; i++) {
        var theta = map(i, 0, nPoints, 0, TWO_PI);
        var px = radius * cos(theta);
        var py = radius * sin(theta);
        line(0, 0, px, py);
    }
    pop();
    
    // draw the circle as a wiggly circle
    push();
    
    translate(4*separation, height / 2);
    beginShape();
    for (var i = 0; i < nPoints; i++) {
        var theta = map(i, 0, nPoints, 0, TWO_PI);
        var px = radius * cos(theta);
        var py = radius * sin(theta);
        vertex(px + random(-5, 5), py + random(-5, 5));
    }
    endShape(CLOSE);
    pop();
    
    
    // draw the circle as a dotted line
    push();
    translate(5*separation, height / 2);
    var qx = 0;
    var qy = 0;
    for (var i = 0; i <= nPoints; i++) {
        var theta = map(i, 0, nPoints, 0, TWO_PI);
        var px = radius * cos(theta);
        var py = radius * sin(theta);
        if ((i % 2 == 0) & (i > 1)) {
            line(qx, qy, px, py);
        }
        qx = px;
        qy = py;
    }
    pop();
}


5. Handin and Post Your Work

  • Zip (compress) your handin-07 folder, which should contain folders containing your blog essay, assignment and project, and upload your zip file to Autolab.
  • Remember to post your blog and your project in two separate posts on the WordPress course website with appropriate category labels so we (and students) can find your work easily.

Your zip file handin on Autolab must be submitted by Saturday, October 16th by 11:59PM EDT to be considered on time. Your blog and project posted on WordPress should be the same or similar to what you submitted in Autolab and should also be posted by the due date. (You may make minor corrections on WordPress for formatting issues.)