Week3: Generative Artwork

Concept:

When I was watching the video from our first reading assignment, I came across one of the speaker’s demonstrations where he explained, while generating a maze (image below), that incorporating randomness into art allows the audience to come up with their own conclusions using their own imagination. I truly think that is the beauty of art.

He also mentioned that the same, ordinary structure produces only a single meaning, and I believe is not the point of art. Art is about subjectivity, and I wanted to achieve this by introducing randomness in this assignment. That is why I created an artwork that automatically generates a maze for you to solve. Every time you run the code, you get a different maze so you can enjoy it in a new way each time rather than solving the same maze again and again. Try solving my maze below!

Part of code I’m proud of:

It was pretty hard for me to do it from scratch so I searched for a tutorial video on YouTube. From the video ( https://www.youtube.com/watch?v=jQFYh3nRfSQ ), I was able to learn how stack and class can work together to keep generating paths and filling out all the grids of the canvas. I am especially proud of this mazeIterate() function, which is the most fundamental part of this project. It basically allows you to find an unvisited neighbor that is connected to the grid you are currently standing on. I had to be careful when marking the wall between the current grid and the neighbor grid, because that wall is shared by both of them, meaning that the interpretation from each side is different. Specifically, I created another function called oppositeBlock() to make sure that the same wall is marked as open from the opposite side as well. I was also able to use a stack properly to push the current grid back onto it so that we can return to it when we hit the dead end. 

//function to search for and go to the next tile 
  mazeIterate(){
    let currentGrid = this.stack.pop(); 
  
    let connectedWall = this.pickNeighbor(currentGrid); //find unvisited neighbour that connects with the current tile
    
    if (connectedWall){
      this.stack.push(currentGrid); //put the current tile into the stack so that you can come back when you hit the dead end 
      
      connectedWall.grid[connectedWall.block] = "open"; //mark the wall as open 
      
      currentGrid[oppositeBlock(connectedWall.block)] = "open"; //mark the opposite wall (the same wall) as open 
      
      connectedWall.grid.visited = true; //mark it visited 
      this.stack.push(connectedWall.grid); //push the tile to the stack 

      currentGrid.current = false; 
      connectedWall.grid.current = true; 
    } 
    else if (this.stack.length != 0){ //if there are no neighbors left, 
      currentGrid.current = false;
      this.stack[this.stack.length - 1].current = true; //move back to the previous tile to seek for unvisited neighbor 
    }
  }

Problems I ran into:

I forgot that I needed to mark the border grids as visited at the beginning. This issue was tricky, because if I didn’t do it, the maze would grow outward and go out of bounds. In order to fix this issue, I restricted the boundary by marking all the grids at the border as visited in the constructor so that we can only generate the maze inside our canvas. 

Reflections & Future Improvements:

I am very satisfied with the outcome because I was able to incorporate randomness into my artwork. The learning process took a lot of time because I had to understand how to automatically generate a maze from the tutorial video. However, it was very beneficial for me overall because I was able to reflect upon how to use an array and a class to generate the maze automatically. I think I was able to fully apply all of the concepts we have learned in class so far, so I am very satisfied. For future improvements, I definitely need to work on my comments and variable names, as they are a bit messy right now. But for this assignment, I think my comments would be good for everyone to understand how each part of my code works. 

Week 3 – Functions, Arrays, and Object Oriented Programming

Sketch

My Concept

For this project, I wanted to create a generative artwork inspired by an Instagram post I saw of a supernova made entirely with math. I was amazed by how something so natural and powerful could be represented through math and wanted to make my own version with code. I used object-oriented programming with classes and arrays to build a layered system: a static star field in the background, a clustered supernova core in the middle, and orbiting particle systems that appear when the mouse is clicked. The ParticleSystem class contains Particles as a sub-class for abstraction. The goal was to make the scene feel cosmic and expansive, with a balance of stillness and motion. The pink and orange hues of the supernova give it warmth and contrast nicely with the dark sky and moving particles.

Post Link

Code Highlight

My favorite part of the code was inside the Particle class. The update method receives origin which are the coordinates of the particles superclass, ParticleSystem. It then increments the the particle’s angle, which was set in the constructor to a random angle, by an also randomized angular velocity between 0.005 and 0.008. After that, I used trigonometry to convert the current angle and radius to x and y coordinates. These 3 lines of code are so simple, yet do very well in creating a smooth orbiting effect with any radius and speed.

// Update the particle's position
 update(origin) {
   // Orbit motion
   this.angle += this.speed;
   // Translate motion on x and y
   this.pos.x = origin.x + cos(this.angle) * this.radius;
   this.pos.y = origin.y + sin(this.angle) * this.radius;
 }

Reflection

Seeing the Instagram supernova showed me how math and code can express phenomena far beyond what we normally imagine drawing. Recreating my own version made me realize the power of classes in producing natural-looking patterns with surprisingly little code. What looks like thousands of unique particles is really the same rules repeated again and again, with variation coming from randomness and simple math. I also found that changing small details (like the radius range of the orbits or the color palette) transforms the entire mood of the scene. For me, this project reinforced how generative art is about designing systems of rules that unfold naturally into complex and beautiful results.

Week 3 Reading Reflection

Reading Chris Crawford’s first chapter on interactivity reshaped how I think about what makes a system truly interactive. At first I believed that something as simple as reacting to an input was enough. For example, when you open a refrigerator and the light turns on, I thought of that as interactivity. Crawford’s model of listening, thinking, and speaking challenged this assumption. He showed that real interactivity is more like a conversation, where input is not only noticed but also processed and answered in a meaningful way. This made me see that many things I used to count as interactive are really just reactive, because they skip the step of thinking.

This idea also helped me reflect on my own coding work. In my self portrait sketch, the eyes follow the mouse and the mouth curves up or down depending on mouseY. At first I was satisfied with these features because they give the impression of interaction, but after reading Crawford I realized that they are closer to one-way responses than to genuine dialogue. The system is listening and speaking, but it is not really thinking about how to respond. That missing step makes the interaction feel mechanical rather than conversational. I started to recognize that stronger interactivity requires the program to interpret or evaluate the input, not just mirror it back in a predictable way.

Looking ahead, I want to design sketches that create a deeper back-and-forth with the user. One improvement would be making more features react to user input. But, instead of only reacting in fixed ways, the program could process input in a way that gives the impression it has some awareness or personality. For example, rather than the mouth always curving in the same manner based on mouse position, the system could shape its response in ways that feel more expressive or varied, like how a person reacts differently in different contexts. This would give the user a sense that their actions are acknowledged in a meaningful way and make the interaction more engaging.

Assignment 3 –Generative Artwork Object-Oriented Programming

Concept + references

For this artwork, I was actually inspired by the composition of Still-life, a genre of art in which the artist focuses on applying an outstanding level of detail to an arrangement of everyday objects. One of the most popular choices for this genre are the paintings of fruit, which I decided to feature in my work. However, I decided to display these with their most fundamental structure, lacking any of the depth or level of detail found within the Still-life. After this, to exercise the use of the arrays, and object-oriented programming, using as inspiration one of the array functions I found in the section of Array Functions on p.5 j.s tutorials, I decided to create a trail for one of my favorite fruit, the watermelon.

Array functions

Highlight code

Although the watermelon trail is the most eye-catching, interactive, and unique code in this entire work, the code I am actually most proud of are the ones that make up the functions for my fruit. It was fun to create these functions and later simply add the berry(x coordinate, y coordinate) under the function draw() as well as for the apples, since not only did this process make it easier to make multiple copies, but it was nice to see objects of my own creation as part of the objects as if they were another primitive shape we can use whenever we want.

function apple(x,y){
  fill(200,40,50);
  ellipse(x,y,35,35);
  fill(0);
ellipse(x-1,y-10,10,8);
  //stem
  fill(50,190,40);
  rect(x-3,y-25,4,15);
 
}

function berry(x,y){
  fill(70,40,190);
  ellipse(x,y,15,15);
 
}

 

Embedded sketch

 

Reflection and ideas for future work or improvements

Although I am happy with the results, I wish I could understand more properly how the function of the trail works so I could make it smoother even if I move the mouse faster. Also, I would like to learn how to make more than one form of interactivity at a time, since I also wanted the rest of the fruit to fall down the canvas while the watermelon remained interactive for the viewers. Despite this, I learned the advantages of creating one’s own functions, how arrays can provide a a¿variety of  interactive outcomes, and how all of these elements compliment each other to make the final piece more engaging.

Week 3 – Reading Reflection

The Art of Interactive Design, Ch. 1 by  Chris Crawford

Throughout the text, Chris Crawford emphasizes that interactivity requires three essential components: listening, thinking, and speaking. He illustrates this by presenting multiple examples where these elements are absent, such as reading a book, dancing, or watching a movie. I find this argument compelling, and agree when he highlights that certain situations, subjects, or objects cannot be considered truly interactive. The three conditions and examples highlighted by Crawford also resemble my own experiences in conversation. Usually, a conversation doesn’t really feel like an interaction if both parties aren’t engaged and responding. In fact, if one of the “actors”, as Crawford describes both participants in a conversation, is not thinking, listening, or speaking in response to the dialogue started by the other person, this situation might as well be like the one with an individual reading a book, an inanimate object that in spite of all the knowledge or information it contains, does not reply back. 

This perspective becomes even clearer when I connect it to the coding concepts we have studied in class. A function not only interacts with variables and other elements of code to produce a visual animation or design, but each act of writing code itself is a form of interaction. In this case, the interaction arises from thinking and analyzing what is needed to structure the code, determining the requirements for it to function, and then writing it out. The system, in response, processes my input and responds to my actions, whether by successfully executing the program or by pointing out an error.



Although our current application of different technologies might be limited to a certain extent, Crawford’s argument has led me to wonder if there is a way to make non-interactive objects interactive. This draws my attention to the example of the book and makes me want to find a way in which a book can respond to our thoughts and opinions and response with enough intellectual and complexity to regard it as a form of interactivity. 

The Art of Interactive Design, Ch. 1

After reading “The Art of Interactive Design” by Chris Crawford, I found it really interesting how he critiques common ideas about interactivity, continuously giving examples while showing why something might initially seem interactive but then explaining why he disagrees. Each time he explains a concept, I think to myself, “Yes, I see this as interactive,” but then he challenges that assumption in a way that convinces me to see it differently. It made me wonder: is interactivity utterly subjective? Can something be called interactive if it only engages one age group, or does it have to be recognized as interactive by most people? Crawford suggests that we can think of interactivity as high, moderate, or low, rather than a simple yes-or-no quality. Interactivity, in his view, is about change, not stagnation; it’s about creating a system that can evolve and respond in better ways, rather than just maintaining the same thing. Like he said, “You can turn up the reaction volume as high as you want, but playing Beethoven’s Ninth Symphony at 20,000 watts does not make it a painting.”

I believe the characteristics of a strongly interactive system are when it is capable of change, not permanent or fixed, and when the person interacting with it can contribute their own personality to the process. I like how he breaks interactivity down into listening, thinking, and speaking; all three need to happen for it to feel real. If one of these is missing, it doesn’t work, just like a conversation falls apart if one person isn’t really listening. Movies, books, or even some games might seem interactive at first, but they fail because they mostly just speak; they don’t listen or think about the user’s input. For me, interactivity is about creating a space where the user can engage fully and shape their experience, making it personal and dynamic. The system isn’t just reacting; it’s part of a back-and-forth process, and that’s what makes it strong and meaningful.

To improve the degree of user interaction in my p5 sketches, I think the key is to make the sketches more responsive to the user’s actions and give them a sense of control over what happens.  For example, I could let users influence multiple aspects of the sketch at once, like color, shape, and movement, so their choices feel meaningful. I could also let the user control some actions from the sketch, like giving them options to choose whether they want one interactive response or another. Later on, when we learn how to include sound features, I could make sketches that track the mouse or input sound continuously and adapt dynamically, rather than only responding at specific moments—which I know might take a long while for me to figure out and really learn how to use.

Week 4 – OOP and Array

References and Inspiration

This project was inspired by sunsets, specifically their color transitions from yellow to orange and purple. These colors were used to design the gradient effect in the particle trails. The movement of the particles was influenced by the idea of natural flows and atmospheric motion. On the technical side, the code was built in p5.js using established techniques such as Perlin noise flow fields and particle systems, which were adapted to fit the chosen sunset theme.

Pink Sunset Color Scheme - Image Color Palettes - SchemeColor.com

Embedded Code

//this is our particle class responsible for each line of perlin noise
class Particle {
  constructor() {
    this.pos = createVector(random(width), random(height)); //randomly positioned
    this.vel = createVector(0, 0);
    this.acc = createVector(0, 0);
    this.maxSpeed = 2; //limit to how fast the particle moves
    this.prevPos = this.pos.copy(); //saves the previous/latest position of the trail 
  }

  update() {
    this.vel.add(this.acc); //alowing the vleocity to change based on the acceleration 
    this.vel.limit(this.maxSpeed); //limting the speed
    this.pos.add(this.vel); //change position based on the velocity 
    this.acc.mult(0); //reset accelration so it foes not increase infintely 
  }

  applyForce(force) {
    this.acc.add(force);
  }

  follow(vectors) {
    let x = floor(this.pos.x / scl); //getting the position of the particle x and y 
    let y = floor(this.pos.y / scl);
    let index = x + y * cols; //makingt he 2d grid into 1 d for indexing
    let force = vectors[index]; //access the vector at index
    this.applyForce(force); //apply the perlin noise
  }


  show() {
    // Sunset gradient colors
    let t = map(this.pos.y, 0, height, 0, 1);

    // Top → yellow, middle → orange/red, bottom → purple
    let topColor = color(255, 200, 50, 30);    // golden yellow
    let midColor = color(255, 100, 50, 30);    // deep orange/red
    let bottomColor = color(180, 60, 160, 30); // magenta/purple

    
    
    let c; // c is the chosen "sunset color"
    if (t < 0.5) { c = lerpColor(topColor, midColor, t * 2); } else { c = lerpColor(midColor, bottomColor, (t - 0.5) * 2); } stroke(c); strokeWeight(1.5); line(this.pos.x, this.pos.y, this.prevPos.x, this.prevPos.y); this.updatePrev(); } updatePrev() { //updating to make sure that the trail starts from the current positoin for the next/continued oaeticle this.prevPos.set(this.pos); } edges() { //limit particles ot stay within the frame if (this.pos.x > width) {
      this.pos.x = 0;
      this.updatePrev();
    }
    if (this.pos.x < 0) { this.pos.x = width; this.updatePrev(); } if (this.pos.y > height) {
      this.pos.y = 0;
      this.updatePrev();
    }
    if (this.pos.y < 0) {
      this.pos.y = height;
      this.updatePrev();
    }
  }
}

