Set 07 (Due 10/15)

The readings, assignments, and projects below constitute the Week 07 Deliverables and are due by 11:59pm EDT on Thursday, October 15.


Technical Readings and Viewings

We highly recommend that you watch the following three videos by Dan Shiffman, which recap key concepts in object-oriented programming. Really: actually do it. We’re all fortunate that such a great educator is explaining this material using a visually-oriented approach and the same programming toolkit.

You may also wish to re-review chapters 10 and 11 in GSWp5js, on Objects and Arrays.


Looking Outwards 07: The Creative Practice of an Individual

This Looking Outwards is different from previous ones. Instead of identifying a project that you like, this time you will identify and study the work of a person whose work you admire. Your mission is to get an overall feel for that individual’s body of work by watching them give a 45-minute artist lecture.

For this Looking Outwards, we’ve decided to limit your choices to the ~150 speakers who have spoken at the Eyeo Festival (and its smaller sibling, the Inst-Int Festival). Over the past 5 years, these Minneapolis-based festivals have curated an amazing group of speakers who work in computational new media and interactive arts. They work as artists, designers, architects, musicians, directors, activists, engineers and inventors. In nearly every case, the festivals have posted videos of their lecture presentations on their Vimeo account.

Browse the following Vimeo channels. Watch a lecture video that seems interesting.

Of course, we understand that 45-50 minutes is a significant investment of your time. To help you choose a speaker who is best matched to your interests, you can contact the instructors via Piazza to ask for a recommendation, or you might find it helpful to browse the web pages of the actual festivals, which contain helpful indexes to their speakers:

Now, in a blog post of about 150-200 words,

  • Briefly summarize the person’s bio, perhaps with a bit of supplemental Googling. Who are they? where are they based? What did they study? How do they describe themselves and what they do?
  • Discuss the person’s body of work. What do you admire about the way they work, and why do you admire these aspects of it? Which projects of theirs do you admire the most, and why?
  • Observe how they present. What strategies do they use to present their work effectively? What can you learn about how to present your own work?
  • Link to the speaker’s web site. You can generally find links to their site(s) in the Vimeo video descriptions.
  • Embed their lecture video. If possible, additionally embed a video of one of their projects that you admire.
  • Label your blog post with the Category, LookingOutwards-07.
  • Label your blog post with the Category referring to your section (e.g.GolanSectionRogerSectionARogerSectionBRogerSectionD, or RogerSectionE).

Some brief remarks:

  • Some speakers have presented more than once at the Eyeo Festival. For the best overview of their work, we recommend you search for their first (oldest) lecture at the festival. Often (but not always), their first lecture is an overview of their practice, while their second lecture is an “update”. On the other hand, it’s great to see the cutting-edge stuff, too.
  • Some of the videos are from panels or 5-minute “Ignite” lectures. Ignore those; choose the 30-60 minute talks instead.
  • Yes, it so happens that (Professor) Golan Levin is one of the Eyeo Speakers. You may not select him. Move along.


Assignments 07: Overview of the Village (Parts A, B, C)

You can think of this set of Assignments as extending the features in Lauren McCarthy’s JitterBug examples for p5.js, which we discussed in class last week. (See Golan’s notes from October 7 if you’d like a reminder.) Instead of Jitterbugs, we will be making a little society (i.e. array) of Villager objects. We’ve broken down the problem into a few pieces for you. Eventually, the results of your efforts will look something like this:

village

The Villagers are very similar to the JitterBugs in the p5.js example:

  • They have an x and y position
  • They have a size
  • They are able to move(), by adding small random deviations to their position
  • They are able to display() themselves

but they have some additional properties as well:

  • They have a name, which is constructed from special prefixes and suffixes
  • They wear certain color garments, depending on certain social considerations.

The village has the following social structure:

  • There is a leader, who is the largest among them. The leader wears red, and can initially be found in the center of the village.
  • There is a royal family, whose names end with the same suffix as the leader’s. The members of the royal family wear orange.

For example, in the GIF shown above, there are about 20 villagers. The largest among them is their leader, “Roler”, who is centrally located, wearing red. Roler’s family members, who are wearing orange, all have the same -ler suffix in their name: Teler, Zaler, Goler.

