Week 2- Maracas Beach

Concept:

As a true island girl, the beach has always held a special place in my heart. It’s not just one of my favourite places in the world; it’s where I find peace and calm. There’s something really magical about being at the beach at night—when the darkness hides your view, but you can still feel the water, hear the rhythm of the waves, and see the moon reflected on the surface. This inspired me to create an ocean scene for this project, with waves at the height of their movement, each with its own unique personality through acceleration.

https://www.youtube.com/watch?v=kT-f2mfNL7s

Embedded Sketch:

Key Features:

In my code, acceleration controls how fast the waves move. You can increase or decrease the speed by pressing the right or left arrow keys:

Pressing the right arrow increases acceleration, making the waves move faster.

Pressing the left arrow decreases acceleration, slowing the waves down.

The movement is smooth because acceleration gradually adjusts the wave speed rather than changing it instantly, making the effect feel more natural. This simulates a build-up or reduction in wave intensity, similar to real ocean waves building up momentum.

Highlight of Code:

One of the most rewarding aspects of this project was simulating the moon’s gravitational pull on the waves. I’m particularly proud of how I captured the subtle way the waves respond to the moon’s slow journey across the sky. The moon’s movement mimics the natural pull of gravity, affecting the height and behaviour of the waves as they interact.

// Slow down the moon's movement, simulating gravitational influence
moonX = map(noise(frameCount * 0.005), 0, 1, 0, width);  // Slow, subtle horizontal movement

// Slightly adjust wave height based on moon's horizontal position (gravity effect)
let gravitationalEffect = map(moonX, 0, width, -20, 20);  // Subtle effect
let y = noise(frameCount * noiseSpeed + i + j) * noiseHeight + noiseY + offsetY + gravitationalEffect;

Reflection and Future Work:

Though the project didn’t quite reach the full vision I had in mind, I’m proud of how it turned out. I originally hoped to simulate waves crashing onto the shore and to add more elements like sound and depth to the sketch. These are definitely areas I plan to improve on in future iterations, but I feel this piece captures the essence of the ocean that I love so much.

 

Falling Leaves in Autumn – Week 2

Concept

I’ve always enjoyed traveling to Europe during autumn. The sight of trees with almost yellow leaves fills me with a sense of calm and nostalgia. As I walk through parks and streets, the leaves gently falling to the ground create a serene atmosphere. Inspired by this, I decided to simulate the motion of falling leaves in my sketch. I wanted to capture how some leaves fall straight down due to gravity, while others drift to the right or left because of the wind. My goal was to recreate this natural motion using code, focusing on how gravity and wind impact the leaves’ movement.

Video Inspiration

I had initially hoped to use a video I took during my travels, but I couldn’t find one. So, I searched online and found a video that inspired this design.

Highlight of the Code

