Angela Lee – Project 11 – Generative Landscape

sketch

/*
 * Angela Lee
 * Section E
 * ahl2@andrew.cmu.edu
 * Project 11 Generative Landscape
 */

// tallest mountains
var tallMtnDetail = 0.005; // detail in mountains
var tallMtnSpeed = 0.0001; // speed of mountains

// medium mountains
var medMtnDetail = 0.0075;
var medMtnSpeed = 0.0002; 

// beach 
var beachDetail = 0.003;
var beachSpeed = 0.0004;

// array for ripples
var ripples = [];

var yellow, pink; 

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

    // boundaries for ripples
    var top = height * 5/8 + 10;
    var bottom = height - 10;

    // first ripples 
    for (var i = 0; i < 10; i++) {
        var rippleX = random(width);
        var rippleY = random(top, bottom);
        ripples[i] = makeRipples(rippleX, rippleY);
    }

    // gradient for the water
    yellow = color(255, 219, 140);
    pink = color(247, 132, 124);
 }

function draw() {
    noStroke();
    background(255, 156, 161);
    makeSun(); // setting sun
    makeTallMtn(); // tallest mountains
    makeMedMtn(); // middle mountains
    //makeWater();
    gradientWater();

    // ripple functions
    updateRipple();
    removeRipple();
    addRipple(); 

    makeBeach();

}
//----------------- FUNCTIONS BELOW THIS LINE -----------------------------

// SETTING SUN
function makeSun() {
    // sun rays
    noStroke();
    fill(255, 161, 135);
    ellipse(width/2, height * 3/8, 275, 275);

    // sun
    stroke(255);
    strokeWeight(1);
    fill(247, 217, 82);
    ellipse(width/2, height * 3/8, 175, 175);
    
}

// TALLEST MOUNTAINS
function makeTallMtn() {
    fill(252, 119, 165);
    strokeWeight(1);
    beginShape();
    vertex(0, height);
    for (var x = 0; x < width; x++) {
        var t = (x * tallMtnDetail) + (millis() * tallMtnSpeed);
        var y = map(noise(t), 0, 1, height / 8 * 2, height / 8 * 4);
        vertex(x, y);
    }
    vertex(width, height);
    endShape();
}

// MEDIUM MOUTAINS
function makeMedMtn() {
    fill(230, 99, 160);
    strokeWeight(1);
    beginShape();
    vertex(0, height);
    for (var x = 0; x < width; x++) {
        var t = (x * medMtnDetail) + (millis() * medMtnSpeed);
        var y = map(noise(t), 0, 1, height / 8 * 3, height / 8 * 5);
        vertex(x, y);
    }
    vertex(width, height);
    endShape();
}

// OCEAN
function gradientWater() {
    noFill();
    for (var y = height * 5/8; y < height; y++) {
        var inter = map(y, height * 5/8, height, 0, 1);
        var c = lerpColor(yellow, pink, inter);
        stroke(c);
        line(0, y, width, y);
    }
}

// BEACH
function makeBeach() {
    fill(252, 195, 182);
    strokeWeight(1);
    beginShape();
    vertex(0, height);
    for (var x = 0; x < width; x++) {
        var t = (x * beachDetail) + (millis() * beachSpeed);
        var y = map(noise(t), 0, 1, height * 7/8, height * 19/20);
        vertex(x, y);
    }
    vertex(width, height);
    endShape();
}

//----------------- RIPPLE OBJ & FUNCTIONS BELOW THIS LINE -----------------------------

// RIPPLE OBJECT
function makeRipples(xPos, yPos) {
    var makeRipple = {x: xPos,
                      y: yPos,
                      // longer ripples are in the front, shorter ones in the back
                      length: map(yPos, height * 5/8, height, 5, 75),
                      // thinner ripples in the back, thicker ones in the front
                      weight: map(yPos, height * 5/8, height, 1, 4),
                      // faster ripples in the front, slower ripples in the back
                      speed: map(yPos, height * 5/8, height, 1, 4),
                      move: moveRipple,
                      draw: drawRipple}
    return makeRipple; 
}

// MOVING THE RIPPLE
function moveRipple() {
    // x position changes by speed
    this.x += this.speed; 
    // if the ripple leaves the frame, reset x position
    // to the left side of the frame
    if (this.x > width + this.length) {
        this.x === -this.length;
    }
}

// ADDING RIPPLES
// using a tiny probability, add ripples
function addRipple() {
    if (random(0, 1) < 0.075) {
        ripples.push(makeRipples(-75, random(height * 5/8, height)));
    }
}

// REMOVING RIPPLES
function removeRipple() {
    // an array for ripples to keep
    var keepRipples = [];
    for (var i = 0; i < ripples.length; i++) {
        if (ripples[i].x < width) {
            keepRipples.push(ripples[i]);
        }
    }
    ripples = keepRipples;
}

// UPDATE AND DISPLAY RIPPLE
function updateRipple() {
    for (var i = 0; i < ripples.length; i++) {
        ripples[i].move();
        ripples[i].draw();
    }
}

// DRAWING THE RIPPLE
function drawRipple() {
    strokeWeight(this.weight);
    stroke(255);
    line(this.x, this.y, this.x + this.length, this.y);
}







For my landscape, I was inspired the 80s vaporwave illustration style and color. I created a sunset scene and had fun with showing depth through details. For instance, the sizes and speeds of the mountains and ripples are all dependent on the “distance” they would be away from the viewer (the farther something is, the slower and smaller it is).

I’m using a grace day for this project 🙂

A sketch of my beach landscape.

Leave a Reply