Dynamic Artistic Skylines with p5.js

After reading several articles and books on the topic of generative art, I came up with the concept of generating an abstract skyline from rectangles.  The main part of the code underwent several iterations to get to the point you see below. The image on the left is with the fill option turned on (backspace toggle), and the image on the right has that turned off.  In either case, by moving the mouse right or left, you can adjust the width of the buildings.  Read on to see some of the code I implemented and check it out for yourself.

As most skylines tend to have taller buildings towards the center, I decided to implement a bell curve and use points along the curve to be the anchors for each of the buildings.  It wasn’t easy to find the formula to implement a bell curve but ultimately pieced some elements together from the web and came up with the following:

				
					 //Function to get a Y value for a given X using std bell curve
 function pdf(x) {
    let mean = width / 2;
    //let std = 120;
    let std = map(mouseY,0,height,60,200);
    let yout = abs(1000/(std * sqrt(2*3.1415)) * exp(-(sq(x - mean)) / (4 * sq(std))));
    return yout*height/16;
 }
				
			

After creating a fairly simplistic version using the standard rect() function, I had in mind a “sketchier” version of the rectangles.  I wanted to create the rectangles from 4 separate lines which would be skewed slightly in multiple iterations and have the opacity vary. 

				
					function artrect(v1, w, h) {
     let v = [];
     v[0] = createVector(v1.x,v1.y+h);
     v[1] = v1;
     v[2] = createVector(v1.x+w,v1.y);
     v[3] = createVector(v1.x+w,v1.y+h);

    //Draw the lines between vertices
    for (let num = 0; num < numshapes; num++) {
        if (num < fuzzy) { //thin normal lines
            if (num == 0) {
                strokeWeight(2);
                stroke(0,100);
            } else {
                strokeWeight(map(num,0,numshapes-1,1,2));
                stroke(0,map(num, 0, numshapes-1,10,1));
            }
        } else { //fat light opacity lines
            strokeWeight(30);
            stroke(0,1);
        }
        for (let i = 0; i < v.length; i++) {
            if (i == 0) {
                line(v[v.length-1].x,v[v.length-1].y,v[0].x, v[0].y);
            } else {
                line(v[i-1].x, v[i-1].y, v[i].x, v[i].y);
            }
        }
        //displace each vertex by a random amount 
        v[0] = v[0].add(random(-displace,displace),random(-displace,displace));
        v[1] = v[1].add(random(-displace,displace),random(-displace,displace));
        v[2] = v[2].add(random(-displace,displace),random(-displace,displace));
        v[3] = v[3].add(random(-displace,displace),random(-displace,displace));
    }
}
				
			

If you’d like to create your own skyline, move your mouse in the image below.  You can also click the ‘S’ key at any time to create a snapshot to save to your PC.

Share This Post

Leave a Comment

Your email address will not be published. Required fields are marked *

More To Explore