Deliverable 08 - Fall 2023

Due Saturday, Oct. 28, 2023 by 11:59PM


PREPARING YOUR HANDIN FOLDER...

FIRST: Create a folder or subdirectory in your 15-104 working area on your computer or in your Andrew private folder for handin-08. You will put all of your work inside this folder and then compress or zip it to create handin-08.zip to submit to Autolab.


Conceptual Questions

In this part of the deliverable, you will download this Word file that contains 4 questions about concepts taught in class. You may download it anywhere on your computer. You should fill in your answers in the spaces provided, and include your name, andrewID and section letter at the top of page 1.

Once you are finished with this part of the deliverable, print/save it as a PDF and store this PDF in your handin-08 folder with the name andrewID-08-concepts.pdf. For example, if your andrewID is acarnegie, then you would save the PDF under the name acarnegie-08-concepts.pdf.


Technical Assignment 08: Mixies (3 points)

This Assignment is to be submitted through Autolab. Its purpose is to practice use of while loops, use of random numbers, use of arrays and use of images on your canvas.

An “Exquisite Corpse“, also known as an exquisite cadaver (from the original French term cadavre exquis), is a method by which an image is collectively assembled. Often, a simple set of rules is devised that allows each contributor to add his or her contribution without knowledge about how the final composition will appear. For example, one person might draw the head of a creature, while someone else would draw the body, while a third person might add the feet. The Exquisite Corpse was a popular parlor game in the Victorian era, and was rediscovered by Surrealist and Dadaist artists in the early 20th century as a quasi-algorithmic generative technique for creating surprising new forms. Below is a set of exquisite corpse artworks by artists (and brothers) Jake and Dinos Chapman, from the collection of the Tate Museum, London.

Samples of Chapman artwork

And here's an interactive exquisite corpse installation by Professor Golan Levin (2007).

Reface Interactive Exhibit photo

(Watch a YouTube video about the installation.)

In this assignment, you will create an interactive exquisite corpse software, using the circus characters from a set of “Mixies” cards from 1956:

Picture of outside box for Mixies game

Courtesy of Meg Richards (former student and CMU staff member), we have been generously provided with scans of her collection of Mixies cards, which were produced in 1956 by the Ed-u-Cards Manufacturing Company. In these cards, a figure of a person or animal was cut into three pieces and each placed on a card. The deck consisted of 12 heads, 12 bodies, and 12 feet, which players could mix up in different ways. The box states that the game can generate “1001 funny figures,” but in fact, there are 12 x 12 x 12 = 1728 unique combinations. (Perhaps 727 of them are less funny than the others.)

One possible combination of Mixies cards

You can find all of the image assets on imgur.com. Here are the links in the form of JavaScript arrays. You can paste this into your sketch:

// these three arrays, bodyLinks, feetLinks, and headLinks can be
// used to access images for Technical Assignment 8
var bodyLinks = [
    "https://i.imgur.com/5YM2aPE.jpg",
    "https://i.imgur.com/oKtGXfd.jpg",
    "https://i.imgur.com/Kvg75bG.jpg",
    "https://i.imgur.com/0FGzErn.jpg",
    "https://i.imgur.com/MJmlPt5.jpg",
    "https://i.imgur.com/VvX0k8e.jpg",
    "https://i.imgur.com/rLIOBoG.jpg",
    "https://i.imgur.com/q03Gko3.jpg",
    "https://i.imgur.com/BWpN5SP.jpg",
    "https://i.imgur.com/ft10TV3.jpg",
    "https://i.imgur.com/CGCZliN.jpg",
    "https://i.imgur.com/qrlc4dK.jpg"]
    
var feetLinks = [
    "https://i.imgur.com/oNSO0T6.jpg",
    "https://i.imgur.com/OWGETX7.jpg",
    "https://i.imgur.com/Zp29aVg.jpg",
    "https://i.imgur.com/AXLWZRR.jpg",
    "https://i.imgur.com/wgZq717.jpg",
    "https://i.imgur.com/sGVMEMw.jpg",
    "https://i.imgur.com/hfbrynH.jpg",
    "https://i.imgur.com/OOASUMM.jpg",
    "https://i.imgur.com/aqtIXi0.jpg",
    "https://i.imgur.com/Eu6ruPo.jpg",
    "https://i.imgur.com/mTSipwg.jpg",
    "https://i.imgur.com/1GzC4Zz.jpg"]
    
var headLinks = [
    "https://i.imgur.com/gBCZVuM.jpg",
    "https://i.imgur.com/YLOXAdH.jpg",
    "https://i.imgur.com/my3TqY7.jpg",
    "https://i.imgur.com/lvtIB9s.jpg",
    "https://i.imgur.com/gvDBfhO.jpg",
    "https://i.imgur.com/JEuJ2ER.jpg",
    "https://i.imgur.com/SbBOG1V.jpg",
    "https://i.imgur.com/cuJ5Ao1.jpg",
    "https://i.imgur.com/dqHjjig.jpg",
    "https://i.imgur.com/mcFUcHf.jpg",
    "https://i.imgur.com/0XKU9Dx.jpg",
    "https://i.imgur.com/sD1ArAR.jpg"]
  