Concept:

In my p5.js sketch for this week, I mainly use a particle system where many small points move across the screen, each leaving a trail. Their movement is controlled by a flow field, which is simialr to an invisible grid of arrows that points the particles in the direction they should move in. The directions of these arrows are created with Perlin noise, which makes the movement look smooth and natural instead of random. Each particle updates its position based on the flow field and avoids the mouse when it gets too close, adding interactivity. To match the sunset theme, the particles are colored with a gradient that changes from yellow to orange to purple depending on their vertical position on the screen.

✨Sunset on the Beach ✨

Problems I Ran Into:

I had to review the previous Decoding Nature slides in order to refresh my memory on the concepts like flow field and perlin noise, and particles leaving a trail. So although it was not exactly a “problem” I had to readjust some parameters and play around with the values of certain parameters to remember what they were responsible for.

Embedded Skecth:

Reflection & Future Sketches:

I plan to incorporate more of the concepts taught in decoding nature to the weekly sketches.  I also want to focus on the creative elements and aspects of the sketches.Looking ahead, I want to experiment with making the particles react to more external inputs, such as sound or keyboard interaction, to create more dynamic sketches.

 

Reading Reflection:

When readings Crawfords piece I noticed that he mainly focused on three elements that make strong creativity: Listening, Thinking, and Speaking. By listening he means the system should be able to “capture” or “record”. Not only that but to accurately respond to certain triggers, whether it would be accurately through time, as in instant reaction, or accurately respond in an area specifically clicked on through the mouse.

