Deliverables 03 (Due 9/23)

Due Friday 9/23 at the beginning of class. 

This set of deliverables has 5 parts.

  1. Provide feedback on other students’ Clock assignments.
  2. Reading & Response: Generative Art Theory
  3. Looking Outwards 03: Generative Art
  4. Re-code: Vera Molnar’s Interruptions (1968-69)
  5. A Looping, Animated, Computationally Generated GIF

1. Feedback on Each Others’ Clocks

Using the Google form below, please provide helpful feedback on the Clock assignments made by your peers. All of your feedback will be anonymized, but may be posted publicly (after collation and anonymization) on this WordPress blog. Please note that the professor reserves the right to edit your feedback for clarity and/or tone.

Here’s the form:
https://goo.gl/forms/dbaudYgkt08DIPh23


2. Reading & Response: Generative Art Theory

For this deliverable, you will read an article, Generative Art Theory by Philip Galanter. In a blog post, you will write brief (50 word) responses to two questions below.

Galanter’s article appears as Chapter 5 (pages 146-175) in A Companion to Digital Art, Edited by Christiane Paul, 2016 by John Wiley & Sons, Inc. This PDF/eBook is available from the CMU Library at:

Question 1A. Read the first 20 pages of “Generative Art Theory” by Philip Galanter (p.146-166). In your own words, and in just a few sentences, discuss an example of something you like which exhibits effective complexity. Where does your selection sit between total order (e.g. crystal lattice) and total randomness (e.g. gas molecules, white noise, static). Include an image which illustrates your selection.

Question 1B. Quickly skim the remaining 10 pages of the article, in which Galanter outlines nine different problems with generative art (The Problem of Authorship; The Problem of Intent; The Problem of Uniqueness; The Problem of Authenticity; The Problem of Dynamics; The Problem of Postmodernity; The Problem of Locality, Code, and Malleability; The Problem of Creativity; The Problem of Meaning). Select one of these problems for which you yourself feel some sort of internal conflict or personal stake. Discuss your internal conflict. Which side of the argument do you come down on?

  • Categorize your blog post, Reading03.
  • Title your blog post, nickname-Reading03.

3. Looking Outwards 03: Generative Art

This deliverable is to be your third Looking Outwards report. Our topic for this week is Generative Art: art whose forms (images, sculptures, etcetera) have been generated by algorithms — algorithms created by artists, designers, architects, musicians, and poets.

“Generative art refers to any art practice where the artist uses a system, such as a set of natural language rules, a computer program, a machine, or other procedural invention, which is set into motion with some degree of autonomy contributing to or
resulting in a completed work of art.” — Philip Galanter, What is Generative Art? (2003)

Some places to get started include:

Here are some lists of generative artists:

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

  • Discuss the project. Respond to the questions:
    • What do you admire about the work, and why do you admire these aspects of it?
    • What do you know (or what do you suppose) about the algorithm that generated the work?
    • It what ways are the creator’s artistic sensibilities manifest in their algorithm?
    • What is the artwork’s effective complexity? Discuss the way that the artist has balanced order and disorder.
  • 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 of the project.
  • Embed a YouTube/Vimeo video of the project (if available).
  • Label your blog post with the Category, LookingOutwards03.
  • Title your blog post, nickname-LookingOutwards03.


4. Re-code: Vera Molnar’s Interruptions (1968-69)

[From Gerald King]: Perhaps you are wondering why artists copy paintings in museums, as I am doing. The answer is to study, to learn, and to find inspiration from the great masters of the past. Copying directly from works of art gives the artists insight into the creative process — insights which cannot be learned from any other source.

Vera Molnar, born 1924, is a Hungarian-French artist who was one of the first ten people to make art with a computer. Her web site is worth studying. For this assignment, we will hone our skills, as artists have done for centuries, by copying a masterwork. You are asked to use code to recreate her generative work, Interruptions, created in 1968-69.

04_2470

Here she is in the 1960s:

molnar-1960s

She wrote: “Thanks to its many possibilities of combination the computer helps to systematically research the visual realm, helps the painter to free himself from cultural ′readymades′ and find combinations in forms never seen before, neither in nature nor at a museum: It helps to create inconceivable images. The computer helps, but it does not ′do′, does not ′design′ or ′invent′ anything. To avoid another misunderstanding I wish to underline something else: The fact that something is new and has not been seen before is no guarantee in any manner for its aesthetic quality. Was the portrayal of a young man with curly hair − Dürer′s self-portrait from around 1500 − new?”

