Project – 11

I chose to do my project in this minimalist style because I thought it was really cute and reminded me of 8-bit video games (minus all the triangles.) My focus was on the smoothness and cleanliness of the moving image by coordinating objects together.

sketch
var count = 0;

var divwidth = 16;
var divider1;
var divider2;

var bench1;
var bench2;
var bench3;

var people = [];   //holds the people
var mountains = [];  //holds the mountains :)
var trees = [];   //holds the trees 😊

var trainbasecolor = 150;

var windowTop = 30;  //just helper variables for the window dimensions
var windowBottom = 150;


function setup() {
    createCanvas(480, 250);

    for (var i = 0; i < width/15+10; i++){
        mountains[i] = makeMountain(i*15);
    }
    bench1 = makeBench(158);
    bench2 = makeBench(458);
    bench3 = makeBench(-142);
    
    for (var i = 0; i < 6; i++){  //start off w some people
        if (random(0, 30)<13){
				people.push(makePerson(bench1.x-108.5 + i*43.1));
			}
    }
    for (var i = 0; i < 6; i++){  //start off w some people
        if (random(0, 30)<13){
				people.push(makePerson(bench2.x-108.5 + i*43.1));
			}
    }
    for (var i = 0; i < 6; i++){  //start off w some people
        if (random(0, 30)<13){
				people.push(makePerson(bench3.x-108.5 + i*43.1));
			}
    }
    
    divider1 = makeDivider(300);
    divider2 = makeDivider(0);

    
    
    

    
    frameRate(24);



}


function draw() {

	background(150, 180, 255);
	
	noStroke();  
	for(i=0; i<mountains.length; i++){ //draw mountains
		mountains[i].drawit();
	}
	for(i=0; i<trees.length; i++){ //draw trees
		trees[i].drawit();
	}

	fill(trainbasecolor);
	rect(0, windowBottom, width, 125);  //trainbase
	rect(0, 0, width, windowTop);
	fill(120);
	rect(0, height-20, width, 20);

	divider1.drawit();
	divider2.drawit();

	bench1.drawit();
	bench2.drawit();
	bench3.drawit();


	for(i=0; i<people.length; i++){ //draw people
		people[i].drawit();
	}
	




	divider1.stepit();
	divider2.stepit();

	bench1.stepit();
	bench2.stepit();
	bench3.stepit();

	for(i=0; i<people.length; i++){
		people[i].stepit();
	}
	for(i=0; i<mountains.length; i++){
		mountains[i].stepit();
	}
	for(i=0; i<trees.length; i++){
		trees[i].stepit();
	}

	removePeopleThatHaveSlippedOutOfView();
	removeMountainsThatHaveSlippedOutOfView();

	if(count % 15 == 0){       //make mountain objects
		//if(random(0,10)<3){

			mountains.push(makeMountain(680));
			
		//}
	}
	if(count % 30 == 0){      //make tree objects
		if(random(0,10)<6){

			trees.push(makeTree(600));
			
		}
	}




	count ++;
	print(people.length.toString());
}

//FUNCTIONS FOR TREE OBJECTS
function makeTree(tx){
	
	var treeTopWidth = random(100, 150);
	var treeTopHeight = random(50, 100)
	var treeHeight = random(70, 250);
	var trunkWidth = random(10, 50);
	

	var tree = {x: tx, y: 150, c: color(random(25, 75), random(125,175), random(25, 75)), topw: treeTopWidth, trunkw: trunkWidth, toph: treeTopHeight, trunkh: treeHeight, drawit: treeDraw, stepit: treeStep};

	return tree;

}

function treeDraw(){
	fill(150, 100, 50);
	rectMode(CENTER);
	rect(this.x, this.y, this.trunkw, this.trunkh);

	fill(this.c);
	ellipse(this.x, this.y-this.trunkh/2, this.topw, this.toph);
	rectMode(CORNER);

	
}

function treeStep(){
	this.x -= 8;
}

function removeMountainsThatHaveSlippedOutOfView(){

    var treesToKeep = [];
    for (var i = 0; i < trees.length; i++){
        if (trees[i].x > -200) {
            treesToKeep.push(trees[i]);
        }
    }
    mountains = mountainsToKeep; // remember the surviving buildings
}
//FUNCTIONS FOR MOUNTAIN OBJECTS
function makeMountain(mx){
	
	var mountainWidth = random(50, 200);
	var mountainHeight = random(50, 125);
	

	var mountain = {x: mx, y: mountainHeight, w: mountainWidth, c: color(random(80, 120), random(225, 255), random(80, 120)), drawit: mountainDraw, stepit: mountainStep};

	return mountain;

}

function mountainDraw(){
	fill(this.c);
	
	triangle(this.x, this.y, this.x-this.w, 250, this.x+this.w, 250);
	
}

function mountainStep(){
	this.x -= 2;
}