You are provided with various code template, below, and you will be asked to fill out functions in order to implement the above.

Code Skeletons.

Below is a skeleton for your sketch (not including the definition of the Villager object):

//------------------------------------------------------
// You may not modify any lines of code in setup() or draw(), 
// though you will be adding a few new lines of code to setup().
// Also: you may not introduce any new global variables. 
 
var villagers = []; 
 
function setup() {
    createCanvas(800,400); 
 
    var prefixes = ["Lu", "Mi", "Vi", "Go", "Za", "Bu", "Te", "Ro"];
    var suffixes = ["mo", "ler", "ca", "va", "ger", "ran", "kla"];
    var nVillagers = 30;
 
    buildVillagers (nVillagers, prefixes, suffixes); 
}
 
function draw() {
    background(200);
    updateVillagers();
}
 
//------------------------------------------------------
// All of the code below is for you to complete. 
 
function buildVillagers(nVillagers, prefixList, suffixList) {
    // Write Code here!
}
 
function findLargest() {
    // Write Code here!
}
 
function setRoyalFamily(largestVillager) {
    // Write Code here!
}
 
function updateVillagers() {
    // Write Code here!
}

Below is an empty prototype for the Villager:

function Villager() {
    this.name = "Default";
    this.x;
    this.y;
    this.size;
    this.col = color(255);
    // Feel free to add more attributes. 
 
    // --------------------------------------------- //
    // ----------------BUILDING--------------------- //
    // --------------------------------------------- //
 
    this.build = function(prefixList, suffixList) {
        // DO NOT modify the code in this function!
        this.buildName(prefixList, suffixList);
        this.pickPosition();
        this.pickSize();
    }
 
    this.buildName = function(prefixList, suffixList) {
        // Write Code here!
    }
 
    this.pickPosition = function() {
        // Write Code here!
    }
 
    this.pickSize = function() {
        // Write Code here!
    }
 
    // --------------------------------------------- //
    // ----------------DISPLAYING------------------- //
    // --------------------------------------------- //
    this.draw = function() {
        // Write Code here!
    }
 
    // --------------------------------------------- //
    // ----------------UPDATING--------------------- //
    // --------------------------------------------- //
    this.move = function() {
        // Write Code here!
    }
}

Assignment 07-A. Building and Displaying the Villagers

In this part of the Assignment, you will:

  1. Complete the contents of the buildVillagers() function
  2. Complete the Villager’s pickPosition() and pickSize() functions
  3. Write an initial working draft of the Villager’s draw() and move() functions.
  4. Complete the updateVillagers() function in the main sketch, so that we can see a preliminary version of the Villagers onscreen.

When you’re done with Part A, you should have something that looks like the GIF below. If it looks similar to the JitterBug examples we studied in class, that’s because, for the moment anyway, it is. (Of course, there’s some additional stuff you can’t see going on, underneath the hood.)

village1

1. Complete the contents of the buildVillagers() function.
This function makes all of the Villagers in our array. As you can see, this function takes as arguments:

  • a number of desired villagers,
  • an array of prefixes, and
  • an array of suffixes.

The buildVillagers() function should contain a for() loop that creates each of the Villagers in the array called villagers. Inside this for() loop, you will want to:

  • create a temporary local variable, to represent a new Villager;
  • invoke this particular Villager’s build() method, passing the correct arguments into it. (See the next paragraph below for more details on that.)
  • push this particular Villager onto the villagers array.

It’s worth looking closely at the Villager’s own build() function. As you can see in the provided code above, the Villager’s build() function will cause that Villager to construct a randomized name for themselves. (We’ll deal with that later.) It will then also cause them to pick their position and size. The key point here is that, when calling the Villager’s build() function from inside buildVillagers(), you’ll need to make sure you “pass through” the arrays of prefixes and suffixes, since the Villager needs those in order to construct their name.