After reading the piece, I have a few ideas for future sketches that will enhance the interactivity. For example, I want to start integrating all the Listening, Thinking, and Speaking elements cohesively so that the user does not have to be told that the piece is interactive- the piece speaks for itself. For instance, if my sketch has audio interaction or mouse interaction, I want the interactive element to shine through and to be the main focus rather than just an addition..

Creating Interactive Visuals with p5.js | Cratecode

 

Reading Reflection – Week 3

Chris Crawford compares interactivity to two people holding a conversation, where each listens and responds, and that back and forth creates something dynamic. Before reading this, I hadn’t really thought deeply about what makes a system truly interactive, and Crawford’s explanation really clarified it for me. I agree with him because a strongly interactive system is one where the user’s input can meaningfully change the outcome, rather than just triggering a predictable or surface-level reaction. That’s when interaction feels real.

For my own p5 sketches, I’ve thought about ways I could improve the interactivity in them. Instead of just clicking to trigger something to happen, the sketch could react differently depending on the type of input, like how long you hold a key or how fast your mouse is moving. This would make the artwork/program feel less like a machine following certain orders and more like an actual conversation between the user and the program.

Week 3 – Reading Reflection

Reading Chris Crawford’s chapter “What Exactly Is Interactivity?” made me rethink what I usually call “interactive.” Especially, now as I am taking 3 IM classes, and we often see the artworks and come to the term interactive, I have started to understand how truly important it is. After the reading, I realized that I often label something as interactive just because I can click or move something and it changes, but Crawford’s explanation made me see that real interactivity is much deeper than that. I really liked his comparison to conversation, it made sense that true interactivity should feel like a back-and-forth exchange where both sides “listen, think, and speak.” This idea made me reflect on my own p5 sketches and notice that, while they respond to user input, they do not necessarily feel like a conversation. They just react without much “thinking” or meaningful change based on the user’s action.