function removeMountainsThatHaveSlippedOutOfView(){

    var mountainsToKeep = [];
    for (var i = 0; i < mountains.length; i++){
        if (mountains[i].x > -200) {
            mountainsToKeep.push(mountains[i]);
        }
    }
    mountains = mountainsToKeep; // remember the surviving buildings
}


//FUNCTIONS FOR WINDOW DIVIDER OBJECTS
function makeDivider(wx) { 
    var divider = {x: wx, y: windowTop,
                  drawit: dividerDraw, stepit: dividerStep};

    return divider;
}

function dividerDraw(){
	fill(trainbasecolor);
	rect(this.x, this.y, divwidth, 150);
}

function dividerStep(){
	this.x++;
	
	if(this.x == 600-divwidth){
		this.x = (0-divwidth);
		
	}

	

}
//FUNCTIONS FOR PEOPLE OBJECTS
function makePerson(px){
	
	var personWidth = random(15, 35);
	var personHeight = random(25, 60);
	var headSize = random(8, 20);

	var person = {x: px, y: 196-personHeight/2, w: personWidth, h: personHeight, hs: headSize, c: random(0, 50), drawit: personDraw, stepit: personStep};

	return person;

}

function personDraw(){
	fill(this.c);
	rectMode(CENTER);
	rect(this.x, this.y, this.w, this.h);
	rect(this.x-this.w/4, 212, 5, 36);
	rect(this.x+this.w/4, 212, 5, 36);
	rect(this.x, this.y-this.h/2-this.hs/2+1, this.hs, this.hs);
	rectMode(CORNER);
	
}

function personStep(){
	this.x++;
}

function removePeopleThatHaveSlippedOutOfView(){

    var peopleToKeep = [];
    for (var i = 0; i < people.length; i++){
        if (people[i].x < 600) {
            peopleToKeep.push(people[i]);
        }
    }
    people = peopleToKeep; // remember the surviving buildings
}

//FUNCTIONS FOR BENCH OBJECTS
function makeBench(bx){
	var bench = {x: bx, y: 170+divwidth, drawit: benchDraw, stepit: benchStep};
	return bench;

	
}



function benchDraw(){
	rectMode(CENTER);
	fill(220);

	rect(this.x, this.y, 266, 50);
	
	for(i=0; i<6; i++){
		fill(225, 0, 0);
		rect(this.x-108 + i*43.1, this.y, 38, 40);
		fill(155, 0, 0);
		rect(this.x-108 + i*43.1, this.y+15, 38, 10);
		
	}
	rectMode(CORNER);

}

function benchStep(){
	this.x++;
	if(this.x == 750){
		this.x = -150;
		for(i=0; i<6; i++){
			if (random(0, 30)<13){
				people.push(makePerson(this.x-108.5 + i*43.1));
			}
		
		}
	}

}

Project 11: Deep Sea

For the project this week, I wanted to create a scene that depicts marine life, with fish seaweed and bubbles blown by the wish.

The objects in this scene are of three types:

  1. Stable – pebbles, seabed
  2. Movement – seaweed, which moves between constraints for the effect of swaying in water
  3. Motion – the fish and the bubbles.

I planned the scene in a sketch and then, using the starter code, tried to explore different ways of making the scene dynamic.

For the fish, I first, used the constructor, to make the shape of the fish and then used transparency to create an element of uniqueness in each new fish that is born on the canvas. This also enhances the effect of transparency scales and that eveything under water is bobbing and swaying.

For the motion of the seaweed, I used the random() function so that the height of the rectangle moves between two constraints, this giving the movement effect.

Please view the full code and visual preview here:

https://editor.p5js.org/ssahasra/full/R7Sh-om9z

LO-11 : Tega Brain

Keeping Time: a time visualisation with photos

Of all the women practitioners I have come across in the field of interaction design and computation, I find Tega Brain’s voice to be one of the most unique. Tega Brain uses computation and combines it with environmental interpretation of computers and her work forms bridges between computation and design as it occurs in nature. She creates computation systems/projects that respond to natural phenomena and vice versa. 

Tega Brain is an Australian-born computational designer/artist. She has a background in environmental engineering. She is a professor of New Media at NYU and is associated with Processing.org – a language similar to p5.js for visual computation.

The project I found the most interesting, especially because we recently learnt about images in p5.js is called “Keeping Time”. As described on her website – “Keeping Time portrays a complex biological system living through the Anthropocene. The series is made by scraping the Flickr database for images of particular plant species and laying the results out according to their time stamp. Photographs for each year are arranged in rows and are ordered across each row according to date.”

She uses transparency of images and their density in a given area of pixels to visualise time and the age of species. I admire that she uses images to visualise data and this project speaks to her larger body of work where she combines design with environmental phenomena.

LO 11 – A Focus on Women Practitioners