2. Complete the Villager’s pickPosition() and pickSize() functions. 

  • In the Villager’s pickPosition() function, give the Villager a random location on the canvas. Do this by assigning the Villager’s x and y values to be random numbers bounded by the width and height, respectively.
  • In the Villager’s pickSize() function, assign their size to be a random number between 10 and 25.
  • We will deal with the Villager’s buildName() function in the next sections.

3. Write a first working draft of the Villager’s draw() and move() functions.

  • For the time being, in drafting the Villager’s draw() function, just render the Villager as an ellipse, centered at (x,y) with a diameter set to the Villager’s size. For now, use default settings for the fill color, stroke color, stroke weight and other properties.
  • Fill out the Villager’s move() function by adding a small random deviation to the Villager’s x and y values. A random number between -1 and 1 should be adequate. Essentially, you are copying the code from the JitterBug’s move() function here. This amount of animation will be sufficient for this week’s Deliverables; nothing further is requested for the Villager’s move() function.

4. Complete the updateVillagers() function in the main sketch. 
Now that the Villagers know how to draw and move themselves, you can fill out the updateVillagers() function in the main sketch’s draw loop. This should be a for() loop that iterates over all of the items in the villagers array, requesting each one to draw() and move() themselves in turn. See the JitterBug example if you need to understand this better.

Here is a checklist for this assignment:

  • Put the following information into comments at the top of your code: Your name; Your class section or time; Your email address, including @andrew.cmu.edu; and Assignment-07-A
  • Name your project UserID-07-a.
  • buildVillagers creates the number of villagers given by its first parameter
  • The initial positions of all villager objects is random, but within the canvas boundaries.
  • The size of all villager objects is randomly chosen between 10 and 25.
  • Villagers are drawn in the correct size, correct location, and appear as white-filled circles.
  • Villagers move up or down and left or right by a random amount from -1 to +1 on every frame.
  • Your code should follow the “Style Do’s and Don’ts”. Do you chose random locations based on the canvas dimensions or do you use “magic numbers”? Did you add comments to explain what your code is doing and what variables are used for?
  • Zip and upload your code to Autolab, using the provided instructions. Zip your entire sketch folder. (Since you’re using our new lightweight sketch template, there will be no libraries subdirectory to include.)

Assignment 07-B. Building and Displaying Villager Names

In this part of the assignment, you will construct and display the Villager’s names. When you’re done with this part of the Assignment, your sketch should look something like this:

village2

1. Get their default name string displaying in the correct place.
Initially, you will notice that Villagers are born with a default name, “Default”. We recommend you begin by modifying the Villager’s draw() function so that it displays their (default) name, centered and over their heads. Your sketch should now look something like this screenshot:

Screen Shot 2015-10-10 at 12.37.37 PM

2. Construct their name, by completing the Villager buildName() function.
Villager’s names are constructed in their buildName() function. This function is called by the Villager’s build() function, which is in turn called by the sketch’s buildVillagers() function, which is in turn called within setup(). Good! So:

You will observe that the Villager’s buildName() function takes two arguments: prefixList and suffixList. We will assume that these are each arrays of strings. We also assume that these are defined elsewhere in the sketch. (They have!) Now, in buildName():

  • Create a random integer between 0 and the number of prefixes. (You might find the floor(), int() or round() functions helpful). Use this number to fetch a random prefix, and store that string.
  • Do the same for the suffix.
  • Assign the Villager’s name to be the result of concatenating the random prefix and suffix strings you selected for them.
  • You might find it helpful for Villagers to store their prefix and suffix persistently, in additional variables.

Here is a checklist for checking and completing the assignment:

  • Put the following information into comments at the top of your code: Your name; Your class section or time; Your email address, including @andrew.cmu.edu; and Assignment-07-B
  • Name your project UserID-07-b.
  • Text should display the name of each villager.
  • The text should be centered above each villager (hint: see textAlign())
  • The text should be above the villager.
  • The name is constructed randomly from the prefix and suffix lists.
  • All the code for creating, placing, and animating the villagers from part A should still be working.
  • All of your code should adhere to the style guidelines found in our “Style Do’s and Don’ts”.
  • Zip and upload your code to Autolab, using the provided instructions. Zip your entire sketch folder. (Since you’re using our new lightweight sketch template, there will be no libraries subdirectory to include.)

