Alexandra Kaplan – Project 10 – Generative Landscape

sketch

/*
Alexandra Kaplan
Section C
aekaplan@andrew.cmu.edu
Project - 10
*/

var planets = [];
var stars = [];
var ex = 500;
var ey = 500;

function setup() {
    createCanvas(480, 480); 
    
    // create an initial collection of planets
    for (var i = 0; i < 10; i++){
        var rx = random(width);
        if (planets.length < 5){
            planets[i] = makePlanet(rx);
        }
    }
    for(var j = 0; j < 200; j++){
        var sx = random(width);
        stars[j] = makeStar(sx);
    }
    frameRate(20);
}

function draw() {
    background(10,30,120);

    updateAndDisplayStars();
    removestars();
    addNewstars();

    updateAndDisplayplanets();
    removeplanets();
    addNewplanets();
    
    drawShootingStar();
    var newShootingStarLikelihood = 0.01; 
    if (random(0, 1) < newShootingStarLikelihood){
    	if(ex > width || ey > height){
    	   createshootingStar();
    	}
    }	
}
function drawShootingStar(){
	fill('khaki');
	strokeWeight(0);
	var dx = 5;
	var dy = 10;
	ellipse(ex + dx, ey + dy, 10);
	ex += dx;
	ey += dy;
}

function createshootingStar(){
	ex = random(0, width);
	ey = 0;
 }

///////////PLANETS////////////////////////////////////////////////
function updateAndDisplayplanets(){
    // Update the Planet's positions, and display them.
    for (var i = 0; i < planets.length; i++){
        planets[i].move();
        planets[i].display();
    }
}

function removeplanets(){
    // If a Planet has dropped off the left edge,
    // remove it from the array
    var planetsToKeep = [];
    for (var i = 0; i < planets.length; i++){
        if (planets[i].x + 50 + planets[i].breadth > 0){
            planetsToKeep.push(planets[i]);
        }
    }
    planets = planetsToKeep; // remember the surviving planets
}

function addNewplanets() {
    // With a very tiny probability, add a new Planet to the end.
    var newPlanetLikelihood = 0.6; 
    if (random(0, 1) < newPlanetLikelihood){
        if (planets.length < 5){
            planets.push(makePlanet(width + 40));
        }
    }
}

// method to update position of Planet every frame
function PlanetMove() {
    this.x += this.speed;
}
   
// draw the Planet
function PlanetDisplay() {
    var pwidth = this.wid;
    fill(this.col); 
    strokeWeight(0); 
    ellipse(this.x, this.y, pwidth);
    stroke(this.strkCol);
    strokeWeight(this.strk);
    line(this.x - (this.wid / this.srtklength) , this.y, this.x + (this.wid / this.srtklength), this.y); 
}


function makePlanet(birthLocationX) {
    var plnt = {x: birthLocationX,
    	        y: random(0, height),
                breadth: 10,
                speed: random(-5,-1),
                wid: random(20, 75),
                move: PlanetMove,
                display: PlanetDisplay,
                col:color(random(50, 100), random(50, 150), random(100, 255)),
                strk: random(0, 5),
                strkCol: color(random(50, 100), random(50, 150), random(100, 255)),
                srtklength: random(1,2),
                }
    return plnt;
}

///////////STARS////////////////////////////////////////////////
function updateAndDisplayStars(){
    // Update the star's positions, and display them.
    for (var i = 0; i < stars.length; i++){
        stars[i].move();
        stars[i].display();
    }
}

function removestars(){
    // If a star has dropped off the left edge,
    // remove it from the array
    var starsToKeep = [];
    for (var i = 0; i < stars.length; i++){
        if (stars[i].x + stars[i].breadth > 0) {
            starsToKeep.push(stars[i]);
        }
    }
    stars = starsToKeep; // remember the surviving stars
}

function addNewstars() {
    // With a very tiny probability, add a new star to the end.
    var newStarsLikelihood = 0.5; 
    if (random(0,1) < newStarsLikelihood) {
        stars.push(makeStar(width + 40));
    }
}

// method to update position of stars every frame
function StarMove() {
    this.x += this.speed;
}
   