Madeline Gannon is a designer of interactive tools for digital fabrication at Madlab. The project I am highlighting is called Tactum, which is an augmented modeling tool that is used to design 3D printed wearables. This tool uses depth-sensing and projection mapping to sense different inputs and in turn, project touch gestures on the user’s skin. This is a very ingenious method of rapid prototyping that allows anybody to design a 3D printed wearable, and see real-time feedback throughout the process. It is very interesting to see the limitations of a program with a finite amount of possible creations (due to the given size and number of bands). I would really like to explore this tool and discover new methods of interaction and how they would produce different outcomes.

http://www.madlab.cc/tactum

Project 11 – Generative Landscape

My project is a simple landscape with hills, trees, buildings, birds, and the sun. The trees vary in size and location, the building varies in width, and the birds vary in location and speed.

Maggie – Generative Landscape
//Maggie Ma
//Section D
//Generative Landscape

var buildings = [];
var hills = [];
var noiseParam = 0;
var noiseStep = 0.02;
var trees = [];
var birds = [];


function setup() {
    createCanvas(400, 500); 
    strokeWeight(4);
    
    // create an initial collection of buildings
    for (var i = 0; i < 2; i++){
        var rx = random(width);
        buildings[i] = makeBuilding(rx);
    }
    //create an initial collection of birds
    for (var i = 0; i < 3; i++){
        var rx = random(width);
        birds[i] = makeBird(rx);
    }

    // drawing hills in the back
    for (var i = 0; i<width/5 +1; i++) {
    	var n = noise(noiseParam);
    	var value = map(n,0,1,0,height+50);
    	hills.push(value);
    	noiseParam+=noiseStep;
    }
    frameRate(15);
}


function draw() {
    background(255,203,186); //light pink

    //sun
    fill(253,165,0); //yellow
    circle(width/2, height/2-70, 120.438 );

    //birds
    updateandDisplayBird();
    removeBirdThatHaveSlippedOutOfView();
    addNewBirdWithSomeRandomProbability();	

    //hills
    drawHills();
    displayHorizon();

    //building
    updateAndDisplayBuilding();
    removeBuildingsThatHaveSlippedOutOfView();
    addNewBuildingsWithSomeRandomProbability(); 

   //trees
    updateAndDisplayTrees();
    removeTreesThatHaveSlippedOutOfView();
    addNewTreesWithSomeRandomProbability(); 
}

function drawHills() {
	hills.shift();
    var n = noise(noiseParam);
    var value = map(n,0,1,0,height+50);
    hills.push(value);
    noiseParam += noiseStep;

    beginShape();
    vertex(0,height);
    for(var i =0; i <= width/5; i++) {
    	fill(255,163,130); //pink color
    	strokeWeight(4);
    	vertex((i*5),hills[i]);
    
    }
    vertex(width,height);
    endShape();
}

//creating trees
function makeTree(birthLocationX) {
    var t = {x: birthLocationX,
                breadth: round(random(10,30)),
                speed: -5.0,
                y: random(10, 40), //randomize tree size and location
                w: random(30, 40),
                h: random(40, 60),
                move: treeMove,
                display: treeDisplay}
    return t;
}

function treeMove() {
    this.x += this.speed;
}

function treeDisplay() {
    push();
    translate(this.x, height -125);
    strokeWeight(4); 
    fill(80,202,119);
    //leaves
  	ellipse(this.x,this.y, this.w, this.h);
  	//trunk
  	line(this.x, this.y+10, this.x, this.y+70);
    pop();
}

function updateAndDisplayTrees(){
    for (var i = 0; i < trees.length; i++){
        trees[i].move();
        trees[i].display();
    }
}

function removeTreesThatHaveSlippedOutOfView(){
    var treesToKeep = [];
    for (var i = 0; i < trees.length; i++){
        if (trees[i].x + trees[i].breadth > 0) {
            treesToKeep.push(trees[i]);
        }
    }
    trees = treesToKeep;
}
function addNewTreesWithSomeRandomProbability() {
    var newTreeLikelihood = 0.07; 
    if (random(0,1) < newTreeLikelihood) {
        trees.push(makeTree(width));
    }
}

//creating building
function makeBuilding(birthLocationX) {
    var bldg = {x: birthLocationX,
                breadth: 70,
                speed: -8.0,
                w: random(70,110), //randomize width
                move: buildingMove,
                display: buildingDisplay}
    return bldg;
}

function buildingMove() {
    this.x += this.speed;
}

