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);
}
}