You will draw a 3 X 3 grid of (random) cards. When you click the mouse, you will generate a new 3 X 3 grid of (random) cards. However, in any row of cards, you can’t pick two of the same cards. Your output will look something like this:

Sample 3 X 3 grid of Mixies images

Program requirements

This assignment is broken down into parts so you can work on each step to get something working before moving on to the next step. Do not try to solve this entire problem in one sitting. Work on each step and make sure it's correct. Then make a backup of your program and then continue on to the next step. If you make a mess of your program, you can always go back to the prior backup you saved!

  1. Make your sketch simply select a new card at random for each vertical column of 3 cards. Don’t worry if you repeat any cards.
    • Include the global arrays with the URLs as given above. Note that these are arrays of strings. They're not the images themselves.
    • Create global arrays (initially empty) called headImages, bodyImages, and feetImages. These will hold (references to) the image objects of cards.
    • Create global arrays called head, body and feet. These will store the images for the three head cards you randomly select, the three body cards you randomly select, and the three feet cards you randomly select. Do not use 9 separate variables to hold the images for the 9 cards you display!
    • Write a preload function that loads the images from the URLs in the arrays headLinks, bodyLinks and feetLinks into the arrays headImages, bodyImages and feetImages, respectively. Note that you can do this with just a small amount of code. If you write more than about 5-7 lines of code, you are probably doing something wrong.
    • Set up a canvas of size 600 (wide) by 450 (high), where each card will be displayed as 200 (wide) by 150 (high). In your setup function, add (push) 3 different head images to the head array, three different body images to the body array and three different feet images to the feet array. You can just pick whichever images you wish for now.
    • Write a draw function so that draws the nine selected images on the canvas like in the example above. Note that you are initializing the head, body and tail arrays in the setup function, so when the draw function repeats, it will just draw the same images again and again, so the image should look static.
    • Test your program so you see what is required, and then save a copy of the sketch file as sketch-v1.js .
  2. Update your sketch so that if click the mouse, a new random permutation of three figures is displayed. Don’t worry if you select the same card twice.
    • Add a mousePressed function that clears the contents of the head, body and tail arrays. It then picks three random head images to push into the head array, three random body images to push into the body array, and three random feet images to push into the feet array. Don't worry if you pick the same image more than once.
    • Now when you start your program, you should see your initial selection, then each time you click the mouse, you should get some other permutation of heads, bodies and feet.
    • Test your program so you see what is required, and then save a copy of the sketch file as sketch-v2.js . If you get to this point successfully, you will earn 2 points of the 3 points.
  3. Next, update your sketch so that you guarantee that a particular card is never displayed twice in a row. (For example, you should not pick the same body for two columns.) To achieve this requirement, your code must use a while() loop.
    • You will need to reprogram your mousePressed function to accomplish this task. You will still need to clear the current head, body and tail arrays. But how you pick the new images will differ.
    • For each part (body, head, feet), randomly pick the part for the first figure and store it in the corresponding array. Then randomly pick the part for the second figure. While it is the same as the part for the first figure, keep picking randomly. Then randomly pick the part for the third figure. While it is the same as the parts for the first or second figure, keep picking randomly. (NOTE: You could write one additional function that does this regardless of the part and then use it for the head, the body and the feet.)
    • Test your program so you see what is required, and then save a copy of the sketch file as sketch-v3.js . If you get to this point successfully, you will earn 2.5 points of the 3 points.
  4. Finally, update your sketch so that only the head, body or foot section is changed if the user clicks in the corresponding region of the canvas. If you get to this point successfully, you will earn all 3 points.

Be sure to store the code and index file for this assignment in a subfolder named according to our conventions in your handin folder. Remember that you could lose up to 1 point if your code is formatted poorly. If you submit just the final program without any of the prior versions, you will not receive the full credit on the assignment.


Open-ended Project 08: Composition with Curves (3 points)

Sample Spirograph drawings

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.

Here is an example that displays an epitrochoid and a cranioid, switching between them when the mouse is clicked:

Epitrochoid image from program   Cranioid image from program

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, a program is shown below to draw 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!

Five circles rendered differently

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();
}


Handing in your work

Your handin folder handin-08 should have the two folders described above.

You will zip up the handin-08 folder and submit this to Autolab. Your overall folder organization should look something like this (indentation indicates subfolders):


  handin-08
    andrewID-08-assignment
      index.html
      sketch.js
      sketch-v1.js
      sketch-v2.js
      sketch-v3.js
    andrewID-08-concepts.pdf
    andrewID-08-project
      index.html
      sketch.js


NOTE: You might not have all of the backup versions shown if you don't complete the technical assignment.

Once you are ready to submit, zip (compress) the handin-08 folder (which will likely be named handin-08.zip) and hand in the ZIP FILE into the Deliverable 8 submission area on Autolab. Once you handin, check your handin history and click on the magnifying glass to look at what you submitted to make sure it looks right. IF YOU SUBMIT THE WRONG ZIP FILE, YOU RISK GETTTING A 0 ON THIS DELIVERABLE!

You may submit as many times as you’d like (in case you find inspiration and want to improve your work) up until the deadline. If you submit up to one day late, even if you submitted on time, you will be marked late. We only grade the final submission you upload to us via Autolab.