// draw the star
function StarsDisplay() {
    var swidth = this.wid;
    fill(this.col); 
    strokeWeight(0); 
    ellipse(this.x, this.y, swidth);  
}


function makeStar(birthLocationX) {
    var st = {x: birthLocationX,
    	        y: random(0, height),
                breadth: 10,
                speed: -.5,
                wid: random(1, 5),
                move: StarMove,
                display: StarsDisplay,
                col:color('palegoldenrod'),
            }
    return st;
}

When thinking about a generative landscape, my mind went straight to space, with planets and stars passing by.

                                                    Image of the original sketch

I started off by referring to the bulding base code and changing it to planets of various sizes. I then added strokes of different random weights and lengths to be the planet’s rings. The stars behind the planets were made in a similar way, but with more of them. I then added some shooting stars for fun. I think it turned out pretty well.

Sophie Chen – Project 10 – Landscape

sketch

// Sophie Chen
// Section C
// sophiec@andrew.cmu.edu
// generative landscape

var terrainSpeed = 0.0004;
var terrainDetail = 0.005;
var clouds = [];

function setup() {
    createCanvas(480, 250);
      // create an initial clouds
    for (var i = 0; i < 10; i++){
        var rx = random(width);
        clouds[i] = makeClouds(rx);
    }
    
}

function draw() {
    background(150, 200, 200, 10);
    sun();
    terrain();
    terrain2();
    terrain3();
    terrain4();
    terrain5();
    

    updateClouds();
    removeClouds();
    addRandomClouds(); 

}

function sun(){
    noStroke();
    fill(255, 160, 110);
    ellipse(350, 230, 220, 220);

}
function updateClouds(){
    // Update the cloud positions
    for (var i = 0; i < clouds.length; i++){
        clouds[i].move();
        clouds[i].display();
    }
}