function buildingDisplay() {
	push();
    strokeWeight(4); 
    fill(253,165,0); //yellow block on right side
  	rect(this.x ,315.478 ,this.w ,137.574);
  
  	rect(this.x - 55.901, 364.514 ,15.016 ,88.538); //yellow pillars
  	rect(this.x +7.51, 364.514 ,15.016 ,88.538);
  	rect(this.x-28.083,180.775,23.237,26.131); //yellow top
  	fill(255,255,255);
  	rect(this.x-33.153,206.996,33.377,33.377); //middle section
  	fill(253,165,0);
  	rect(this.x-21.845,219.566,10.762,20.807);
  	fill(255,255,255);
  	rect(this.x-40.661, 240.463,48.108 ,212.59 ); //bottom base
  	fill(0,195,227);
  	rect(this.x-40.661,259.105,15.016 ,25.094); //turquoise designs
  	rect(this.x-40.661,302.931,15.016 ,25.094);
  	rect(this.x-7.508,259.105,15.016 ,25.094 );
  	rect(this.x-7.508, 302.931,15.016 ,25.094);
  	fill(225,43,0);
  	rect(this.x-40.885,346.758,15.016,106.295); //red designs
  	rect(this.x-7.508,346.758,15.016,106.295);
  	line(this.x-25.869,240.8 ,this.x-25.869,453.053);
  	line(this.x-7.508,240.8 ,this.x-7.508,453.053);

    pop();
}

function updateAndDisplayBuilding(){
    for (var i = 0; i < buildings.length; i++){
        buildings[i].move();
        buildings[i].display();
    }
}

function removeBuildingsThatHaveSlippedOutOfView(){
    var buildingToKeep = [];
    for (var i = 0; i < buildings.length; i++){
        if (buildings[i].x + buildings[i].breadth > 0) {
            buildingToKeep.push(buildings[i]);
        }
    }
    buildings = buildingToKeep;
}
function addNewBuildingsWithSomeRandomProbability() {
    var newBuildingLikelihood = 0.015; 
    if (random(0,1) < newBuildingLikelihood) {
        buildings.push(makeBuilding(width));
    }
}

//creating birds
function updateandDisplayBird(){
    for (var i = 0; i < birds.length; i ++){
        birds[i].move();
        birds[i].display();
    }
}

function removeBirdThatHaveSlippedOutOfView(){
    var keepBirds=[];
    for (var i = 0; i < birds.length; i++) {
        if (birds[i].x < width) {
            keepBirds.push(birds[i]);
        }
    }
    birds = keepBirds;
}

function addNewBirdWithSomeRandomProbability(){
    var newBirdLikelihood = 0.01; 
    if (random(0,1) < newBirdLikelihood) {
        birds.push(makeBird(15, 15));
    }
}

function Birdmove(){
    this.x += this.speed;
}

function birdDisplay(){
    fill(0);
    stroke(0);
    push();
    translate(this.x, this.y);
    //wings
    triangle(0, 0, 3, 0, -2, -3);
    triangle(0, 0, 3, 0, 2, 3);
    pop();
}

function makeBird(birthLocationX, birthLocationY){
    var bird = {x: birthLocationX,
                y:random(100,200),
                speed:random(2, 9),
                move: Birdmove,
                display: birdDisplay};
    return bird;
}
//creating grass horizon line
function displayHorizon(){
    fill(106,207,124);
    stroke(4);
    rect(0, height-50, width, height-50);
}

Project 11: Landscape

sketchDownload
var waveDetail = 0.003; // detail in shallow wave
var waveSpeed = 0.0002; // speed of waves
var waveDetail2 = 0.002; //detail of mid wave
var waveDetail3 = 0.001; //detail of deep wave
var seaGround = []
var sunset;

function preload() {
    sunset = loadImage("https://i.imgur.com/14AlgbU.png");
    seaweed = loadImage("https://i.imgur.com/JHftB8t.png");
    fish = loadImage("https://i.imgur.com/BFimCOm.png")
}
function setup() {
    createCanvas(600, 400);
    for (var i = 0; i < 5; i ++){
        var rx = random(width);
        var ry = random(10, 50)
        seaGround[i] = makeSeaweed(rx, ry);
    }
    frameRate(15);
}

function draw() {
    background(153, 153, 204);

    image(sunset, 0, 0, 600, 400);
    makeWaves();
    updateSeaweed();
    removeSeaweed();
    image(fish, 300, 200, 300, 200);  
    addSeaweed();

}

function makeWaves() {
    fill(95, 191, 254);
    noStroke();
    beginShape();
    vertex(0, height);
    for (var x = 0; x < width; x++) {
        var t = (x * waveDetail) + (millis() * waveSpeed);
        var y = map(noise(t), 0, 1, height / 8 * 2, height / 8 * 4);
        vertex(x, y);
    }
    vertex(width, height);
    endShape();

    //second wave
    beginShape();
    fill(41, 160, 255);
    vertex(0, height);
    for (var x = 0; x < width; x++) {
        var t2 = (x * waveDetail2) + (millis() * waveSpeed);
        var y = map(noise(t2), 0, 1, 100, 300);
        vertex(x, y);
    }
    vertex(width, height);
    endShape();

    //third wave
    beginShape();
    fill(19, 138, 233);
    vertex(0, height);
    for (var x = 0; x < width; x++) {
        var t3 = (x * waveDetail3) + (millis() * waveSpeed);
        var y = map(noise(t3), 0, 1, 300, height);
        vertex(x, y);
    }
    vertex(width, height);
    endShape();
}