Speaking of 5p, the reading challenged me to think about how I can make my work more engaging and meaningful. I felt motivated to experiment more with giving my sketches some kind of “memory” or adaptive behavior so that the experience feels less mechanical and more like a dialogue. For me, a strongly interactive system is one where the user’s input actually matters and shapes the outcome in noticeable, sometimes unexpected ways. It should feel like the system is “paying attention” and changing its behavior based on what I do, rather than just executing a simple trigger. I think strong interaction also invites me to explore, experiment, and maybe even get surprised by the result.

After the reading, I had some ideas of how I can improve my interactivity of  p5 sketches. I could add elements that respond over time or evolve depending on how much and how often I interact. For example, instead of bubbles just appearing when I click (assignment 3 – OPP), I could make them “learn” from my clicks, maybe clustering in areas where I click often or changing colors based on patterns of interaction. I could also make my sketches remember past actions so that the experience feels continuous rather than resetting each time. I think, after this steps, it would move my work closer to what Crawford calls a real conversation between user and system.

Week 3: Generative Artwork

Concept

When I thought about what to do for this assignment, I started brainstorming and eventually decided to create a simple simulation of rainfall. I always found rain both calming and visually appealing, so I wanted to capture that feeling in my artwork.

Code I’m Proud Of

I’m proud of this code because I figured out how to make the raindrops disappear at the bottom of the canvas (when they reach the sea). At first, I used pop(), but it didn’t work the way I wanted it to: it would randomly delete all the droplets in the middle of the page. So I researched a bit and instead, used splice(), it deletes the droplets when they reach the bottom of the page and works perfectly!

//deletes raindrops after they reach the sea
if (raindrops[i].disappear()) {
  raindrops.splice(i,1);
  //splice removes/deletes the disappeared raindrops 
}

Here’s the artwork I created:

Reflection and Future Improvements

Overall, I’m happy with the way my rainfall artwork turned out. I especially liked learning how to use arrays with objects because it made me think more carefully about organization and how each part of the code connects.

If I were to improve this piece in the future, I’d probably add sound effects of rain falling, or even experiment with lightning and thunder for a more dramatic atmosphere. Another idea I had is to adapt the same logic to create snow instead, using different PNGs for different snowflake shapes. That way, the piece could feel more unique while still using the same object-oriented structure I implemented here.