Assignment 3 – Generative Art

Concept

Last semester, I was doing my study away in New York and when the semester ended, I decided to travel to the other end of the country to San Francisco, because why not. While I was there, one of the many places on my checklist was the Golden Gate Park. Inside it was a Japanese Tea Garden. It was one of the most aesthetically pleasing and peaceful places I have ever been. One of the many things I really liked about that tea garden were the unique Japanese trees that it had, and so, as a small tribute of remembrance, I tried to make a Japanese tree of my own for this project.

Implementation

I started off by making the basic shapes for the background. I placed the rectangles for the window, pot, sky, wall and circles for the moon. The main part however, were the leaves. To keep it simple, I made a very basic Class for a circular leaf and then went on to add the functions for its movement and appearance. the idea I had was to fill up different clusters of leaves for the tree. I made three clusters or regions of leaves, each having their own set of leaves. The leaves would fall from the clusters in a random fashion and subsequently be deleted from the array when they exit the canvas from the bottom. I also decided it was a good idea to make use of noise for the first time to make the fall seem more natural. So I went on and added noise in the x-direction while making the leave travel downwards simultaneously.

However straightforward this may seem, I encountered quite a few bugs along the way and thankfully managed to resolve them. I will share the significant ones here.

Positioning the Leaves

I started off by creating the x0 and y0 coordinates for the center of the cluster where the leaf object would be. I also specified the clusterWidth and clusterHeight in the leaf’s constructor. The initial position of the leaf was placed randomly in the cluster by selecting a random position in the rectangular area bounded by it:

class Leaf {
  // x0 and y0 specify the center of the cluster of leaves (one of the 3 clusters)
  constructor(x0, y0, clusterWidth, clusterHeight) {
...

Following this, I found out that I had to use a separate variable to store this initial x-position since I was making use of noise in the move() function of the leaf’s class. I couldn’t add the xPos variable to itself to update its value since that would enlarge it too abruptly inside the draw function thanks to the noise() function. It took me quite some while to figure this out as this wasn’t a very straightforward bug, but I eventually got there:

// using a separate variable for the initial position of x since xPos will
    // always be changing in draw() and this will cause abrupt behavior in the
    // leaf's x-movement if used along with noise inside move()

    // positioning initialX, xPos, and yPos within the cluster
    this.initialX = random(x0 - clusterWidth, x0 + clusterWidth);
    this.xPos = random(x0 - clusterWidth, x0 + clusterWidth);
    this.yPos = random(y0 - clusterHeight, y0 + clusterHeight);

...

// for the leaf's falling movement
  move() {
    // only make the leaf fall if the fall attribute of the object is true
    if (this.fall) {
      // giving some noise in the x direction to give a natural feel while falling
      this.xPos = this.initialX + noise(this.xoff) * 100;
      this.xoff += this.xincrement;
      // incrementing y to make the leaf fall vertically
      this.yPos += this.ySpeed;
    }
Removing the Leaves

Since I was keeping a check both on whether a leaf is alive or not and whether it is falling or not, I had to implement both of these concurrently. For instance, if a leaf reached the end of the canvas and it got deleted from the array, the code that randomly chooses a leaf to fall would not know whether the leaf is alive or not and could encounter an empty object. So I added a check for whether the leaf is alive before making it fall and it fixed the bug that I was facing. Moreover, if the leaves[] array becomes empty, the random(0, leaves.length) would return zero and that would cause an error again since the element at index zero doesn’t exist. So I added a check for that as well:

// choosing a random leaf to fall every 20 frames

  // if the leaves[] array becomes empty, it causes an error because the length is 0 but
  // the 0th element doesn't exist anymore so we provide a check for that as well

  if (frameCount % 20 == 0 && leaves.length != 0) {
    // choosing a random leaf index to make it fall from the tree
    index = int(random(0, leaves.length));

    // check if the leaf at the random index is alive and present inside the array
    if (leaves[index].alive) {
      // if yes then make the leaf fall
      leaves[index].fall = true;
    }
  }
Randomizing Leaf Color

At first I tried to do this within the Leaf class itself but then I realized that if I choose the color inside the draw() function of the Leaf class, it would cause the leaf to change color continuously because the draw() function loops continuously. I couldn’t place the array inside the standard draw() function either for the same reason. So I came up with the idea of creating a global array that would store the two leaf colors (shades of purple) and then choose the color inside the attributes of the leaf class as a this.color attribute:

// array which stores the two shades of purple for the leaves
let leafColors = ["#963990", "#4B2454"];

class Leaf {
  // x0 and y0 specify the center of the cluster of leaves (one of the 3 clusters)
  constructor(x0, y0, clusterWidth, clusterHeight) {

...

    // choosing a random shade of purple from the two specified in the global array
    this.color = leafColors[int(random(0, 2))];
  }

...

// drawing the leaf
  draw() {
    noStroke();
    fill(this.color);
    ellipse(this.xPos, this.yPos, this.width, this.height);
  }

Reflection

I feel like I managed to get the kind of aesthetic feel I was going for in this assignment. The color combinations worked really well and the tree stood out within a minimalistic background without being too overwhelming. I went for a kind of peaceful and calm feel and the falling leaves did well to prortray that feeling as well. It was unfortunate that I had to start from scratch after losing progress mid-assignment but gladly I was able to recall the functions I made and how I implemented them. It was disheartening at first but after putting in some extra hours I was able to remake the project exactly how I wanted to in the first place. As for the future, I would definitely like to save my progress often and make the habit of hitting the save shortcut from time-to-time, although it sounds trivial but its something i would definitely like to work on. Excited to see what I can do with transformations for our next assignment!

 

Assignment 2 – Creative Piece

Concept

Initially, I thought of making something with lines and creating some sort of an illusion. Then I remembered something I saw in Brooklyn’s Botanic Garden during my study away. It was a series of lights in lines converging into one single point. It looked amazing in the dark and I was really inspired by its pattern, so I thought of recreating it.

I feel like the pattern came out exactly as I wanted it to be, maybe even better because it changes color based on the position of the mouse. Once I was done with the lines, I made triangles to give a 3D effect so it seems like the pattern is inside a cube.

Implementation

I had to think quite a lot about where to place the lines and where to converge them to give the illusion effect. Especially since we had to implement the pattern using for loops, I had to think about where I had to place the “i” to change the position of the lines in the way I wanted.

The two main sections of my code are where I implemented the for loops for the changing-color lines and for the top and bottom triangle patterns.

The first one for the changing-color lines is below:

// creating a for loop for the changing line patterns on the left and right
// loops till the width in steps of 5, the steps define the spacing between the lines
for (let i = 0; i < width; i = i + 5) {
  
  // changing color patterns, increase mouseX for more red and increase mouseY for more green
  stroke(mouseX - random(255), mouseY - random(255), random(255));
  
  // dividing pattern into two halves (left side and right side) and making separate lines for each
  
  // left half
  line(0, i, mouseX, mouseY);
  
  // right half
  line(width, height - i, mouseX, mouseY);
}

I played around with the color-changing part until I was satisfied with the color combinations I achieved. The lines were made in two parts, the left half and the right half. This gave a triangle effect (two triangles on the left and right changing colors) without actually creating triangles. The starting points for the lines were changed using the for loop and the ending points were always the mouse position.

The second one for the top and bottom triangle patterns was done using the following for loop:

// making a for loop for white triangle patterns on top and bottom
for (let i = 0; i < width / 2; i = i + 10) {
  noFill()
  stroke(100)
  
  // one point on the top left half of the canvas, one point on the mouse position, and another one
  // on the top right half of the canvas
  triangle(i, 0, mouseX, mouseY, width - i, 0)
  
  // repeating procedure for triangles on the bottom half
  triangle(i, height, mouseX, mouseY, width - i, height)
}

I achieved this pattern by dividing the width into two halves (left and right sections) and then looping to make triangles from left to right. The converse was done from the right-to-left half as well. This gave me the white triangles that move based on the mouse position.
 

Reflection

I feel like I achieved exactly what I was going for in this assignment and the pattern turned out to look quite visually pleasing. I had the chance of showing it to my friends as well and getting their feedback and I subsequently added the triangle patterns on the top and bottom right after. Next time, I would like to use the mouseClicked() and keyPressed() functions to add even more user interactions.

 

Self Portrait – Abraiz

Concept

My sketch is inspired by something that is a big part of my life – Tennis. I could go hours and hours watching or playing it and not even notice the time pass by. The reason I love this sport so much is that it gives me a chance to escape from my stressful and work-intensive routine and not think about anything besides hitting the ball and feeling the satisfaction of it smacking against my racket strings :p

So I thought why not make a self-portrait of me holding a racket on a tennis court while juggling a ball on it.. indefinitely 🙂

Implementation

I tried to play around with shapes as much as I could and place them until they were in the right position. However, some things like making the ball bounce and creating the net in the background are worth mentioning here.

To make the ball bounce, I created a variable called ballSpeed and added it to the y value of the ball inside the draw() function to make it move. However, to keep it inside certain bounds, I made use of an if statement and as soon as it reached one of the bounds, I reversed the direction of the ballSpeed variable, this made it “bounce” within certain bounds.

fill("#AEDA38");
ellipse(x + racketOffsetX, y + racketOffsetY, 30, 30)

// make the ball rebound within a certain area
if (y <= 350 || y > 390) {
  ballSpeed = -ballSpeed;
}

y -= ballSpeed

For making the net, I used a simple for loop to make horizontal and vertical lines. This saved me a lot of time and I feel it was worth mentioning here.

// vertical lines of the net
stroke(10);
strokeWeight(1);
for (let i = 0; i < 50; i++) {
  line(10 + 10*i, 207, 10 + 10*i, 275)
}

stroke(10);
for (let i = 0; i < 8; i++) {
  line(0, 207 + 10*i,  width, 207 + 10*i)
}

Reflection

I found this homework more of an activity than an assignment because I enjoyed every moment of crafting it and making it come to life. I wanted to implement a lot more things, like making the scene transform into one where I would be holding a frying pan in place of the racket and wearing a chef’s hat in place of the tennis cap with a kitchen in the background (yes, I recently discovered that I have a thing for cooking). The ball could be an egg or a pancake maybe? Time was my biggest enemy for this idea but I would love to implement this sometime in the future. I would also love to add live interactions to my projects next time where the user can interact using clicks or button presses to make the experience more immersive.