function updateSeaweed(){
    for (var i = 0; i < seaGround.length; i ++){
        seaGround[i].move();
        seaGround[i].display();
    }
}

function removeSeaweed(){
    var keepSeaweed=[];
    for (var i = 0; i < seaGround.length; i++) {
        if (seaGround[i].x < 600) {
            keepSeaweed.push(seaGround[i]);
        }
    }
}

function addSeaweed(){
    //little probability
    var newSeaweedLikelihood = 0.02; 
    if (random(0,1) < newSeaweedLikelihood) {
        seaGround.push(makeSeaweed(15, 15));
    }
}

function moveSeaweed(){
    this.x += this.speed;
}

function displaySeaweed(){
    fill(0);
    stroke(0);
    push();
    translate(this.x, height-300);
    image(seaweed, 0, 0, 400, 320);
    pop();

}

function makeSeaweed(birthLocationX, birthLocationY){
    var seaweeds = {x: birthLocationX,
                y:birthLocationY,
                speed:random(3, 7),
                move: moveSeaweed,
                display: displaySeaweed};
    return seaweeds;
}

I wanted to illustrate a fish swimming in the ocean, as the ocean waves and seaweed passed by. I was inspired by the sunset, and I started to think about how i can make the sunset a moving landscape. I drew the sunset, seaweed, and fish objects on Procreate.

No description available.
sunset that i drew that was the source of inspiration
No description available.
rough sketch
No description available.
final sketch

Project 11: Generative Landscape

For this week’s project, I decided to visualize an NYC subway line I used often (pre-pandemic) and the views of the skyline you can see passing by when the subway tracks are outdoors. I first roughly sketched out the scene on paper and then used Professor Cortina’s sample code as a baseline and customized it further to meet my vision. I displayed the scene to be at night since that’s the time of day I liked most when watching the skyline. Also, although nighttime, the lights would always be on in the buildings, so I decided to have lit up windows on all the buildings as well as the light reflections.

sketch
var frontBuildings = [];
var backBuildings = [];
var moonAndStars;

function preload(){
  moonAndStars = loadImage("https://i.imgur.com/0JJlsGR.png");
}

function setup() {
  createCanvas(480, 270);
  // make initial array of buildings
  for(var i = 0; i < 20; i++) {
    var x = random(width);
    backBuildings[i] = makeBackBuilding(x);
  }
  for(var i = 0; i < 10; i++) {
    var x = random(width);
    frontBuildings[i] = makeFrontBuilding(x);
  }
  frameRate(50);
}

function draw() {
  // gradient night background
  setGradient(color("#655BCE"), color("#1A1449"));
  // moon
  image(moonAndStars, 0, 0, 480, 350);

  updateAndDisplayBuildings();
  removeBuildingsThatHaveSlippedOutOfView();
  addNewBuildingsWithSomeRandomProbability(); 
  // tracks
  drawTrack();
  // train
  drawTrain();

}

function drawTrain() {
  strokeWeight(1);
  stroke("#4A4954");
  // train body
  fill("#65656D");
  rect(0, 180, 220, 80);
  strokeWeight(5);
  line(0, 240, 218, 240);
  strokeWeight(2);
  line(0, 245, 218, 245);
  strokeWeight(5);
  line(0, 190, 218, 190);
  strokeWeight(2);
  line(0, 196, 218, 195);
  noStroke();
  // doors
  fill("#5D5C66");
  rect(10, 200, 36, 60);
  rect(130, 200, 36, 60);
  // windows
  fill("#383664");
  rect(12, 202, 32, 30);
  rect(132, 202, 32, 30);
  rect(58, 200, 60, 30);
  rect(200, 200, 20, 40);
  // train number
  fill("purple");
  circle(182, 220, 25);
  fill(255);
  textSize(20);
  text("7", 177, 227);
}

function drawTrack() {
  fill(20);
  rect(0, 220, width, 100);
  fill("#8F8F91");
  rect(0, 220, width, 30);
  fill("#F0D933");
  rect(0, 240, width, 5);
}