function removeClouds(){
    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 addRandomClouds() {
    // half half probability of new cloud
    var newCloudLikelihood = 0.005; 
    if (random(0,1) < newCloudLikelihood) {
        clouds.push(makeClouds(width));
    }
}


// move cloud positions
function cloudMove() {
    this.x += this.speed;
}
    

// draw clouds
function cloudDisplay() {
    var bHeight = this.x; 
    fill(255, 255, 255); 
    noStroke(); 
    push();
    translate(this.x, this.y);
    ellipse(0, 0, this.diam, this.diam);
    ellipse(0 - 20, 0 + 5, this.diam / 1.3, this.diam / 1.3);
    ellipse(0 + 15, 0, this.diam, this.diam);

    pop();
}

function makeClouds(birthLocationX) {
    var cloud = {x: birthLocationX,
    	        y: random(0, height / 2),
    	        diam: random(30, 60),
                breadth: 50,
                speed: -1.0,
                move: cloudMove,
                display: cloudDisplay}
    return cloud;
}

// noise terrains

function terrain(){
    noFill(); 
    stroke(0); 
    beginShape();
    for (var x = 0; x < width; x++) {
        var t = (x * terrainDetail) + (millis() * terrainSpeed);
        var y = map(noise(t - 0.05), 0, 1, 0, height);
        vertex(x, y); 
    }
    endShape();   
}

function terrain2(){
    noFill(); 
    stroke(0);
    beginShape(); 
    for (var x = 0; x < width; x++) {
        var t = (x * terrainDetail) + (millis() * terrainSpeed);
        var y = map(noise(t - 0.1), 0, 1, 0, height);
        vertex(x, y + 5); 
    }
    endShape();
}

function terrain3(){
    noFill(); 
    stroke(0);
    beginShape(); 
    for (var x = 0; x < width; x++) {
        var t = (x * terrainDetail) + (millis() * terrainSpeed);
        var y = map(noise(t - 0.15), 0, 1, 0, height);
        vertex(x, y + 10); 
    }
    endShape();
}

function terrain4(){
    noFill(); 
    stroke(0);
    beginShape(); 
    for (var x = 0; x < width; x++) {
        var t = (x * terrainDetail) + (millis() * terrainSpeed);
        var y = map(noise(t - 0.2), 0, 1, 0, height);
        vertex(x, y + 15); 
    }
    endShape();
}

function terrain5(){
    noFill();
    stroke(0);
    beginShape(); 
    for (var x = 0; x < width; x++) {
        var t = (x * terrainDetail) + (millis() * terrainSpeed);
        var y = map(noise(t - .25), 0, 1, 0, height);
        vertex(x, y + 20); 
    }
    endShape();
}

I’m glad that I got to play more with noise in this project. I tried to create a mix of 2d and 3d to create more contrast and depth since everything is going in the same direction. My favorite part is the interaction between the terrain and the sun, overall I think it turned out better than I expected.

initial rough sketch

 

Kyle Leve-Project-10-Landscape

sketch

// Kyle Leve
// kleve@andrew.cmu.edu
// Section A
// Project-10-Landscape

var img1;
var img2;
var snowman = [];
var terSpeed1 = 0.0002;
var terDetail1 = 0.01;
var terSpeed2 = 0.00025;
var terDetail2 = 0.005;
var terSpeed3 = 0.0003;
var terDetail3 = 0.0001;

// Loads ski guy and snowman images
function preload() {
	img1 = loadImage('https://i.imgur.com/9Bjj5oY.jpg');
	img2 = loadImage('https://i.imgur.com/6UIcB6H.jpg');
}

function setup() {
    createCanvas(480, 480);
    frameRate(10);
}

function draw() {
	background('indigo');

    // Dark blue mountains
	fill(0, 20, 70);
	beginShape();
	vertex(0, height);
	for (var x = 0; x < width; x++) {
		var z = (x * terDetail1) + (millis() * terSpeed1);
	    var y = map(noise(z), 0, 1, 0, height/3);
		vertex(x, y);
	}
	vertex(width, height);
	endShape();

    // Lighter blue mountains
	fill(0, 20, 120);
	beginShape();
	vertex(0, height);
	for (t = 0; t < width; t++) {
		var s = (t * terDetail2) + (millis() * terSpeed2);
	    var r = map(noise(s), 0, 1, 0, height - 100);
		vertex(t, r);
	}
	vertex(width, height);
	endShape();

    // Snow hill
	fill(255);
	beginShape();
	vertex(0, height);
	for (a = 0; a < width; a++) {
		var b = (a * terDetail3) + (millis() * terSpeed3);
	    var c = map(noise(b), 0, 0.75, 0, height - 70);
		vertex(a, c);
	}
	vertex(width, height);
	endShape();

    // Ski guy image
    noStroke();
	image(img1, 20, c + 40, 70, 70);

    displaySnowman();
    removeSnowman();
    newSnowman(); 
}

// To show the snowman
function displaySnowman() { 
    for (var i = 0; i < snowman.length; i++){
        snowman[i].move();
        snowman[i].display();
    }
}

// Removes any snowmen that go off the screen
function removeSnowman() {
    var keepSnowman = [];
    for (var i = 0; i < snowman.length; i++){
        if (snowman[i].x + snowman[i].breadth > 0) {
            keepSnowman.push(snowman[i]);
        }
    }
    snowman = keepSnowman;
}

// Creates snowmen
function newSnowman() {
    var snowmanChance = 0.0005; 
    if (random(0.1) < snowmanChance) {
        snowman.push(makeSnowman(width));
    }
}

// Moves snowmen
function snowmanMove() {
    this.x += this.speed;
}

// Calls the snowman image    
function snowmanDisplay() {
    var b = (a * terDetail3) + (millis() * terSpeed3);
    var c = map(noise(b), 0, 0.75, 0, height - 70); 
    noStroke();
    push();
    translate(this.x, height - 100);
    image(img2, 10, 0, 70, 100);
    pop();
}

// Sets the location of the snowman and moves it across the screen
function makeSnowman(LocationX) {
    var snow = {x: LocationX,
                breadth: 50,
                speed: -20.0,
                move: snowmanMove,
                display: snowmanDisplay}
    return snow;
}

I found this project to be very fun because it allowed me to create a scene even if it just repeated itself. I decided to create a winter scene with a guy skiing and some snowmen. I used the snowmen as an object that would randomly generate itself as the scene continued.

Jenna Kim (Jeeyoon Kim) – Project 10 – Landscape

jeeyoonk10

/* Jenna Kim (Jeeyoon Kim)
Section E
jeeyoonk@andrew.cmu.edu
Project 10
*/

var hillSpeed = 0.00055;
var hillDetail = 0.0055;
var yN = 50;
var trees = [];

var x = [];
var y = [];

function setup() {
   createCanvas(500, 400);

    for (i = 0; i < 100; i++){ //setting for stars placement
        x[i] = random(50, width);
        y[i] = random(50, width / 2);
    }
    //trees
    for (var j = 0; j < 15; j++){
        var rx = random(width);
        trees[j] = makeTree(rx);
    }
    frameRate(10);
}


function draw(){
    background(24, 44, 63);
    var S = second();
     for(i = 0; i < S; i++){ //tiny firefly appears every "SEC"
        fill(255);
        noStroke();
        ellipse(x[i], y[i], 3, 3);
    }
    hill();
    wave();
    updateAndDisplayTrees();
    noStroke();
    ellipse(width-55, 40, 45, 45); //pink moon
}

function star() {
    for(i = 0; i < S; i++){ //star appears every "SEC"
        fill(247, 246, 146);
        noStroke();
        ellipse(x[i], y[i], 4, 4);
    }
}
//drawing hill
function hill() {
    stroke(49, 110, 167);
    beginShape(); 
    for (var x = 0; x < width; x++) {
        var t = (x * hillDetail) + (millis() * hillSpeed);
        var y = map(noise(t), 0,1, 30, height-35);
        //vertex(x, y); 
        line(x, y, x, height);
    }
    noStroke(); //ground
    fill(136, 143, 208);
    rect(0, 380, width, 20)
    endShape();
} 

function wave(){ //drawing waves
    beginShape();
    fill(221, 153, 205);
    var xN = yN;
    for (var x = 0; x <= width; x += 10){
        var y = map(noise(xN, yN), 0, 1, 200, 400);
        //setting the vertex
        vertex(x, y - 0.005); //x dimension
        xN += 0.05;
    }
    yN += 0.055; //y dimension
    vertex(width, height - 20);
    vertex(0, height - 20);
    endShape();

}

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

// Trees are removed when hitting the edge
function RTrees(){
    var TreesToKeep = [];
    for (var i = 0; i < trees.length; i++){
        if (trees[i].x + trees[i].breadth > 0) {
            keepTrees.push(trees[i]);
        }
    }
    trees = TreesToKeep;
}

// adding tree to the end
function addrandomTreeswithProbability() {
    var newTreesLikelihood = 0.05;
    if (random(0,4) < newTreesLikelihood) {
        trees.push(makeTree(width));
    }
}

// update position of tree every frame
function treeMove() {
    this.x += this.speed;
}

// drawing the trees
function treeDisplay() {
    var floorHeight = 5;
    var bHeight = this.nFloors * floorHeight * 2;
    noStroke();
    //drawing tree trunks
    push();
    translate(this.x, height - 20);
    fill(24, 44, 63);
    rect(3, -bHeight, this.breadth, bHeight);
    // drawing top part of the tree
    fill(105, 247, 193);
    ellipse(3, -bHeight, bHeight / 2, bHeight / 2);
    pop();
}


function makeTree(birthLocationX) {
    var TRR = {x: birthLocationX,
             breadth: 1,
             speed: -0.5,
             nFloors: round(random(2,4)),
             move: treeMove,
             display: treeDisplay}
    return TRR;
}

For this project, I had fun making this animation, but at the same time, it was very difficult to figure out how to place the trees and try different variations for the mountains. I tried to make this very aesthetic and attractive by thinking a lot about good color combination. I added stars so that they appear every second. The final result is close to what I wanted, and I want to develop it further in the future.

sketch

Jessica Timczyk – Looking Outwards 10

Some of the man hole coverings included in Ingrid Burrington’s website and book about New York’s networks and infrastructures.

Ingrid Burrington is an author, activist, and hacker and has worked on many  exhibitions, projects making maps, writing books and teaching at various schools including Cooper Union and the Rhode Island School of Design. She is from and still lives in New York City, and I unfortunately was unable to find where she went to school. One of her most interesting works, I have found, is her website and book Seeing Networks in New York City, that details New York’s network infrastructure. I found this project incredibly interesting because when in New York, normally a visitor is looking for and paying attention to all the sight-seeing and famous buildings and etc. that are there, but this project provides a map of city focusing on features that are commonly over looked. For example man hold covers, street markings and antennas. This project provides a different way to look at New York that I find incredibly interesting.

 

Mimi Jiao – Project 10 – Section E

sketch

/* Mimi Jiao
wjiao@andrew.cmu.edu
Section E 
Project 10
*/

var terrainSpeed1 = 0.00004;
var terrainSpeed2 = 0.00015;
var terrainDetail = 0.0024;
var trees = [];

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

    //pushing trees into initial tree array 
    for (var i = 0; i < 10; i++){
        var rx = random(width);
        trees[i] = makeTree(rx);
    }
    frameRate(10);
}