Assignment 07-C: Constructing Villager Society

In this final part of the Assignment, you will:

  1. Identify the largest Villager, which should be returned by findLargest().
  2. Based on the identity of the largest Villager, create the royal family in setRoyalFamily(). This will color various Villagers appropriately.
  3. You should only have to determine who the leader is ONCE.
  4. Modify the Villager’s draw() function so that it displays their color.

Here we go.

1. Identify the largest Villager. 
In setup(), declare a temporary Villager variable and assign this to be the result of calling findLargest(). Now complete the code of findLargest() so that it determines which Villager is the largest, and returns that Villager. (That Villager will be our “Leader.”) If there is a tie, in other words, if two or more villagers are the same size and larger than all the rest, then pick one of these largest villagers arbitrarily to be the “leader.”

2. Create the royal family. 
Villagers whose names end with the same suffix as the Leader are members of the royal family. Here, we will figure out which villagers they are. This is done in setRoyalFamily().

The setRoyalFamily() function needs to know who the Leader is, in order to mark which other villagers are (or are not) part of the royal family. In setup(), pass the Leader into the setRoyalFamily() function. Now inside the setRoyalFamily() function: for each Villager whose suffix is the same as the Leader’s, set their color property to orange. Afterwards, set the color property of the Leader to red, and position the Leader in the center of the canvas.

3. Display Villager colors correctly. 
Finally, modify the Villagers’ draw() function so that it displays their color correctly. You’re done!

village