function removeBuildingsThatHaveSlippedOutOfView(){
  // If a building has dropped off the left edge,
  // remove it from the array.  This is quite tricky, but
  // we've seen something like this before with particles.
  // The easy part is scanning the array to find buildings
  // to remove. The tricky part is if we remove them
  // immediately, we'll alter the array, and our plan to
  // step through each item in the array might not work.
  //     Our solution is to just copy all the buildings
  // we want to keep into a new array.
  var frontBuildingsToKeep = [];
  var backBuildingsToKeep = [];
  for (var i = 0; i < frontBuildings.length; i++){
      if (frontBuildings[i].x + frontBuildings[i].width > 0) {
          frontBuildingsToKeep.push(frontBuildings[i]);
      }
  }
  for (var i = 0; i < backBuildings.length; i++){
      if (backBuildings[i].x + backBuildings[i].width > 0) {
          backBuildingsToKeep.push(backBuildings[i]);
      }
  }
  frontBuildings = frontBuildingsToKeep; // remember the surviving buildings
  backBuildings = backBuildingsToKeep;
}


function addNewBuildingsWithSomeRandomProbability() {
  // With a very tiny probability, add a new building to the end.
  var newBuildingLikelihood = 0.08; 
  if (random(0,1) < newBuildingLikelihood) {
      backBuildings.push(makeBackBuilding(width));
      frontBuildings.push(makeFrontBuilding(width));
  }
}

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

// method to update position of building every frame
function frontBuildingMove() {
    this.x += this.speed;
}
    
// draw the building and some windows
function frontBuildingDisplay() {
  noStroke();
  // building
  fill(this.color);
  var y = 220 - this.height;
  rect(this.x, y, this.width, this.height);
  // windows
  fill("#FFE9AD");
  for(var i = 0; i < 5; i ++) {
    rect(this.x + 5, y + 10 + 15*i, this.width/6, 8);
    rect(this.x + 20, y + 10 + 15*i, this.width/6, 8);
    rect(this.x + 35, y + 10 + 15*i, this.width/6, 8);
  }
}

function makeFrontBuilding(xlocation) {
  var building = {x: xlocation, 
                  width: random(40, 50), 
                  height: random(80, 120),
                  color: color(random(20, 70), random(20, 70), 130),
                  speed: -3,
                  move: frontBuildingMove, 
                  display: frontBuildingDisplay}
  return building;
}


// method to update position of building every frame
function backBuildingMove() {
  this.x += this.speed;
}
    
// draw the back building and some windows
function backBuildingDisplay() {
  noStroke();
  var y = 220 - this.height;
  // light reflections
  fill(255, 243, 180, 20);
  ellipse(this.x + this.width/2, y + 20, this.width*2);
  // building
  fill(this.color);
  rect(this.x, y, this.width, this.height);
  // windows
  fill("#FFE9AD");
  for(var i = 0; i < 8; i ++) {
    rect(this.x + 5, y + 10 + 15*i, this.width/6, 8);
    rect(this.x + 20, y + 10 + 15*i, this.width/6, 8);
    rect(this.x + 35, y + 10 + 15*i, this.width/6, 8);
  }
}

function makeBackBuilding(xlocation) {
  var building = {x: xlocation, 
                  width: random(40, 50), 
                  height: random(130, 160),
                  color: color(random(60, 80), random(60, 80), 180),
                  speed: -3,
                  move: backBuildingMove, 
                  display: backBuildingDisplay}
  return building;
}

// code from https://editor.p5js.org/REAS/sketches/S1TNUPzim
function setGradient(c1, c2) {
  noFill();
  for (var y = 0; y < height; y++) {
    var inter = map(y, 0, height, 0, 1);
    var c = lerpColor(c1, c2, inter);
    stroke(c);
    line(0, y, width, y);
  }
}



Beach Landscape

When I saw the prompt for the project this week, I immediately thought of doing something with a noise function. I felt as though mountains wouldn’t allow for enough variability, so I decided to do a beach. I laid out the very basic sand, water, and sky, and then added embellishing elements to try to create a drive by beach scene.

beach
var boats = [];     //arrays to hold respective objects
var clouds = [];
var umbrellas = [];
var planes = []; 
var buildings = [];
var railings = [];
var people = [];
var towels = [];
var landscape = [];     //array that creates slope of shoreline
var noiseParam = 0;     
var noiseStep = 0.005;      //defines extremity of shoreline slope


function setup() {
    createCanvas(480,300); 
    
    for (var i = 0; i < 3; i++){        //make a certain amount of (object) to start out, at random locations within a constraint
        var rx = random(width);
        var ry = random(80,150)
            boats[i] = makeBoat(rx,ry);
    }

    for (var i = 0; i < 3; i++){
        var Cx = random(width);
        var Cy = random(0,60)
            clouds[i] = makeCloud(Cx,Cy);
    }

    for (var i = 0; i < people.length; i++){
        var Tx = random(width);
        var Ty = random(250,300)
            towels[i] = makeTowel(Tx,Ty);
    }
    for (var i = 0; i < people.length; i++){
        var Px = random(width);
        var Py = random(250,300)
            people[i] = makePerson(Px,Py);
    }

    for (var i = 0; i < 5; i++){
        var Ux = random(width);
        var Uy = random(250,300)
            umbrellas[i] = makeUmbrella(Ux,Uy);
    }
    
    for (var i = 0; i < 15; i++){
        var Bx = random(width);
            buildings[i] = makeBuilding(Bx);
    }

    for (var i = 0; i < 0.9; i++){
        var Px = random(width);
        var Py = random(0,20)
            planes[i] = makePlane(Px,Py);
   }
    

    for(var i=0;i<=width/5;i++){    
        var n= noise(noiseParam);       //picks value 0-1
        var value = map(n,0,1,50,height);        //scales it to the canvas size

            landscape.push(value);      //adds to array
            noiseParam+=noiseStep;      //moves to the right for the next point in the array
   }
    
    frameRate(5);
}



