For this assignment, we were asked to create a piece of art or a game using object-oriented programming (OOP). I immediately thought of re-creating some significant piece of art using processing and adding randomized, generative elements to it. When I started thinking of pieces that were predominantly geometric, I immediately thought of Piet Mondrian’s work. I thought it would be interesting to see abstractness become randomized, in a way. After this, I searched for Mondrian + Generative Art. I did not expect to find that many results. Mondrian and code, Mondrian and generative art, Mondrian and processing. There even was an entire programming language called Piet. It was way, way too overdone to the point where I couldn’t think of any way I could create my own take on it- so I had to change my idea.
So, inspired by the rainfall over the weekend, I created a rainy skyline of Abu Dhabi from day to night. First, for the sky, I had to think on paper:
Here is the final result, the “time of day” changes with the movement of the mouse:
And, here is my code:
//arrayList to hold all stars ArrayList<Star> stars = new ArrayList<Star>(); Moon moon = new Moon(); int modifier; float raindrop; int red, green, blue; void setup() { size(585,430); background(0); raindrop= 0; //generate 30 random stars for (int i = 0; i < 30; i++) { stars.add(new Star()); } } void draw() { raindrop = raindrop + 4; //speed //if raindrop falls below canvas, reset to zero if (raindrop >= height) raindrop = 0; //map mouseX to rgb values of background red = int(map(mouseX, 0, width, 83, 0)); green = int(map(mouseX, 0, width, 157, 0)); blue = int(map(mouseX, 0, width, 253, 0)); modifier = int(map(mouseX, width/2, width, 29, 0)); background(red, green, blue); if (mouseX > width/2) { for (int i = 0; i < stars.size() - modifier; i++) { Star s = stars.get(i); s.drawStar(); } } moon.update(); moon.drawMoon(); //rainfall fill(211,211,211); rect(10, raindrop, 2, 5); rect(50, raindrop+20, 2, 5); rect(80, raindrop, 2, 5); rect(110, raindrop+100, 2, 5); rect(140, raindrop+150,2, 5); rect(180, raindrop-200, 2, 5); rect(200, raindrop-150, 2, 5); rect(240, raindrop-50, 2, 5); rect(240, raindrop, 2, 5); rect(300, raindrop+20, 2, 5); rect(440, raindrop, 2, 5); rect(440, raindrop, 2, 5); rect(550, raindrop+100, 2, 5); rect(530, raindrop-250, 2, 5); rect(530, raindrop-200, 2, 5); rect(580, raindrop-300, 2, 5); rect(300, raindrop-400, 2, 5); rect(140, raindrop-350, 2, 5); rect(400, raindrop-300, 2, 5); rect(400, raindrop-250, 2, 5); rect(400, raindrop-200, 2, 5); rect(550, raindrop, 2, 5); //this part of my code uses & adapts from "skyline" by Shiwen Qin on OpenProcessing //building 1 fill(250); rect(35,255,5,55); fill(250); rect(40,250,40,60); fill(51, 51, 51); quad(80,250,80,310,95,310,95,260); fill(106,106,71); for (int y=258; y<310; y+=8){ fill(106,106,71); rect(36,y,2,2); } for (int y=258; y<300;y+=10){ for(int x=44; x<78; x+=10){ fill(106,106,71); rect(x,y,3,3); } } //building 2 fill(51, 51, 51); rect(93,265,40,60); for (int y=270; y<300;y+=10){ for(int x=96; x<130; x+=10){ fill(165,160,102); rect(x,y,5,3); } } //building 3 fill(220,220,220); rect(150,225,15,120); fill(220,220,220); rect(164,215,10,140,6); fill(169,169,169); rect(166,218,2,140,7); fill(105,105,105); arc(170,250,70,70,-PI/2,0); rect(170,250,35,140); fill(192,192,192); arc(170,250,60,60,-PI/2,0); rect(170,250,30,140); fill(192,192,192); arc(170,250,40,40,-PI/2,0); rect(170,250,20,140); //fourth building fill(250); fill(250); rect(235,225,5,75); fill(250); rect(240,225,40,80); fill(106,106,71); for (int y=258; y<310; y+=8){ fill(106,106,71); rect(236,y,2,2); } for (int y=258; y<300;y+=10){ for(int x=244; x<278; x+=10){ fill(106,106,71); rect(x,y,3,3); } } // fifth building fill(102, 102, 102); rect(300,185,36,120); fill (51, 51, 51); rect (295, 185, 5, 120); rect (305, 185, 5, 120); //sixth building fill(51, 51, 51); rect(376,172,2,10); rect(375,180,3,15); quad(350,206,350,316,380,316,380,190); fill(102, 102, 102); quad(375,198,375,316,405,316,405,215); fill(51, 51, 51); rect(387,215,1,115); rect(396,215,1,115); //seventh building fill(51, 51, 51); rect(430,200, 40 ,150); fill(250); rect(430,200, 40 ,5); rect(470,200, 2 ,150); //seventh building .2 fill(192,192,192); rect(490,200, 40 ,150); fill(250); rect(490,200, 40 ,5); rect(500,200, 2 ,150); //eighth building fill(51, 51, 51); rect(225,225,10,120); rect(270,225,10,120); //building 8 arc(540,190,70,70,-PI*4/6,-PI*1/6,CHORD); quad(523,159,523,325,570,325,570,172); for(int y=170;y<325 ;y+=5){ fill(106,106,71); quad(523,y,570,y+2,570,y+4,523,y+2); } //ninth building fill(51, 51, 51); quad(585,165,615,155,620,325,585,325); fill(31,30,72); triangle(614,155,622,158,619,325); for(int y=210;y<325 ;y+=5){ fill(106,106,71); quad(585,y,615,y-1,615,y+1,585,y+2); } for(int y=210;y<325 ;y+=5){ fill(64,64,34); quad(615,y-1,621,y,621,y+2,615,y+1); } //shore fill(69, 137, 163); rect(0,310,900,400); //mangroves for(int x=0;x<900;x+=20){ mangroves(x,310,10,10,3,28,5,255); //varying parameters for mangroves mangroves(x+10,305,8,8,6,41,8,255); mangroves(x+5,300,5,4,14,62,17,255); } } void cloud(int x,int y,int w,int h,int red,int green,int blue,int a){ fill(red,green,blue,a); ellipse(x,y,w,h); } //sets variables they're being created in void mangroves(int x,int y,int w,int h,int red,int green,int blue,int a){ fill(red,green,blue,a); ellipse(x,y,w,h); ellipse(x+5,y+5,w,h); ellipse(x-5,y-3,w,h); ellipse(x+3,y-5,w,h); ellipse(x-3,y+5,w,h); }
class Moon { int x; int y; int sizeMod = 0; Moon() { this.x = 60; this.y = 90; } void drawMoon() { int blue, green; //map mouseX to green and blue rgb values for moon green = int(map(mouseX, 0, width, 221, 250)); blue = int(map(mouseX, 0, width, 0, 205)); noStroke(); fill(255, green, blue); //map mouse X to rgb values for background/sky int bg_red = int(map(mouseX, 0, width, 83, 0)); int bg_green = int(map(mouseX, 0, width, 157, 0)); int bg_blue = int(map(mouseX, 0, width, 253, 0)); //map mouseX to variable sizeMod, starting at 0, ending at 20 sizeMod = int(map(mouseX, 0, width/6, 0, 20)); //width/6 divides canvas into 6, for each moon/sun phase if (mouseX <= width/6) { //sizeMod decreases size of moon, starts at 80, ends at 80 - 20 = 60 ellipse(x, y, 80 - sizeMod, 80 - sizeMod); } else if (mouseX > width/6 && mouseX <= 2 * (width/6)) { arc(x, y, 60, 60, HALF_PI, 3 * HALF_PI, OPEN); } else if (mouseX > 2 * width/6 && mouseX <= 3 * width/6) { ellipse(x, y, 60, 60); //draw two overlapping circles to give illusion of crescent moon fill(bg_red, bg_green, bg_blue); ellipse(x + 10, y, 50, 50); } else if (mouseX > 3 * width/6 && mouseX <= 4 * width/6) { ellipse(x, y, 60, 60); //can't figure out how to flip arc, just cover with rectangle fill(bg_red, bg_green, bg_blue); rect(x - 30, y - 30, 30, 60); } else if (mouseX > 4 * width/6 && mouseX <= 5 * width/6) { ellipse(x, y, 60, 60); //draw two overlapping circles to give illusion of crescent moon fill(bg_red, bg_green, bg_blue); ellipse(x - 10, y, 50, 50); } else { ellipse(x, y, 60, 60); } } void update() { x = mouseX; } }
class Star { int x; int y; Star() { //instantiate star with random x and random y values, every time you restart sketch it' random this.x = int(random(0, width)); this.y = int(random(0, height/3)); } void drawStar() { fill(255); ellipse(x, y, 1.5, 1.5); } }