function draw() {
    background(76, 101, 205); 

    //mountains in the back
    beginShape(); 
    stroke(78, 69, 94)
    for (var x = 0; x < width; x++) {
        var t = (x * terrainDetail) + (millis() * terrainSpeed1);
        var y = map(noise(t), 0,1, height / 2, height / 5);
        line(x, y, x, height * 9 / 12);

    }
    endShape();

    //mountains in the front
    beginShape();
    stroke(55, 55, 81)
    for (var x1 = 0; x1 < width; x1++) {
        var t1 = (x1 * terrainDetail) + (millis() * terrainSpeed2);
        var y1 = map(noise(t1), 0,1, height / 4, height / 1.5);
        line(x1, y1, x1, height * 9 / 12);

    }
    endShape();
    
    //horizon line
    fill(36, 36, 42);
    rect(0, height * 9 / 12, width, height / 4);

    updateTrees();
    removeTrees();
    randomTrees();

    //wall fill
    noStroke();
    fill(38, 44, 62);
    rect(0, 0, width, height / 5);
    rect(0, 0, width / 10, height);
    rect(0, 4 * height / 5, width, height / 5);
    rect(9 * width / 10, 0, width / 10, height);

    //WINDOW 
    noFill();
    rectMode(CORNER);
    rect(width / 10, height / 5, width * 8 / 10, 3 * height / 5);
    fill(70, 90, 140);
    noStroke();
    rect(width / 10 - 10, height / 5, (width * 8 / 10) + 20, height / 40);
    rect(width / 10 - 10, height * 4 / 5, (width * 8 / 10) + 20, height / 40);
    rect(width / 10 - 10, height / 5, 10, 185);
    rect(width * 9 / 10, height / 5, 10, 185);
    push();
    rectMode(CENTER);
    rect(width / 2, height / 2 + 5, (width * 8 / 10) + 20, height / 40);
    rect(width / 2, height / 2 + 5, 10, 185);
    pop();   
}