function draw() {
    background(3,220,245);

    fill(13,66,212,230);    //dark blue
        rect(0,height/4,width,height);      //body of water   
    fill(227,232,164,175);  //pale beige
        rect(0,height/4-7,width,7);    //distant shoreline

                    //call the functions to spawn and despawn respective obejcts
    removeBoat();         
    newBoat(); 

    removeCloud();
    newCloud();

    removeUmbrella();

    removePlane();
    newPlane();

    removeBuilding();
    newBuilding();

    removeRailing();
    newRailing();

    removePerson();

    removeTowel();
  
   
                                                //call the move and show functions to continually draw and redraw objects after updated coordinates
    for (var i = 0; i < clouds.length; i++){
        clouds[i].move();
        clouds[i].show();
    }

    for (var i = 0; i < buildings.length; i++){
        buildings[i].move();
        buildings[i].show();
     }

    for (var i = 0; i < boats.length; i++){
        boats[i].move();
        boats[i].show();
    }
   

    displayHorizon();

     for (var i = 0; i < towels.length; i++){
        towels[i].move();
        towels[i].show();
    }

    for (var i = 0; i < people.length; i++){
        people[i].move();
        people[i].show();
    }

    for (var i = 0; i < umbrellas.length; i++){
        umbrellas[i].move();
        umbrellas[i].show();
    }


    for (var i = 0; i < planes.length; i++){
       planes[i].move();
       planes[i].show();
     }

    fill(159,159,159);
        rect(0,height-50,width,40);
    fill(110,110,110);
        rect(0,height-45,width,30);


    for (var i = 0; i < railings.length; i++){
       railings[i].move();
       railings[i].show();
     }    
}

                        //functions to remove an object from a displayed array once "out of sight"
function removeBoat(){
    
    var boatsToKeep = [];    //the boats that should still be displayed
    for (var i = 0; i < boats.length; i++){
        if (boats[i].x + boats[i].breadth > 0) {    //if the boat is closer than it's width to the edge
            boatsToKeep.push(boats[i]);     //add this boat to the boats that will be displayed
        }
    }
    boats = boatsToKeep; // only display the baots currently being kept
}

function removeCloud(){
    var cloudsToKeep = [];
    for (var i = 0; i < clouds.length; i++){
        if (clouds[i].x + clouds[i].breadth > 0) {
           cloudsToKeep.push(clouds[i]);
        }
   }
    clouds = cloudsToKeep; 
}

function removeUmbrella(){
    var umbrellasToKeep = [];
    for (var i = 0; i < umbrellas.length; i++){
        if (umbrellas[i].x + umbrellas[i].breadth > 0) {
           umbrellasToKeep.push(umbrellas[i]);
        }
    }
    umbrellas = umbrellasToKeep; 
}

function removePlane(){
    var planesToKeep = [];
    for (var i = 0; i < planes.length; i++){
        if (planes[i].x + 150 > 0) {
           planesToKeep.push(planes[i]);
        }
   }
    planes = planesToKeep; 
}

function removeBuilding(){
    var buildingsToKeep = [];
        for (var i = 0; i < buildings.length; i++){
            if (buildings[i].x > 0) {
                buildingsToKeep.push(buildings[i]);
        }
   }
    buildings = buildingsToKeep; 
}

function removeRailing(){
    var railingsToKeep = [];
        for (var i = 0; i < railings.length; i++){
            if (railings[i].x > 0) {
                railingsToKeep.push(railings[i]);
        }
   }
    railings = railingsToKeep; 
}

function removePerson(){
    var peopleToKeep = [];
        for (var i = 0; i < people.length; i++){
            if (people[i].x > 0) {
               peopleToKeep.push(people[i]);
        }
   }
    people = peopleToKeep; 
}

function removeTowel(){
    var towelsToKeep = [];
        for (var i = 0; i < towels.length; i++){
            if (towels[i].x > 0) {
               towelsToKeep.push(towels[i]);
        }
   }
    towels = towelsToKeep; 
}

                    //functions to create new objects that come into sight