Now: carefully study the following five reproductions of her generative work, Interruptions, created in 1968-69. In p5.js, reproduce Interruptions to the best of your ability. Have your “re-coded” version of Interruptions generate a new version whenever the user clicks.

Now:

  • Begin by observing Molnar’s artwork very carefully. In a WordPress blog post, list all of the observations you made about Molnar’s artwork. By “observations”, I mean: facts you noticed. Some of these observations might seem painfully obvious, but please list them anyway. All of them. For example, your list might look something like the following:
    1. The artwork is square.
    2. The artwork consists of many short black lines, on a white background.
    3. The lines all have the same length.
  • Embed your p5.js app in your WordPress post. Please keep the size under 720 pixels wide.
  • Link to your Github repository for your code, as well.
  • Write 100-150 words about your process, including an evaluation of your results. Were there any observations you made, that you found challenging or difficult to reproduce? What are some things you learned, or now appreciate?
  • Categorize your blog post with the category, Interruptions.
  • Title your blog post with the title, nickname-Interruptions.


5. A Looping, Animated, Computationally Generated GIF

In this assignment, you will create a looping, animated GIF from computationally generated graphics. First, some inspiration:

3

  • Study the work of DVDP (Davidope): http://dvdp.tumblr.com/. (Be sure to click on the links (–) at the bottom of the site to see previous pages.) 
  • Study the work of Paolo Čerićhttp://patakk.tumblr.com/. (Again, be sure to click on the “older” links to see previous pages.) There is also a survey of some of his work in ThisIsColossal.
  • Study the work of Bees and Bombs.
  • Syed Reza Ali has been using animated GIFs to document his lovely work. For Ali, they are a compact, lightweight and durable format. His software may not be easy to get running in ten years, but the GIFs will still work reliably.

Others use drawn and photographic media. It’s worth examination:

  • Cindy Suen has lovely concepts.
  • The British experimental animator, Cyriak Harris, is a prodigious creator of weird and disturbing animated GIFs.
  • If you’ve got time to kill, there’s also this epic NSFW GIF mashup by Evan Roth:

Now:

  1. SKETCH FIRST! Before doing anything, make some (real) sketches in your notebook.
  2. Write code which creates a (seamlessly) looping animation. You may use the code templates below to get started. I’ve provided templates in Processing (Java), and p5.js. With permission of the instructor, you may use another environment (such as Python in Rhino, Python in Maya, Expressions (JavaScript) in After Effects, or Python in Blender (API), so long as your solution is scripted. (Please note that the professor and TA will only officially provide support for p5.js and Processing.)
  3. Your design may be abstract, figurative, etc. according to your tastes. I recommend that your image be no larger than 600 pixels wide, and that you restrict yourself to just a few colors. Remember, GIFs must represent all of your frames with a single a palette of just 256 colors. You may find this resource helpful, tips for making animated GIFs.
  4. Export a series of frames, and compile these into an animated GIF. You can do this with an online tool like http://gifmaker.me/. Alternatively, here is a helpful tutorial for creating animated GIFs from folders of images, using Photoshop. Remember to set its duration to “forever”. Your GIF can be any length, but keeping it under 2MB would be sensible, and there is a hard upload limit of 12MB per file for our WordPress site.
  5. In a blog post, upload and embed your animated GIF. Be sure not to embed any version that has been automatically resized by WordPress; it will not be animated!
  6. If you developed your project using p5.js, please embed a live (running) version of that as well.
  7. Write a paragraph about the experience of creating the piece. Critique your work: where you feel you succeeded, where you feel you fell short of what you’d hoped to achieve.
  8. Include a scan or photo of your pen-and-paper sketches.
  9. Embed your code into the blog (use the WP-Syntax plugin if you wrote Java code). Instructions for doing so are here and here. Note that you may need to switch to the WordPress text (not Visual) editing mode at this point. (Otherwise, code with < and > characters can get messed up.)
  10. Link to your code for this project on Github.
  11. Label your blog post with the Category, AnimatedLoop.
  12. Title your blog post, nickname-AnimatedLoop.

Here’s a p5.js template for exporting frames for an animated GIF loop. To export the frames, you’ll need to set bIAmRunningThisOnMyLaptop to true.

gif-loop-generator.js

// This is a template for creating a looping animation in p5.js. 
// When you press a key, this program will export a series of images
// into an "output" directory located in its sketch folder. 
// These can then later be combined into an animated gif. 
// Known to work with p5.js version 0.5.3
// Prof. Golan Levin, September 2016

//===================================================
// Global variables. 
var nFramesInLoop = 120;
var nElapsedFrames;
var bRecording;
var bIAmRunningThisOnMyLaptop = false;

//===================================================
function setup() {
  createCanvas(500, 200);
  bRecording = false;
  nElapsedFrames = 0;
}

//===================================================
function keyPressed() {
  if (bIAmRunningThisOnMyLaptop) {
    bRecording = true;
    nElapsedFrames = 0;
  }
}

//===================================================
function draw() {

  // Compute a percentage (0...1) representing where we are in the loop.
  var percentCompleteFraction = 0;
  if (bRecording) {
    percentCompleteFraction = float(nElapsedFrames) / float(nFramesInLoop);
  } else {
    percentCompleteFraction = float(frameCount % nFramesInLoop) / float(nFramesInLoop);
  }

  // Render the design, based on that percentage. 
  renderMyDesign(percentCompleteFraction);

  // If we're recording the output, save the frame to a file. 
  // Note that the output images may be 2x large if you have a Retina mac. 
  // You can compile these frames into an animated GIF using a tool like: 
  if (bRecording & bIAmRunningThisOnMyLaptop) {
    var frameOutputFilename = "mynickname-loop-" + nf(nElapsedFrames, 4) + ".png";
    println("Saving output image: " + frameOutputFilename);
    saveCanvas(frameOutputFilename);
    nElapsedFrames++;
    if (nElapsedFrames >= nFramesInLoop) {
      bRecording = false;
    }
  }
}

//===================================================
function renderMyDesign(percent) {
  // This is an example of a function that renders a temporally looping design. 
  // It takes a "percent", between 0 and 1, indicating where we are in the loop. 
  // This example uses two different graphical techniques. 
  // Use or delete whatever you prefer from this example. 
  // Remember to SKETCH FIRST!

  //----------------------
  // here, I set the background and some other graphical properties
  background(180);
  smooth();
  stroke(0, 0, 0);
  strokeWeight(2);

  //----------------------
  // Here, I assign some handy variables. 
  var cx = 100;
  var cy = 100;

  //----------------------
  // Here, I use trigonometry to render a rotating element.
  var radius = 80;
  var rotatingArmAngle = percent * TWO_PI;
  var px = cx + radius * cos(rotatingArmAngle);
  var py = cy + radius * sin(rotatingArmAngle);
  fill(255);
  line(cx, cy, px, py);
  ellipse(px, py, 20, 20);

  //----------------------
  // Here, I use graphical transformations to render a rotated square. 
  push();
  translate(cx, cy);
  var rotatingSquareAngle = percent * TWO_PI * -0.25;
  rotate(rotatingSquareAngle);
  fill(255, 128);
  rect(-40, -40, 80, 80);
  pop();

  //----------------------
  // Here's a linearly-moving square
  var squareSize = 20;
  var topY = 0 - squareSize - 2;
  var botY = height + 2;
  var yPosition = map(percent, 0, 1, topY, botY);
  fill(255, 255, 255);
  rect(250, yPosition, 20, 20);

  //----------------------
  // Here's a pulsating ellipse
  var ellipsePulse = sin(3.0 * percent * TWO_PI);
  var ellipseW = map(ellipsePulse, -1, 1, 20, 50);
  var ellipseH = map(ellipsePulse, -1, 1, 50, 30);
  var ellipseColor = map(ellipsePulse, -1, 1, 128, 255);
  fill(255, ellipseColor, ellipseColor);
  ellipse(350, cy, ellipseW, ellipseH);

  //----------------------
  // Here's a travelling sine wave
  stroke(0, 0, 0);
  for (var sy = 0; sy <= height; sy += 4) {
    var t = map(sy, 0, height, 0.0, 0.25);
    var sx = 450 + 25.0 * sin((t + percent) * TWO_PI);
    ellipse(sx, sy, 1, 1);
  }

  //----------------------
  // Include some visual feedback. 
  fill(255, 0, 0);
  noStroke();
  textAlign(CENTER);
  var percentDisplayString = "" + nf(percent, 1, 3);
  text(percentDisplayString, cx, cy - 15);
}

Here is an animated GIF, and the Processing code template that produced it:

looping-500x200

// This is a template for creating a looping animation in Processing. 
// When you press a key, this program will export a series of images
// into an "output" directory located in its sketch folder. 
// These can then be combined into an animated gif. 
// Known to work with Processing 3.0.1
// Prof. Golan Levin, September 2016
 
//===================================================
// Global variables. 
 
int     nFramesInLoop = 120;
int     nElapsedFrames;
boolean bRecording; 
 
//===================================================
void setup() {
  size (500, 200); 
  bRecording = false;
  nElapsedFrames = 0;
}
//===================================================
void keyPressed() {
  bRecording = true;
  nElapsedFrames = 0;
}
 
//===================================================
void draw() {
 
  // Compute a percentage (0...1) representing where we are in the loop.
  float percentCompleteFraction = 0; 
  if (bRecording) {
    percentCompleteFraction = (float) nElapsedFrames / (float)nFramesInLoop;
  } else {
    percentCompleteFraction = (float) (frameCount % nFramesInLoop) / (float)nFramesInLoop;
  }
 
  // Render the design, based on that percentage. 
  renderMyDesign (percentCompleteFraction);
 
  // If we're recording the output, save the frame to a file. 
  if (bRecording) {
    saveFrame("output/mynickname-loop-" + nf(nElapsedFrames, 4) + ".png");
    nElapsedFrames++; 
    if (nElapsedFrames >= nFramesInLoop) {
      bRecording = false;
    }
  }
}
 
//===================================================
void renderMyDesign (float percent) {
 
  // This is an example of a function that renders a temporally looping design. 
  // It takes a "percent", between 0 and 1, indicating where we are in the loop. 
  // This example uses two different graphical techniques. 
  // Use or delete whatever you prefer from this example. 
  // Remember to SKETCH FIRST!
 
  //----------------------
  // here, I set the background and some other graphical properties
  background (180);
  smooth(); 
  stroke (0, 0, 0); 
  strokeWeight (2); 
 
  //----------------------
  // Here, I assign some handy variables. 
  float cx = 100;
  float cy = 100;
 
  //----------------------
  // Here, I use trigonometry to render a rotating element.
  float radius = 80; 
  float rotatingArmAngle = percent * TWO_PI; 
  float px = cx + radius*cos(rotatingArmAngle); 
  float py = cy + radius*sin(rotatingArmAngle); 
  fill    (255); 
  line    (cx, cy, px, py); 
  ellipse (px, py, 20, 20);
 
  //----------------------
  // Here, I use graphical transformations to render a rotated square. 
  pushMatrix(); 
  translate (cx, cy);
  float rotatingSquareAngle =  percent * TWO_PI * -0.25;
  rotate (rotatingSquareAngle); 
  fill (255, 128); 
  rect (-40, -40, 80, 80);
  popMatrix(); 
 
  //----------------------
  // Here's a linearly-moving square
  float squareSize = 20;
  float topY = 0 - squareSize - 2;
  float botY = height + 2;
  float yPosition = map(percent, 0, 1, topY, botY); 
  fill (255, 255, 255); 
  rect (250, yPosition, 20, 20); 
 
  //----------------------
  // Here's a pulsating ellipse
  float ellipsePulse = sin ( 3.0 * percent * TWO_PI); 
  float ellipseW = map(ellipsePulse, -1, 1, 20, 50); 
  float ellipseH = map(ellipsePulse, -1, 1, 50, 30); 
  float ellipseColor = map(ellipsePulse, -1, 1, 128, 255); 
  fill (255, ellipseColor, ellipseColor); 
  ellipse (350, cy, ellipseW, ellipseH); 
 
  //----------------------
  // Here's a traveling sine wave
  for (int sy=0; sy <= height; sy+=4) {
    float t = map (sy, 0, height, 0.0, 0.25); 
    float sx = 450 + 25.0 * sin ((t + percent)*TWO_PI); 
    point (sx, sy);
  }
 
  //----------------------
  // If we're recording, I include some visual feedback. 
  if (bRecording) {
    fill (255, 0, 0);
    textAlign (CENTER); 
    String percentDisplayString = nf(percent, 1, 3);
    text (percentDisplayString, cx, cy-15);
  }
}