//update tree location after moving them and display them
function updateTrees(){
    for (var i = 0; i < trees.length; i++){
        trees[i].move();
        trees[i].display();
    }
}

//if trees fall out of the viewing window, remove from array
function removeTrees() {
    var treesToKeep = [];
    for (var i = 0; i < trees.length; i++) {
        if (trees[i].x + trees[i].breadth > width / 10) {
            treesToKeep.push(trees[i]);
        }
    }
    trees = treesToKeep;

}

//randomly generate trees
function randomTrees() {
    var newTreeProbability = .03;
    if (random(0,1) <= newTreeProbability) {
        trees.push(makeTree(width));
    }
}

//move the trees
function treeMove() {
    this.x += this.speed;
}

//display and draw the trees
function treeDisplay() {
    var treeHeight = -height * 4 / 12;
    fill(255); 
    noStroke(); 
    push();
    translate(this.x, height);
    fill(71, 91, 73);
    //tree body and leaves
    triangle(0,(-height * 3 / 12) + 5,
             20, (-height * 3 / 12) + 5,
             10, treeHeight + this.height);
    //tree log
    noStroke();
    fill(106, 91, 82);
    rect(8, (-height * 3 / 12) + 5, 5, 6);
    stroke(200); 
    pop();
}

//create the tree
function makeTree(birthLocationX) {
    var tr = {x: birthLocationX,
                breadth: 20,
                speed: -3.5,
                height: random(-25, 10),
                move: treeMove,
                display: treeDisplay}
    return tr;
}

