A programming language is, after all, just another language. And a language can be spoken in many different ways, with a variety of accents or inflections. [...] But if a language isn’t capable of poetry, it has clearly lost its relevance on the human side of the equation. Matt Pearson
Processing
is a flexible software sketchbook and a language for learning how to code.
Since 2001, Processing has promoted software literacy within the visual arts and visual literacy within technology.
In a , students in a college-level introductory computing course taught with Processing said they would be twice as likely to take another computer science class as the students in a class with a more traditional curriculum.
Processing was started by Ben Fry and Casey Reas in 2001. At that time, Fry and Reas were both graduate students at the MIT Media Lab within John Maeda's Aesthetics and Computation research group. Processing grew directly out of Maeda's Design By Numbers project, developed at the Media Lab and released in 1999. The full Processing story is told by Fry and Reas in this Medium article: .
Notably, the Processing approach has also been applied to electronics through the and projects. Both projects (proudly) started at the Interaction Design Institute of Ivrea in Italy.
Coding example: Game of Life
The Game of Life is a cellular automaton developed by British mathematician John Conway in the late 1960s. Its purpose is to show how complex life-like behaviors can emerge from simple rules of interaction among many bodies.
The game takes place on an infinite grid of square boxes (cells) called the world according to the following rules:
each cell has 8 neighbors, which are the cells adjacent to it, including those in a diagonal direction
each cell can be in two states: alive or dead
initially, the states of cells are randomly chosen
the states of all cells at a given instant are used to calculate the state of the cells at the next instant. All cells in the world are updated simultaneously as they transition from one instant to the next
The state transition rules depend solely on the number of living neighbors:
a living cell with 2 or 3 living neighbors survives, otherwise it dies (due to isolation or overcrowding)
a dead cell with exactly 3 living neighbors is reborn
Cell[][] cells;
int cellSize = 10;
int numX, numY;
void setup() {
size(600, 600);
// fullScreen(); // goes full screen
frameRate(8); // reduce frame rate to 8 fps
numX = floor(width/cellSize);
numY = floor(height/cellSize);
startup();
}
void draw() {
background(0);
for (int x = 0; x < numX; x++) {
for (int y = 0; y < numY; y++) {
cells[x][y].compNextState();
}
}
for (int x = 0; x < numX; x++) {
for (int y = 0; y < numY; y++) {
cells[x][y].drawMe();
}
}
}
void startup() {
// create the cell grid
cells = new Cell[numX][numY];
for (int x = 0; x < numX; x++) {
for (int y = 0; y < numY; y++) {
cells[x][y] = new Cell(x, y);
}
}
// assign cells' neighbors
for (int x = 0; x < numX; x++) {
for (int y = 0; y < numY; y++) {
int above = y-1;
int below = y+1;
int left = x-1;
int right = x+1;
if (above < 0) above = numY-1;
if (below == numY) below = 0;
if (left < 0) left = numX-1;
if (right == numX) right = 0;
cells[x][y].addNeighbour(cells[left][above]);
cells[x][y].addNeighbour(cells[left][y]);
cells[x][y].addNeighbour(cells[left][below]);
cells[x][y].addNeighbour(cells[x][below]);
cells[x][y].addNeighbour(cells[right][below]);
cells[x][y].addNeighbour(cells[right][y]);
cells[x][y].addNeighbour(cells[right][above]);
cells[x][y].addNeighbour(cells[x][above]);
}
}
}
void mousePressed() {
startup();
}
class Cell {
float x, y;
boolean state;
boolean nextState;
Cell[] neighbours;
// create a random world
Cell(float _x, float _y) {
x = _x * cellSize;
y = _y * cellSize;
if (random(1) > 0.5) {
nextState = true;
} else {
nextState = false;
}
state = nextState;
neighbours = new Cell[0];
}
void addNeighbour(Cell cell) {
neighbours = (Cell[]) append(neighbours, cell);
}
void compNextState() {
// count live neighbors
int liveCount = 0;
for (int i=0; i < neighbours.length; i++) {
if (neighbours[i].state == true) {
liveCount++;
}
}
// a living cell with 2 or 3 living neighbors survives, otherwise it dies
if (state == true) {
if ((liveCount == 2) || (liveCount == 3)) {
nextState = true;
} else {
nextState = false;
}
// a dead cell with exactly 3 living neighbors is reborn
} else {
if (liveCount == 3) {
nextState = true;
} else {
nextState = false;
}
}
}
void drawMe() {
state = nextState;
noStroke();
if (state == true) {
fill(255); // white is alive
} else {
fill(0); // black is dead
}
rect(x, y, cellSize, cellSize);
}
}
Play - Tweak Game of Life
Create your personal version of GoL starting from the original code
Learn Processing
study some notable books:
p5.ps
ps.js is an interpretation of Processing for today’s web. Using the metaphor of a sketch, p5.js has a full set of drawing functionality. However, you’re not limited to your drawing canvas. You can think of your whole browser page as your sketch, including HTML5 objects for text, input, video, webcam, and sound.
Coding example: Game of Life
let cells; // use let to declare functions
let cellSize = 10;
let numX, numY;
function setup() {
createCanvas(600, 600); // use createCanvas instead of size
frameRate(8); // reduce frame rate to 8 fps
numX = floor(width / cellSize);
numY = floor(height / cellSize);
startup();
}
function draw() {
background(0);
for (let x = 0; x < numX; x++) {
for (let y = 0; y < numY; y++) {
cells[x][y].compNextState();
}
}
for (let x = 0; x < numX; x++) {
for (let y = 0; y < numY; y++) {
cells[x][y].drawMe();
}
}
}
function startup() {
// create the cell grid
cells = new Array(numX); // matrices are arrays of arrays
for (let x = 0; x < numX; x++) {
cells[x] = new Array(numY);
for (let y = 0; y < numY; y++) {
cells[x][y] = new Cell(x, y);
}
}
// assign cells' neighbors
for (let x = 0; x < numX; x++) {
for (let y = 0; y < numY; y++) {
let above = y - 1;
let below = y + 1;
let left = x - 1;
let right = x + 1;
if (above < 0) above = numY - 1;
if (below == numY) below = 0;
if (left < 0) left = numX - 1;
if (right == numX) right = 0;
cells[x][y].addNeighbour(cells[left][above]);
cells[x][y].addNeighbour(cells[left][y]);
cells[x][y].addNeighbour(cells[left][below]);
cells[x][y].addNeighbour(cells[x][below]);
cells[x][y].addNeighbour(cells[right][below]);
cells[x][y].addNeighbour(cells[right][y]);
cells[x][y].addNeighbour(cells[right][above]);
cells[x][y].addNeighbour(cells[x][above]);
}
}
}
function mousePressed() {
startup();
}
class Cell {
constructor(_x, _y) { //use constructor() to define the class constructor
this.x = _x * cellSize; // use this to self-referencing the object
this.y = _y * cellSize;
this.nextState = random(1) > 0.5;
this.state = this.nextState;
this.neighbours = []; // empty array
}
addNeighbour(cell) {
this.neighbours.push(cell); // add a new cell with push()
}
compNextState() {
let liveCount = 0;
for (let i = 0; i < this.neighbours.length; i++) {
if (this.neighbours[i].state) {
liveCount++;
}
}
if (this.state) {
this.nextState = liveCount == 2 || liveCount == 3;
} else {
this.nextState = liveCount == 3;
}
}
drawMe() {
this.state = this.nextState;
noStroke();
if (this.state) {
fill(255); // white is alive
} else {
fill(0); // black is dead
}
rect(this.x, this.y, cellSize, cellSize);
}
}
Learn p5.js
study some notable books:
Play - Tweak Game of Life
R
Coding example
library(ggplot2) # import library for plots
library(magrittr) # import library for pipes
seq(from=-10, to=10, by = 0.05) %>% # create a sequence from -10 to 10 with step 0.05
expand.grid(x=., y=.) %>% # expand the sequence into a grid
ggplot(aes(x = (x + sin(y)^2), y = (y + sin(x)))) + # alter the grid using some math
geom_point(alpha=.1, shape=20, size=1, color="black") + # plot the grid as a scatterplot
theme_void() # set the void theme for the plot
Play - Tweak in R
Tweak the above R code altering the math functions and see what's the outcome.
Learn R (for generative art)
Play - Make art with R
pick one function in aRtsy
investigate how it works
read the corresponding R code on GitHub
generate some art with it
post it on Telegram
Play - Draw a portrait with R
generate a portrait of someone you love
send it to your lover!
read tutorials, examples, and documentation on Processing
read, fork and create your sketches on
(Second Edition) by Casey Reas and Ben Fry
by Daniel Shiffman
by Hartmut Bohnacker, Benedikt Gross, Julia Laub, and Claudius Lazzeroni
is a JavaScript library for creative coding, with a focus on making coding accessible and inclusive for artists, designers, educators, beginners, and anyone else.
read tutorials, examples, and documentation on p5.js
read, fork and create your sketches on
by Lauren McCarthy, Casey Reas, and Ben Fry
by Hartmut Bohnacker, Benedikt Gross, Julia Laub, and Claudius Lazzeroni
If your Processing tweaks were interesting, implement them in p5.js. Then fork the GoL on OpenProcessing and post your own version in p5.js.
is a free software environment for statistical computing and graphics. R was not born to create art. However, it has been recently (ab)used in this sense, proving that even statistics is capable of poetry!
Typically, an artwork in R is generated as a plot - often a scatterplot - using library, which is a system for declaratively creating graphics: you provide the data, tell ggplot2 how to map variables to aesthetics, what graphical primitives to use, and it takes care of the details.
read the Travelling Salesman Portrait by Fronkonstin