Week 2 – Simple Art

I always liked Piet Mondrian’s art. Something about the lines and the geometrical shapes was satisfying. Although it is simple, I find his art, particularly his most famous work “Composition with Red, blue and yellow” to be one of my favourite art. I thought his art could be somewhat re-created with code so I decided to give it a shot.

 

Unlike its simplistic looks, creating this was much harder than I thought. At first, I just selected completely random vertical and horizontal lines. However, I quickly realized that in his work, the lines do not reach from one end to another. It sometimes fell short before reaching the total width or height of the canvas. Choosing random positions of the lines along with random lengths was not an easy process, so I decided to simple things out by controlling the lengths to a certain extent.

I made three rules. The first rule was to choose 2 verticals lines with spaces of at least 60 in between. If it wasnt for this, sometimes the vertical lines overlapped, or the distance between the lines fell so small that the outcome looked a bit ugly. The second rule was to controll the height of the vertical lines. The lines should start from 0, but the end point of the lines had to fall randomly between 60% of the height to the end. The last rule of the lines was to keep the distance between the horizontal lines to be atleast 80 pixels apart.

After setting these rules, I tried generating the lines. However, I was soon met with another problem. The horizontal lines did not intersect perfectly with the vertical lines. So to prevent this, I just placed horizontal lines where the vertical lines ended. I also decided not to play around with the lengths of the horizontal lines to keep things simple.

//the key function that chooses the lines drawn on the canvas
  function pickRandomWithSpacing(minVal, maxVal, existing, spacing) {
    for (let t = 0; t < 300; t++) {
      //first it chooses a random candidate in selecting lines.
      //usually selects lines from 0 to either height or width, this is saved as candidate
      const candidate = random(minVal, maxVal);
      let ok = true;
      //now we assume that this is a valid space, and try to check if the distance between the previously selected line and e has enough space.
      for (const e of existing) {
        //gets the previously selected value,
        if (abs(candidate - e) < spacing) { //checks if the distance is valid
          //if not, break the loop
          ok = false; 
          break; 
        }
      }
      if (ok){ //if the distance is valid, we found the valid line.
        return candidate;
      } 
    }
    return null; //if we couldnt find it, give up finding to avoid beig stuck in loop
  }

 

The key part for this artwork was randomly choosing the lines in a sort of a controlled manner. If it was chosen completely randomly, it would not look like the orignal art so I had to make some working boundaries. This is the function called pickRandomWithSpacing. It takes 4 variables: minVal, maxVal, existing, spacing. Line needs two points. The starting point of vertical line is chosen from a ranges 0 to width and is saved in array called verticalX with space of 60. The end point of vertical line is chosen from ranges 60%of height to height and is saved in array called verticalEndYs with spacing of 80. The idea of trial and error is applied when finding the correct spacing. When we first choose the space, we assume that it follows the rules that I made. However, it checks if the spaces are correctly picked. If it does not follow the rules, it breaks the loop and chooses another random space which hopes to follow the rule. It ensures that it finds the correct working spacing by repeating the loop 300 times.

This is an example of how its called

//pick two valid vertical lines
  for (let i = 0; i < 2; i++) {
    //we use the function that we created. from 0 to width, saved in arraynamed verticalX with spacing 60.
    let x = pickRandomWithSpacing(0, width, verticalXs, 60);
    verticalXs.push(x);

    //yEnd is the end value for the vertical line, I wanted to give it a end to the length of it. The vertical lines start at 0 but is randomly chosen when to end. The minimum is 60% of the height, all the way untill height. These values are saved in array calkled verticalEndYs
    let yEnd = pickRandomWithSpacing(MIN_VERTICAL_LENGTH, height, verticalEndYs, MIN_Y_SPACING);
    verticalEndYs.push(yEnd);
    
    //this pushing is key in finding the cells to color. It saves the coordinates of the lines created in order to select the different sized cells
    verticalLines.push({ x1: x, y1: 0, x2: x, y2: yEnd });
  }

 

After the lines were correctly chosen, the next part was correctly identifying the cells created. Since I saved all the nessasary points of the array. I went through several trial and error sessions to identify the cells. I found that there were 9 cells when I applied the rules and focused on finding the cells generated with the random lines. This was much more complicated then I thought because the cell sizes of x and y are completely different and unique. I had a notebook with me that kept track of the coordinates. The key point about identidying cells was finding out with points to skip. When the vertical lines fall short, when identifying the cell that does not include that particular vertical line, it needs to skip it. I was stuck on this for a long time and received advice from openAI on the logistics of it.

The rest of it was easy. I had to pick random colors from the color pallete that I chose. (The color pallete from the original work).

As you see here, I repeated null three times to increases the chances of white rectangles. This is because the original artwork contains more background than the colored ones.

Lastly, I drew the lines on top of the colored rectangles to create the final look.

For future improvements, I can apply random horizontal lengths so that not all horizontal lines reach from one end to another. Also I can also apply controlled randomization in choosing the colors instead of my complete randomization that I have now with colors. In the original artwork, when the color is chosen, the same color should not be next to each other. However, for simplicity I allowed this.

 

Leave a Reply