One of my deepest memories is of myself looking out of a moving train at night in the deserts of north-central China. I wanted to recreate the feeling of watching mountains pass by when the sun has just set. I initially explored both a vertical and horizontal composition, but I ultimately ended up with the landscape view. At the end, I changed a train window to a regular window because I thought it was more intuitive to understand. Here’s a picture of my initial sketches:

Mimi Jiao – Looking Outwards 10 – Section E


Claudia Hart, Inside the Flower Matrix, 2017

Claudia Hart is a new media artist who emerged as a part of the identity art movement. Her works center around observing identity, perception, and the physical being through the lens of technology. A work I particularly was interested in is virtual reality environment and sound installation Inside the Flower Matrix, 2017. This piece is a play on Alice in Wonderland in the digital age, where rationality and technology goes off-rail. There are multiple parts of this piece where viewers can experience it through a virtual reality app by pointing their camera at the artwork. In addition to the digital version, there are also hand thrown ceramics, quilts, wallpaper to accompany the experience. I am really impressed by the way that she has brought a digital environment into the real world and added instances of tangibility to further emphasize her idea. The way she has integrated items that the user can interact with and experience through touch and sound really drives her idea of the integration of technology with the human body. I really wish I could visit the real site installation of this piece – the online experience of this piece is nowhere as representative as it would be in the real space. It would be interesting to see her build a web and digital experience off of this piece.

Victoria Reiter – Looking Outwards – 10

Kristin Neidlinger Augmented Fashion Designer

Goosebump Poof in action

This week I chose the augmented fashion designer Kristin Neidlinger as the focus for my Looking Outwards post. I thought that her work was really interesting, because it combines a lot of different sectors that may not seem like they relate to each other.

Kristin is no doubt a fashion designer, as you can see by the elegant design of her clothes, but she also makes use of code and scientific technology. This “Goosebump Poof” is embedded with biosensors that track mood through heart rate, excitement (GSR), and breath. Thus, Neidlinger also utilizes elements of the human body, itself a complex system albeit a natural when compared to computing and technology.

Goosbump Poof with lights

Furthermore, Neidlinger’s projects really contribute something to their wearers. This project allows people to intimately self-reflect, and be in touch with their own emotions, feelings, and memories, also something that may seem to be juxtaposed with technology. Another one of her projects is a corset that detects stress levels and constricts in order to relax its wearer.

What’s even more is that her projects are made out of recycled materials!

Full info on the project can be found here!

Eunice Choe – Looking Outwards-10

TACTUM – Tactile Augmented Reality from Madeline Gannon on Vimeo.

This video highlights the process of creating a Tactum wearable.

An example of a final product.

Tactum (2015), by Madeline Gannon, is a skin centric design tool that allows people to design 3D printed wearables on their bodies using depth sensing and projection mapping. This modeling tool allows people to design wearables naturally. Through touching, poking, rubbing, or pinching the skin, people can easily manipulate the design of the wearables and then 3D print them. I admire this project because it is interactive, efficient, and customizable. I admire how the designer found a way to use interactive technology for fashion and functional purposes. This project was led by Madeline Gannon, the head of Madlab.cc and a PhD candidate in Computational Design at Carnegie Mellon University. She runs Madlab.cc which is a research studio that specializes in creating interfaces for wearables on the body.

Eunice Choe – Project 10 – Landscape

sketch

/*Eunice Choe
Section E
ejchoe@andrew.cmu.edu
Project-10*/

var cloud = [];
var trees = [];
var terrainSpeed = 0.0001;
var terrainDetail1 = 0.005;
var terrainDetail2 = 0.008;


function setup() {
    createCanvas(480,300);
    angleMode(DEGREES);
    // initial collection of trees and clouds
    for (var i = 0; i < 10; i++) {
        var cloudX = random(width);
        var rx = random(width);
        cloud[i] = makeCloud(cloudX);
        trees[i] = makeTree(rx);
    }
}