One part of the code I’m particularly proud of is how I simulate the wind and gravity forces. In the sketch, each leaf is given a slight variation in fall speed, which makes their movement feel more natural. Here’s a snippet:

 
// Loop through all the leaves and apply forces, update positions, and display them
for (let leaf of leaves) {
  // Apply gravity force to the leaf (fallSpeed controls how fast it falls)
  leaf.applyForce(createVector(0, leaf.fallSpeed * 0.1)); 
  
  // Random wind strength to add lateral movement (drift) to the leaf
  let windStrength = random(0, 0.05); 
  // Apply wind force in the direction determined by the leaf's drift
  leaf.applyForce(createVector(windStrength * leaf.drift, 0));

In this section, I applied gravity (downward force) and wind (side-to-side force) to each leaf. The random factor in wind strength and leaf drift direction gives the scene a more dynamic and organic feel.

Embedded Sketch

Reflection and Ideas for Future Work

Working on this sketch was both fun and calming. I was able to simulate the movement of the leaves quite effectively using acceleration, gravity, and wind forces. In the future, I’d love to add more interactivity to this simulation. For example, the wind could change based on mouse movements, or the leaves might react differently depending on where they fall. Another idea is to vary the leaf shapes or introduce different weather elements, like rain or snow, for a more complex autumn scene.

P5.js Full Code and Sketch

https://editor.p5js.org/maryamalmatrooshi/sketches/8tY74Enmr

Week 1: Reading Response

In this week’s reading “The Computational Beauty of Nature”, I came across many scientific analogies that have widened my views on nature. Before this reading, I would always look at things from a further perspective and not really think deeply of every object around me and its particular details. Just like the author mentions, the roles of ants in every ant colony would usually be similar, but every ant is unique to its identity and behaves differently despite working on the same task.

It is very fascinating that the reductionist approach can be applied in the computing world. We have had many simulations built thus far that researchers and scientists have benefited from.

Week 1: Self-Avoiding Walk through RGB space

For this week’s assignment, I decided to create a self-avoiding walk within an RGB space.

Whenever a dot tries to walk to a spot that has already been visited before, it stops the program. This can be restarted on click.

In the draw function, I made the RGB space using map() and assigning each dot to a random RGB value.

I tried to simplify the code as much as possible. In the snippet below, it checks if a spot in the grid has been visited before, if not, it pushes a new dot.

for (let option of allOptions) {
  let newX = x + option.dx;
  let newY = y + option.dy;
  if (newX >= 0 && newX < cols && newY >= 0 && newY < rows && !grid[newX][newY]) {
    options.push(option);
  }
}

 

 

Week 1 Sketch

Concept

The concept behind this code revolves around generating a dynamic and visually engaging animation using Bézier curves. Bézier curves, often used in computer graphics to model smooth curves, provide an ideal foundation for creating a path that an animated object can follow. In this program, a “walker” moves along a Bézier curve defined by a set of fluctuating control points. The movement along the curve is complemented by changing colors, creating a lively and evolving visual pattern. This approach allows for the exploration of procedural animation techniques, where randomness and mathematical functions are used to produce aesthetically pleasing, unpredictable outcomes.

Reflections for the Future

Looking forward, there are several enhancements and extensions that could be made to this project. One possible improvement is to introduce user interactivity, allowing viewers to influence the motion, control points, or colors in real-time. Another idea is to experiment with more complex curve types, such as cubic or quadratic Bézier curves, to see how they impact the animation’s aesthetics. Furthermore, adding sound that reacts to the movement or colors could create a multisensory experience, deepening the engagement with the artwork.

Self-Avoiding Walker navigating through RGB space

The two components I decided to choose were to make a self-avoiding walker and have it navigate through an RGB space. The program is below:

The code for my program can be found on my GitHub here. EDIT: I really quickly added a reset function so you don’t need to constantly refresh the page to restart the walker.

Essentially, the program creates an invisible grid for the walker to travel on and then checks what adjacent points have been unvisited. It will then randomly choose one of the valid directions and travels there. The points are colored and are made so the RGB values are mapped based on the current coordinates of the walker. Red is mapped to x, and green is mapped to y. Blue is simply given a random value from 0-255 since the space is only two-dimensional. The program will continue until the walker gets stuck, meaning there are no unvisited nodes adjacent to it that can be visited. The code is a heavily modified version of the barebones walker we used in class.

Originally, it was going to be much closer to what the original walker code was like, but I opted to use the grid because I thought it would be much easier to track the coordinates that have been visited. Also, the original walker is small and hard to see, so I decided to use a more visually appealing and visible pathing. When I first tried to tackle the checking adjacent points problem, the code I had was using the original random 1-4 picker, and keeping the walker in a while loop if the chosen coordinate was within an array of coordinates to avoid. However, this was really inefficient, since the walker would have to iterate through an array of coordinates that go progressively larger over time every time it tried to move, and it made the program slow down if the program was able to go long enough.  After doing some research into other walker programs, I realized there was a much easier way to do the checking. This is how I came to develop the grid instead. Each coordinate in the array is given a value of false, which is then changed to true if the walker chooses that coordinate. You can then have a simple function that will return the boolean value of the coordinates adjacent to the walker.

//checks to make sure the point is unvisited and in bounds
function isValid(i, j) {
  if (i < 0 || i >= cols || j < 0 || j >= rows) {
    return false;
  }
  return !grid[i][j];
}

 

If there are visited nodes adjacent to the walker, it will not add it to the array of options it will randomly choose from to make its next move.

//all adjacent points on grid
let allOptions = [
  { dx: 1, dy: 0 },
  { dx: -1, dy: 0 },
  { dx: 0, dy: 1 },
  { dx: 0, dy: -1 },
];

...

let options = [];
    for (let option of allOptions) {
      let newX = this.x + option.dx;
      let newY = this.y + option.dy;
      if (isValid(newX, newY)) {
        options.push(option);
      }
    }
    //chose a random direction to move in
    if (options.length > 0) {
      let step = random(options);
...

    } else {
      //ends program if theres nowhere to go
      console.log(`I'm stuck!`);
      this.stuck = true;
    }

Honestly, there was a lot more I wanted to do with this program that I did not get to achieve. The main issue stemmed from the fact that during the development process of my program. I made a mistake debugging a loop, which caused the IDE to get stuck and crash the page. In a stroke of genius, I had completely forgotten to save the program I was writing at any point, meaning I had lost all the code I had done, and I was now back to square one. This severely demotivated me for a while and I did not try to tackle the program again until the end of the weekend.

Another aspect of this program I intended to develop was making the walker not get stuck. It annoyed me how quickly the walker usually got itself stuck. It made it hard to see the color changes at times when the walker was occupying about 10% of the grid. Had I given myself more time after my entire program ceased to exist I probably would’ve figured out how to make this work, but unfortunately, I was unable to do so.

Originally, I had also intended to make this program a 3D self-avoiding walker that would navigate through an RGB space, because it meant I could map the z coordinate to blue. I had found some programs that would allow me to do this, but I had a hard time understanding the code and was doing a lot of trial-and-error to really understand what each part of the program was doing and how I could translate it into code of my own. I just decided to go with 2D instead because it was easier to understand, code, and debug. I think I want to try to tackle this again at some point in the future because the walker looked really nice and it would be a good opportunity to work with processing in three dimensions rather than two.

 

EDIT 9/4: After completing the two-dimensional program, I went back to attempt the three-dimensional walk again, and I managed to do so. The link to it can be found here.

The program is functionally similar to the two-dimensional program, there were extra parts that had to be added in order to make the program work in three dimensions. Also, I added some buttons that could be interacted with so that there are some options for the user to play around with. The main difference is in how the program renders the 3D path, where there is an array storing each coordinate point the walker has visited, and renders lines between each point. This means the program has to iterate through the entire array every time to render it, which does lag the program when the path gets very large. There is also a function that tries to center the camera around the path and will shift when it reaches a new min/max to account for this. You can also use the mouse to move the camera, lmb to rotate, rmb to pan, and scroll to zoom.

 

Response 1

Flake’s introduction to “The Computational Beauty of Nature” really got me thinking about how we approach understanding the world around us. I’ve always been drawn to the reductionist approach, dissecting things down to their smallest parts to see how they work. But Flake’s argument for considering interactions and the emergent properties of complex systems is really compelling. The ant colony example is a perfect illustration – a single ant is pretty simple, but a whole colony exhibits incredibly sophisticated behaviors you wouldn’t predict just by studying individual ants.

I’m left with a lot of questions though. Flake mentions the “frugal” nature of the rules governing interactions – is there a way to quantify this frugality? And how exactly do we go about describing these interactions in a computational way? The idea of “nature’s program” is intriguing, but I wonder how far that metaphor can be stretched. What I found most interesting was the connection between computation and natural phenomena like fractals and chaos. It’s mind-blowing to think that simple iterative processes can generate such intricate and seemingly unpredictable patterns. I’m definitely looking forward to diving deeper into these topics in the following chapters.

Reading 1

It’s fascinating to contemplate that simple agents, like ants or even molecules, can come together to create complex behaviors that we see in larger systems. This reading emphasized that we can’t always predict how a group will behave just by knowing about the individual parts. It’s like trying to understand a sports team by only looking at the skills of each player rather than how they fit/work together.

I am particularly intrigued by the idea that nature often uses simple rules to create complexity. The role of computers in studying these interactions also excites me, as it opens up new ways to explore and understand complex systems, and places technologists on the frontlines of the quest to understand nature.

Gaussian Random Walk in RGB Space

The program generates a random walk where each step’s size is determined by a Gaussian distribution, causing the walker to move in smooth, less erratic paths. As the walker traverses the canvas, its position influences the RGB values used to create colors. The resulting display features a vibrant color trail that evolves with the walker’s movement.

function drawTrail() {
  for (let i = 0; i < colors.length; i++) {
    stroke(colors[i]);
    point(width / 2 + randomGaussian() * 80, height / 2 + randomGaussian() * 80);
  }
}

The above code draws points on the graph deviating from the center using gaussian distribution for each random color, leading to higher intensity closer to the middle of the canvas.

Full code

 

Sketch – Week1

Concept

I wanted to create a self-avoiding walk and when the walk ended there would be a morphing shape displayed.

Embedded Sketch

Code Highlight

function displayShape() {
  background(50);

  // Rotate the shape around the y-axis
  rotateY(frameCount * 0.05);

  // Draw shape using the curve function
  fill(167, 250, 250);
  curve(-500, 500, 0, 0, 20, 20, 20, 20, 0, 500, 500, 0);
}

Future Improvements

The self-avoiding walk was time-consuming to figure out, and it was my first time using curve(). I had difficulty implementing it into my code as I haven’t worked with “WEBGL”, and thus had to modify my code accordingly. In the future, I want to try to add text to the displayShape screen as well, as I couldn’t figure out how to add it with “WEBGL” interfering.