Here is a checklist for checking and completing this assignment:

  • Put the following information into comments at the top of your code: Your name; Your class section or time; Your email address, including @andrew.cmu.edu; and Assignment-07-C
  • Name your project UserID-07-c.
  • There is a leader which is the largest villager (if there is a tie, the leader is one of the largest.
  • The leader is initially in the center of the canvas.
  • The leader is filled with red.
  • Every villager with the same suffix string as the leader (except for the leader itself) is orange.
  • All of the behavior from assignment B (names, initial locations of non-leaders, animation) is working as in assignment B.
  • All of your code should adhere to the style guidelines found in our “Style Do’s and Don’ts”.
  • Zip and upload your code to Autolab, using the provided instructions. Zip your entire sketch folder. (Since you’re using our new lightweight sketch template, there will be no libraries subdirectory to include.)


Project 07 – Generative Landscape: An Ever-Changing Terrain

(Also known as: “stuff passing by”.)

homer-trump

Create a program which presents an ever-changing (generative) and imaginative “landscape”. Come up with a concept, and populate your landscape with features and objects that are suitable for your concept: perhaps trees, apartment buildings, huts, vehicles, animals, people, asteroids, sea anemones, food items, body parts, hairs, zombies, etc.

train-window-nothing

The landscape should move past the “camera”, but you can elect the way in which it does so; for example, it might appear to scroll by (as if you were looking out the window of a train or submarine); or approach from a first-person point of view (as if you were driving); or slide underneath (as if you were looking out of a glass-bottomed airplane). The camera might be viewing an outside environment, or viewing objects on a conveyor belt, etc.

gmgd3

Give consideration to the depth of variation in your landscape: after how much time does your landscape become predictable? How might you extend this inevitability as much as possible? How can you make a landscape which is consistent, yet surprising? You may need to make a variety of different elements, and continually change how you clump them. Consider how these elements themselves can be generative, which is to say, synthesized on-the-fly, with all sorts of subtle variation.

Some possibilities to consider:

  • people + trees + buildings (According to Jungian psychology, these are the “three verticals”, the basic psychological features of landscapes)
  • foreground, middleground, and background “layers”
  • variation at the macro-scale, meso-scale, and micro-scale.
  • surprise: unusual and/or infrequent items in the landscape
  • utopia, dystopia, heterotopia

Requirements:

  • Sketch first on paper.
  • Create your landscape in p5.js.
  • Your assignment must incorporate at least one type of JavaScript Object that you yourself have defined (i.e. “Building”, “Vehicle”, etc.) where the objects we see are instances with randomized properties (such as their number of floors, color, etc.)
  • Limit your design to a canvas which is no larger than 800 x 800 pixels, please.
  • 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 images of paper sketches from your notebook; these could be as simple as photos captured with your phone.
  • Label your project’s blog post with the Category Project-07-Landscape.
  • Label your project’s blog post with the Category referring to your section (e.g. GolanSection, RogerSectionARogerSectionBRogerSectionD, or RogerSectionE).

Here are some possibly helpful code fragments to help you understand how you could get started.

The following program generates a row of Building objects, which continually slip out of view. New buildings are randomly added from time to time (with a low probability). Buildings have a random number of floors.

sketch

var buildings = [];

//----------------------------------
function setup() {
    createCanvas(640, 240); 
    
    // create an initial collection of buildings
    for (var i=0; i<10; i++){
        var rx = random(width);
        buildings[i] = new Building (rx);
    }
}

//----------------------------------
function draw() {
    background(200); 
    
    displayStatusString();
    displayHorizon();

    updateAndDisplayBuildings();
    removeBuildingsThatHaveSlippedOutOfView();
    addNewBuildingsWithSomeRandomProbability(); 
}


//----------------------------------
function updateAndDisplayBuildings(){
    // Update the building's positions, and display them.
    for (var i=0; i<buildings.length; i++){
        buildings[i].move();
        buildings[i].display();
    }
}

//----------------------------------
function removeBuildingsThatHaveSlippedOutOfView(){
    // If a building has dropped off the left edge, remove it from the array. 
    for (var i=0; i<buildings.length; i++){
        if (buildings[i].x < 0-buildings[i].breadth){
            buildings.splice(i, 1); // look it up
        }
    }
}

//----------------------------------
function addNewBuildingsWithSomeRandomProbability(){
    // With a very tiny probability, add a new building to the end.
    var newBuildingLikelihood = 0.007; 
    if (random(0,1) < newBuildingLikelihood){
        buildings.push(new Building (width));
    }
}

//----------------------------------
function Building (birthLocationX){
    this.x = birthLocationX; 
    this.breadth = 50; 
    this.speed = -1.0;
    this.nFloors = round(random(2,8)); 
    
    this.move = function() {
        this.x += this.speed;
    }
    
    // draw the building and some windows
    this.display = function() {
        var floorHeight = 20;
        var bHeight = this.nFloors * floorHeight; 
        fill(255); 
        stroke(0); 
        push();
        translate(this.x, height-40);
        rect(0,0, this.breadth, -bHeight);
        stroke(200); 
        for (var i=0; i<this.nFloors; i++){
            rect(5,-15-(i*floorHeight), this.breadth-10,10);
        }
        pop();
    }
}

//----------------------------------
function displayHorizon(){
    stroke(0);
    line (0,height-50, width, height-50); 
}

//----------------------------------
function displayStatusString(){
    noStroke(); 
    fill(0); 
    var statusString = "# Buildings = " + buildings.length;
    text(statusString, 5,20); 
}

If your Project looks like the above template, we will become really, deeply, profoundly sad. We implore you to think beyond the provided sample code, and to come up with something more interesting.

Incidentally, the sketch below shows what’s “really” going on here, in terms of the way buildings are added (on the right) and removed (on the left). We’re using the splice() function to remove buildings from the array of objects. (Also: check out the little pattern we use to decide whether or not to add a new building.)

sketch

Here’s a simple demonstration of the noise() function, which is very useful for generating randomized terrain:

sketch

// Simple demonstration of the noise() function. 
// Change these for different effects:
var terrainSpeed = 0.0005;
var terrainDetail = 0.005;

function setup() {
    createCanvas(640, 240);
}
 
function draw() {
    background(255);
    
    noFill(); 
    beginShape(); 
    for (var x=0; x<width; x++){
        var t = (x*terrainDetail) + (millis()*terrainSpeed);
        var y = map(noise(t), 0,1, 0,height);
        vertex (x, y); 
    }
    endShape();
    
    rect(0,0, width-1,height-1);
}
 

Finally, here’s a pretty picture of a landscape made from recycled lamps, by artist Rune Guneriussen.

Rune-Guneriussen-recycled-object-light-installation-art