Week 2 Loop Assignment – Joy Zheng

Concept

My concept for this work came from an in-class moment. When Professor Mang was demonstrating looping horizontal and vertical lines, my eyes were tricked into seeing illusory diagonal lines that weren’t actually there.

After chatting with a psychology major friend who is taking a course on visual perception, I learned this effect is called optical illusion (our brain “fills in” missing shapes or creates illusions). She also introduced me to a set of famous illusions, and I was especially fascinated by the Cafe Wall Illusion, where parallel lines look slanted (not parallel as they really are) when black and white tiles are offset. I decided to recreate that illusion using nested loops, because it is simple yet powerful in showing how math and art can merge to create perceptual and artistic effects.

The effect turned out to be amazing. You can actually feel the tiles appear sloped when you look at them from a certain distance. I noticed that the illusion doesn’t work really well when you are too close.

Embedded sketch

The interactivity of p5.js also inspired me to experiment with different ways of breaking the illusion, so I found that adding bold lines between the tiles is a surprisingly effective method.

A highlight of some code that you’re particularly proud of

My favorite pieces of code are the row offset logic and interactive show lines feature:

for (let y=0; y<rows; y++) {
  //all even rows' first tile was pushed half way in   
    let offset = 0;
    if (y%2 == 1) {
      offset = tileSize/2;
    }
    //for every column
    for (let x = 0; x < columns; x++) {
      //all even row tiles are white
      //all odd row tiles are black
      if (x%2 == 0) {
        fill(0);
      } else {
        fill(255);
      }
      //create tileSize tiles
      //created half way in when it's on the even row
      rect(x * tileSize+offset, y * tileSize, tileSize, tileSize)
    }
    
  }
  //display the breaking illusion lines when clicked
  if (showLines) {
    fill(150);
    for (let y=1; y <rows; y++) {
    rect(0, y*tileSize, width, 5);
    }
  }

This small conditional offset, embedded in a loop, shifts every other row half a tile, which is what makes the illusion possible. The most basic function of showing lines gives me the immediate initiative to stop the illusion. I specifically love these parts because it shows how a very minimal algorithm can have a huge impact on the final visual. Without it, the grid reverses back to ordinary.

Reflection and ideas for future work or improvements

This project inspired me to think about how simple loops and conditions can recreate complex psychological effects. It reminded me that coding is not only technical but also artistic—it can play with human perception in surprising ways. In the future, I would like to expand this piece by making the illusion interactive: for example, letting the user adjust the tile size or the offset with a slider, or animating the tiles so that the illusion shifts dynamically. I would also like to try building other illusions, like the Zollner illusion or the Kanizsa triangle, to see how far p5.js can push visual trickery.

Week 1 Self-portrait Joy

Concept

I started the idea of pixel art with this piece of wooden pixel art that we mentioned in our first class(Wooden Segment Mirror). I’m also recently obsessed with Perler Beads(plastic fusible beads to form patterns and fuse together with an iron). So, I pixelated one of my self-portraits and created a canvas of 10 * 12 colored squares.

To make it more interactive, I also use the mouseClicked function to add a more immersive version to get rid of the pixel stroke.

Code Highlight

I’m particularly proud of the color list. When I just started, I wanted to do an automatic color picker program to create the list for me. However, after a few trials, all the available auto ones cannot handle many colors, either giving a fake hex code or a single palette with a maximum of 10. Then, I did some research on manual color pickers, and I found this one(https://colorpickerfromimage.com/) to be the best hex color picker shortcut among all. Since I had to manually picking up all the colors, it also pushes me to optimize other parts of my code to use less repeated manual calls but using the loop to create all the squares.

let colors = ["#9194a6","#7d7d8f","#c29c8e","#e8bc9e","#ebbe9e","#dcac8c","#a38572","#5b585a","#5b585a","#c0cc66","#767787","#736f79","#c19a88","#e7b691","#edbb93","#daa884","#a5846d","#5b5350","#685d56","#dfe1b5","#676672","#6c6266","#ab8273","#ab8273","#e5af83","#927466","#7c6258","#544944","#665a52","#bea7a9","#5c5258","#6c5554","#a17d68","#db9f7e","#e8b08a","#5e4540","#785145","#544139","#665c56","#cecccf","#5c4b4a","#b57b64","#de9b79","#e5aa8a","#e6a68d","#d09375","#c18067","#5c443a","#6a5c57","#ccc7c9","#674e46","#cd8e6a","#eaa67d","#e1a286","#e7ab93","#e6a880","#d8946e","#5c4035","#544b47","#cdcdd3","#543d36","#d7996a","#e9ae7e","#e0a17b","#d08b5d","#e0a46d","#d39560","#3b2922","#49423b","#ccc7c4","#372623","#c28b5c","#d5936e","#c6735c","#c67255","#d59761","#7f5535","#34231c","#3a2c23","#625c43","#33221e","#644430","#e4a976","#da8667","#da7c5e","#af794d","#341d13","#39261d","#3b281e","#3b281e","#39251e","#5d402d","#d29e74","#d59d6d","#a6754b","#2b1810","#2b1b14","#422c1e","#4c3626","#28190a","#4d372d","#694735","#d09c74","#d29d72","#7c593e","#362822","#3a2b24","#442f21","#78614d","#4d3b26","#4e382f","#6a4833","#d69a74","#c99874","#49362d","#2f221f","#3c2f2b","#402d20","#876e51","#83735c"]

I also think the way p5.js displays these hex codes is another piece of art that breaks down the color of me into hex code pieces.

Reflection

For my future works, this work reminded me the importance of planning before starting. Digital art is a more well-planned process compared to free-form drawing on papers. This time, I began by creating all the squares manually, but soon I realized how redundant that was. So, I turned back to a draft note to jot down the ratio calculations. Overall, the process of choosing colors and planning turned out to be quite meditative.