function draw() {
    background(255, 223, 197);
    // dark mountains in background
    push();
    beginShape();
    fill(104, 101, 181);
    vertex(0,height);
    for (var x = 0; x < width; x++) {
        var t = (x * terrainDetail2) + (millis() * terrainSpeed);
        var y = map(noise(t), 0, 1, 0, height);
        vertex(x, y - 50);
    }
    vertex(width, height);
    endShape();
    pop();

    // light mountains in background
    push();
    beginShape();
    fill(165, 168, 199);
    vertex(0,height);
    for (var x = 0; x < width; x++) {
        var t = (x * terrainDetail1) + (millis() * terrainSpeed);
        var y = map(noise(t), 0, 1, 0, height);
        vertex(x, y);
    }
    vertex(width, height);
    endShape();
    pop();

    displayHorizon();
    updateTrees();
    removeTrees();
    randomTrees();
    fill(165, 168, 199);

    // drawing and moving the transparent clouds
    for(var i = 0; i < cloud.length; i++) {
        cloud[i].draw();
        cloud[i].move();
    }
}

function cloudDraw() {
    push();
    translate(this.xPos, this.yOffset);
    stroke(255, 255, 255, 60);
    strokeWeight(this.cHeight);
    line(0, 0, this.cSize, 0);
    pop();
}

// when moving clouds reach edge
// send them to other edge with random position, size, height
function cloudMove() {
    this.xPos += this.speed;
    if(this.xPos < 0 - this.cSize - 30) {
        this.cHeight = random(10, 50);
        this.cSize = random(30, 150);
        this.xPos = width + this.cSize + random(-25, 25);
    }
}

function makeCloud() {
    var cloud = {xPos: random(width), //, width*4
                speed: random(-0.4, -0.3),
                cSize: random(30, 150),
                cHeight: random(20, 60),
                yOffset: random(50, height),
                draw: cloudDraw,
                move: cloudMove};
    return cloud;
}

function updateTrees(){
    // Update the trees positions
    for (var i = 0; i < trees.length; i++){
        trees[i].move();
        trees[i].display();
    }
}

// if trees hit edge, then remove from array
function removeTrees(){
    var keepTrees = [];
    for (var i = 0; i < trees.length; i++){
        if (trees[i].x + trees[i].breadth > 0) {
            keepTrees.push(trees[i]);
        }
    }
    trees = keepTrees;
}

// with probability, add tree to the end
function randomTrees() {
    var newTreeLikelihood = 0.007;
    if (random(0,1) < newTreeLikelihood) {
        trees.push(makeTree(width));
    }
}

// update position of tree every frame
function treeMove() {
    this.x += this.speed;
}


// drawing the trees
function treeDisplay() {
    var floorHeight = 10;
    var bHeight = this.nFloors * floorHeight;
    noStroke();
    // tree trunk
    push();
    translate(this.x, height - 100);
    fill(204, 187, 145);
    rect(0, -bHeight, this.breadth, bHeight);
    // tree trunk reflections
    fill(204, 187, 145, 50);
    rect(0, -bHeight + bHeight, this.breadth, bHeight);

    // tree leaves
    fill(255, 136, 112);
    ellipse(2.5, -bHeight, 35, bHeight);
    //tree leaves reflections
    fill(255, 136, 112, 50);
    ellipse(2.5, bHeight, 35, bHeight);
    pop();
}


function makeTree(birthLocationX) {
    var tr = {x: birthLocationX,
             breadth: 5,
             speed: -1.0,
             nFloors: round(random(2,8)),
             move: treeMove,
             display: treeDisplay}
    return tr;
}

function displayHorizon(){
    noStroke();
    // water
    fill(192, 219, 212);
    rect(0,height-100, width, height-50);
    // grqss
    fill(152, 194, 146);
    rect(0,height-100, width, 20);
}

Overall, I found this project a little challenging. I had a solid plan with my sketch and I was able to execute it, but I found myself getting easily confused because there were so many lines of code. However, when I got the code figured out, I was able to capture the calmness and serenity of a mountain landscape. Along with the mountains in the background, I added trees, water, and tree reflections in the front. I also added moving transparent clouds that overlay the canvas. While this project was difficult for me, I am satisfied with the outcome and the skills I developed from it.

My initial sketches.