function newBoat() {

    var newBoatChance = 0.009;      //the chance that a new boat will appear
    if (random(0,1) < newBoatChance) {      //activate probability
        boats.push(makeBoat(width,random(100,150)));        //add a new boat if the porbability condition is met
    }
}
function newCloud() {

    var newCloudChance = 0.001; 
    if (random(0,1) < newCloudChance) {
        clouds.push(makeCloud(width,random(0,60)));
    }
}


function newPlane() {

    var newPlaneChance = 0.003; 
    if (random(0,1) < newPlaneChance) {
        planes.push(makePlane(width, random(0,50)));
   }
}

function newBuilding() {

    var newBuildingChance = 0.1; 
    if (random(0,1) < newBuildingChance) {
        buildings.push(makeBuilding(width));
   }
}

function newRailing() {

    var newRailingChance = 0.8; 
    if (frameCount % 2 == 0 & random(0,1)

Yael Braha

Eamonn Burke

This is Yael Braha’s “Tree of Changes”, an interactive sculpture which utilizes metalwork, voice recognition and algorithms, LED lights, and a custom Max/MSP software. It allows a user to speak a “wish” into a microphone, watch it travel up the tree, and become a glowing leaf on the branches.

What I really admire about this project is interactivity, and especially how intimate that interactivity is. It shows the power of computational design as a way to connect to people and make them feel special. Not only is a user able to alter the sculpture, but they are able to do it in a way that feels personal to them, which is the epitome of user experience design. In addition to this, the tree itself looks very elegant despite being made from metal, which is quite a feat.

Yael Braha studied Graphic Design at the European Institute of Design in Rome. She then immigrated to the US to study film at San Francisco State University. She now works in Canada, and works mainly with large computational and architectural installations, but also creates fine hand art such as jewelry and ceramics.

Project 11 Generative Landscape

Planetscape?

sketch
//tjchen 
// project landscape 

var stars=[]; // array for circles 
var streaks=[]; // array for streaks
var speed = 3; // change for how zoom
// color initialization 
var r; 
var g;
var b;
// rate of change fo color 
var dr;
var dg;
var db;

function setup() {
    createCanvas(480, 480);
    //initalize objects
    for(i=0; i<=500; i++ ){
        var s =makeStar();
        var st=makeStreak();
        stars.push(s); 
        streaks.push(st);
    }
    //background color setup
    r = (random(255));
    g = (random(255));
    b = (random(255));
    dr = (random(-5,5));
    db = (random(-5,5));
    dg = (random(-5,5));
    }


function draw() {
    background(r,g,b);
    //set it up from the middle 
    translate(width/2,height/2);
    //draw the stars and streaks 
    for(i=0; i<500; i++){
        var s = stars[i];
        s.drawstar();
        s.updatestar()

        var st = streaks[i];
        st.drawstreak();
        st.updatestreak();
}
// color update 
    if (r>255 || r<0){
        dr= -dr;
    }
    if (g>255 || g<0){
        dg= -dg;
    }
    if (b>255 || b<0){
        db= -db;
    }
    r+=dr;
    g+=dg;
    b+=db;

}

//star construction 

function makeStar(){
    var star={
        x:random(-width,width),
        y:random(-height,height),
        z:random(width), // constant ratio for zoom 
        c:color(random(255),random(255),random(255)),
        drawstar: stardraw,
        updatestar: starupdate,
    }
    return star; 
}

function stardraw(){
    noStroke();
    fill(this.c);
    // draw stars but mapped to z 
    var dx = map(this.x/this.z,0,1,0,width);
    var dy = map(this.y/this.z,0,1,0,width);
    // map it for sizze increase 
    var r = map(this.z,0,width,20,0);  
    ellipse(dx,dy,r);
}

function starupdate(){
    this.z-=speed;
    // reset
    if (this.z<1){
        this.z = width;
        this.x = (random(-width,width));
        this.y = (random(-height,height));
    }

}

// streak construction 
function makeStreak(){
    var streak={
        x:random(-width,width),
        y:random(-height,height),
        z:random(width),
        c:color(random(255),random(255),random(255),50),
        pz: this.z, // previous location of z 
        drawstreak: streakdraw,
        updatestreak: streakupdate,
    }
    return streak; 

}

function streakdraw(){
    strokeWeight(5);
    stroke(this.c);
    var dx = map(this.x/this.z,0,1,0,width);
    var dy = map(this.y/this.z,0,1,0,width);
    var px = map(this.x/this.pz,0,1,0,width);
    var py = map(this.y/this.pz,0,1,0,width); 
    //draw line 
    line(dx,dy,px,py);
}

function streakupdate(){
    this.z-=speed;
    // reset 
    if (this.z<1){
        this.z = width;
        this.x = (random(-width,width));
        this.y = (random(-height,height));
        this.pz = this.z;
    }

}