Week #1 — Dynamically (and randomly) variable “Flower Pot”

The concept

Since in class we view the topic of motions with some formulas, I initially was confused as to how it worked. I and the mathematics, we do not get along very well. Although, I did want to try the new material taught with the following code. So, in this occasion, I present: The Dynamically (and randomly) variable “Flower Pot”.

The Pelin walker presented in class reminded me of how plants can grow overtime: beautiful and with a bit of unproductiveness. With this in mind, I had some ideas related to the growth of plants and a flower pot.

How it works

The code starts by:

1. Preparing some Pelin walkers and keeping them inside the flower pot (or the white rectangle).

2. Decreasing (as in increasing the height) of the Pelin walkers.

3. Once the Pelin walkers reached the top of the flower cup, they began their iconic movement.

4. When the Pelin walkers are moving, their color uses the same motion to shift the RGB values.

The interaction

Once the movement phase start, the Pelin walkers can be altered by the position of the mouse. That is, depending on which X or Y coordinates the mouse is, the Pelin walkers can either continue growing, stop completely or avoid the pointer. Not only this, but to avoid overgrow, there is a chance (about 1%) of stopping the Pelin walkers from continue moving and if the user decides, it can reset the canva by pressing left click.

A highlight of the code I am proud of

The code was a bit hard to make it work, since the implementation of the interaction with the mouse and the way the Pelin increases within the margins was challenging:

class Walker {
    constructor(x, y, w){  //It is called initial X and Y since is the initial start point.
        //This has to generate under the condition of being inside the box
        this.x = x;
        this.y = y;
        this.w = w;

        //Variables for the pelin movement.
        this.tx = x;
        this.ty = y;
        this.lastposition = 0;
        this.rise = 0; //Controls the map to allow the plant to growth.
        this.free_x = 0; //Frees X space
        this.free_y = 0; //Frees Y space.  Both of them helps to create the illusion of growth.

    } 
    draw(){
        push();
        noStroke();
        fill(map(noise(seed1), 0, 1, 0, width),  map(noise(seed2), 0, 1, 0, height), map(noise(seed1+seed2), 0, 1, 0, seed1+seed2));
        ellipse(this.x, this.y, this.w);
        pop();
    }
             //!!!!!!!!!!!!!!!!
    move(){  //Cup class has to be created first in order for this to move. If not, there wil be a crash.
             //!!!!!!!!!!!!!!!!

        this.x = map(noise(this.tx), 0, 1, (cup.x)-this.free_x, (cup.x+cup.w)+this.free_x);
        this.y = map(noise(this.ty), 0, 1, this.lastposition-this.free_x, cup.y-this.free_y);
        this.tx += 0.01;
        this.ty += 0.01; 
    
        //Dynamic probability over here. Basically, according to a number of chance, it dictates if
        //it should be more open or closed

        if (random_number > 1 && random_number < 4){
            if (this.free_y != -1){
                this.free_y -= mouseY/6;
            }
    
            if (this.free_x != -1){
                this.free_x -= mouseX/6;
            }
        } else if (random_number == 1){
            this.free_y = -1;  //Stops growing;
            this.free_x = -1;
        } else {
            if (this.free_y != -1){
                this.free_y += 1;
            }
    
            if (this.free_x != -1){
                this.free_x += 1;
            }
        }
    }
}

Here is the embedded sketch

Remember to press left click to reset!

Reflection and ideas for future work or improvements

Since the code feels unfinished due to the lack of hints and meaningful interaction between the user and the canva, there is a lot that is left that I desired to add:

  • The Pelin Walker actually avoid the cursor in a fluid motion.
  • Useful hints that indicate which sections of the screen allows or stops the growth of the Pelin walkers.
  • Music in the background.
  • An actual white flower pot instead of a white rectangle.

Despite all this, I feel satisfied that I could learn something new; maybe I can implement this technique in the future if there is the need.

Self-Avoiding Walker _ Week 1

Concept:

In the first week of classes, I decided to make a self-avoiding walker with randomized RGB colors for the background, lines, and points of the walker and Gaussian random point size. I took this assignment to review my prior knowledge of P5Js and build upon it.  For the point, I made sure I used noise to randomize the color to make it more organic, playfull, and aesthetically pleasing.

Highlight of some code:

To successfully make this project, I had to research a little about self-avoiding walkers, and I came across the Coding Trian video where he transforms the random walker we made in class into a self-avoiding one. For my code, I followed the same logic as he did but I also added my own into it. I also explored noise and Gaussian random a lot in this assignment. I also decided to add some text indicating that the pattern has stopped so that the user can reload the code if they want another pattern.

 

// global variable to store the data in the left right up and dawn, each objects stores an element of direction
let allDirections = [
  { dx: 1, dy: 0 }, //right
  { dx: -1, dy: 0 }, //left
  { dx: 0, dy: 1 }, //dawn
  { dx: 0, dy: -1 }, //up
];

let x;
let y;

// randomize the color of stokes
let Clr = 0;

let grid;
let spacing = 20;
let cols, rows; //variables for the colombs and rows to store info

//
function GridArray(cols, rows) {
  let arr = new Array(cols);
  for (let i = 0; i < arr.length; i++) {
    arr[i] = new Array(rows);
  }
  return arr;
}

function setup() {
  createCanvas(400, 400);
  //colums and raws for the 2d array
  cols = floor(width / spacing);
  rows = floor(height / spacing);
  x = cols / 2;
  y = rows / 2;
  //random Background color
  r = random(200, 160);
  g = random(200, 160);
  b = random(200, 160);
  background(r, g, b);
  //make an array to store the grid data in to save it and set it intially to false if it did not go there
  grid = GridArray(cols, rows);
  for (let i = 0; i < cols; i++) {
    for (let j = 0; j < rows; j++) {
      grid[i][j] = false;
    }
  }
  //   set to true when walker has been there
  grid[x][y] = true;
}

//create a function to check validity to go to a specific spot
function isValid(i, j) {
  if (i < 0 || i >= cols || j < 0 || j >= rows) {
    return false;
  }
  return !grid[i][j];
}

function draw() {
  // make dot size based on random gaussian
  let w = randomGaussian(8, 4);
  strokeWeight(w);

  // make stroke color based on noise
  let n = noise(Clr);
  let n2 = noise(Clr + 80);
  let n3 = noise(Clr + 50);
  Clr += 0.75;
  let c1 = map(n, 0, 1, 0, 255);
  let c2 = map(n2, 0, 1, 0, 255);
  let c3 = map(n3, 0, 1, 0, 255);
  let c = color(c1, c2, 160 + c3);

  //plot the point
  stroke(c);
  point(x * spacing, y * spacing);

  //make array and put all directions in the array then check if its valid
  let options = [];
  for (let option of allDirections) {
    let newX = x + option.dx;
    let newY = y + option.dy;
    if (isValid(newX, newY)) {
      options.push(option);
    }
  }

  if (options.length > 0) {
    let step = random(options);

    strokeWeight(5);
    stroke(c);

    beginShape();
    //     line
    vertex(x * spacing, y * spacing);
    x += step.dx;
    y += step.dy;
    vertex(x * spacing, y * spacing);
    endShape();
    grid[x][y] = true;
  } else {
    console.log(`Walked this path!`);
    textSize(14);
    fill(255);
    text('OOPS... almost walked on myself',100,200)
    noLoop();
  }
}

One part of the code I am particularly proud of is making the color for the stroke. Here, I created 3 Perlin noise variables. Then, I incremented Clr by 0.75 to ensure a smooth and gradual transition in color. Then, I mapped the noise values to the color ones understood by P5. Finally, when I made the variable c for color, I  made sure that the blue color was more dominant by adding 160 to it.

Embedded sketch:

Reflection and ideas for future work or improvements:

I am really happy with the outcome. This assignment was an opportunity to review what I previously learned in P5Js and add new knowledge to it.  However, I think there is always room for improvement. For instance, I need to figure out how to restrict the walker within the canvas boundaries. Further, I want it to be a little more interactive. For instance, if the mouse is pressed or the space bar is clicked, I want the walker to re-load and then make another randomized walker and change colors.

Resources:

Wikipedia contributors. (2024, August 7). Self-avoiding walk. Wikipedia. https://en.wikipedia.org/wiki/Self-avoiding_walk

1.1 What is a Vector? (n.d.). https://thecodingtrain.com/tracks/the-nature-of-code-2/noc/1-vectors/1-what-is-a-vector

The Coding Train. (2021, June 10). Coding Challenge 162: Self-Avoiding Walk [Video]. YouTube. https://www.youtube.com/watch?v=m6-cm6GZ1iw

Week 1- The Computational Beauty of Nature Reflection

Reflecting on the first chapter of ‘The Computational Beauty of Nature’ I found it really interesting how the author talks about the connection between computers nature and beauty. As a computer science student the idea that we can understand complex things in nature through simple computer algorithms made a lot of sense to me. I usually think of coding as a way to solve problems or make things work better but this reading helped me see it differently. The author shows how even simple rules in code can create beautiful and complex patterns which reminded me of my own projects where simple code led to surprising results. This made me appreciate the beauty in coding even more seeing how it can reveal hidden patterns in the world around us.

However I also noticed that the author seems to focus a lot on computation as the main way to understand nature and that made me think. Is it possible that by focusing too much on algorithms we might miss out on other ways of seeing the beauty in nature? This question challenges my belief that while computers are powerful tools they might not always capture everything about the natural world. For example when I think about the random patterns in nature like the shapes of clouds or how rivers flow I wonder if algorithms can really show this randomness or if they might make it seem less natural. This chapter has made me more curious about the limits of using computers to understand nature and it makes me want to explore how I can balance coding with the unpredictable beauty of the natural world.

Week 1 – Reading Reflection

In the first chapter of The Computational Beauty of Nature, Gary Flake draws on examples from different fields of science and nature to offer a new way of thinking. I believe he succeeds in simplifying complex concepts like computing and coding. Looking at something as complicated as computer science can be quite intimidating; however, a solution is offered by trying to view how things may work using different methods. This approach to learning can make complex coding a simpler task.

Flake’s approach to reductionism and holism allows for a more thorough learning experience. One example I can provide is when a person tries to get their driver’s license—it is required to gain a basic understanding of some car parts before driving. The parts they would focus on include batteries, engines, alternators, as well as external products used for cars. This allows the driver to recognize the kind of device they will be dealing with and understand the use of each part, especially since specific parts may differ across car brands. The holistic approach comes into play when driving the car itself, as managing the car and ensuring that all parts work together cooperatively is crucial.

Getting my driver’s license was a traumatic experience, especially with the overwhelming amount of information I had to learn. But if it means I get to be the best driver among my siblings, then it is worth it.

The Computational Beauty of Nature – Week 1

 

In The Computational Beuty of Nature, Flake transforms how I thought about nature and the world from an extremely complex perspective into a simpler one. In this chapter, Flake explores ways in which the world’s complexity can be simplified. From his definition of Reduction, I tried to understand how things work and behave. For instance, when coding something hard I began by thinking of the different elements it encompaces, and put it in simpler words. Through this reading, I realized that the world is like a puzzle. Small pieces of it come together to make something more complex. Additionally, in this book,  he argues that there is a significant importance in looking at the world through other different lenses, such as holism and parallelism.

“Choas shows us that even in deterministic systems, predictability is not guaranteed”.

Further, I liked his comparison between natural selection and algorithm because even though someone knows how specific algorithms work and the creator knows how natural selection works we, as users, often do not know. As a result, I think this creates a form of randomness, and he will explain further in chapter three about chaos where algorithmic systems can produce seemingly random outcomes.

Even though the chapter focuses on how to see the world it also briefly introduces the different chapters of the book where he draws a connection to the relationship between the various chapters in understanding one another and nature.
I think this chapter formulates a foundation for the book and how via computation one can understand the complexity of our world.

 

Week 1- Independence Day

Concept:

Yesterday, my home country, Trinidad and Tobago, celebrated its 62nd Independence Day, marking our freedom from British colonialism. This is a deeply cherished event back home, filled with parades showcasing our military, fire service, and vibrant cultural bands. As the day winds down, the celebrations culminate in a spectacular fireworks display in our capital, Port of Spain. While I couldn’t be there to celebrate in person this year, I wanted to honour my country by drawing inspiration from this beloved tradition. That’s why I chose fireworks as the concept for this project, allowing me to connect with home even from afar.

Embedded Sketch:

Code I’m Particularly proud of:

// Firework class definition
class Firework {
  constructor(x, y) {
    this.firework = new Particle(x, y, true);
    this.exploded = false;
    this.particles = [];
  }
  
  // Update the firework's state
  update() {
    if (!this.exploded) {
      // Apply gravity to the firework
      this.firework.applyForce(gravity);
      
      // Update the firework's position
      this.firework.update();
      
      // If the firework reaches the peak and starts falling, it explodes
      if (this.firework.vel.y >= 0) {
        this.exploded = true;
        this.explode();
      }
    }
    
    // Update the particles from the explosion
    for (let i = this.particles.length - 1; i >= 0; i--) {
      this.particles[i].applyForce(gravity);
      this.particles[i].update();
      
      // Remove particle if its lifespan is over
      if (this.particles[i].done()) {
        this.particles.splice(i, 1);
      }
    }
  }
  
  // Handle the explosion of the firework
  explode() {
    // Create multiple particles at the firework's current position
    for (let i = 0; i < 100; i++) {
      let p = new Particle(this.firework.pos.x, this.firework.pos.y);
      this.particles.push(p);
    }
  }
  
  // Display the firework and its particles
  show() {
    if (!this.exploded) {
      this.firework.show();
    }
    
    // Show all particles from the explosion
    for (let i = 0; i < this.particles.length; i++) {
      this.particles[i].show();
    }
  }
  
  // Determine if the firework is done (all particles are gone)
  done() {
    return this.exploded && this.particles.length === 0;
  }
}

I’m very proud of my firework class, specifically the explode method that handles the creation of the explosion when the firework reaches its peak. By generating 100 particles at the exact position where the firework explodes, I effectively simulate the burst of a firework. The fact that these particles are given random directions and speeds makes each explosion unique and unpredictable, which greatly enhances the realism and excitement of the simulation.

Key Features:

The main feature of this code is to simulate fireworks that shoot up from the mouse click position and then explode into multiple smaller particles. The visual effect is designed to mimic a real-life fireworks show, complete with motion, colour changes, and fading effects.

Each time you click the mouse, a new firework is created at the position where you clicked. The firework then moves upward on the screen, just like a rocket being launched. This adds a layer of interactivity, allowing you to control where and when fireworks appear.

The code uses a special colour mode (HSB—Hue, Saturation, Brightness) to create vibrant, colourful particles. Each firework and its particles are assigned random colours, which makes the display visually exciting.

The entire visual process is controlled by a loop that continuously updates the position, appearance, and behaviour of each firework and its particles. This loop allows for smooth and continuous animation, ensuring that the fireworks display looks natural and fluid.

Reflection and Future Work:

I’m really proud of my fireworks simulation. To take it even further, I’m thinking about adding explosion sounds that vary based on the size and type of firework, which would make the experience even more immersive. I’d also love to introduce different types of fireworks, like starbursts or spirals with unique explosion patterns, to add more variety and depth to the display. These improvements would not only elevate the overall experience but also make the simulation richer and more dynamic, allowing me to create something truly special.

References:

Coding Challenge #27: Fireworks! (youtube.com)

mousePressed (p5js.org)

Week 1 – Reading Response

I think that Flake’s take on how simple things can generate complex outcomes is an interesting point of view which applies to evolution, learning, and adaptation. These small adjustments can eventually adapt and can result in substantial evolutionary changes in the natural world.

I think this shows that adaptation isn’t just something living creatures do. It’s a basic part of how any system works, whether that’s in nature, a society, or even in computer programs. For example, it is the same way people adjust to new technologies and learn how to use them even if they haven’t interacted with them before.

Here’s how I see it: there is a reciprocal interaction between an adaptive system and its surroundings. The system’s modifications are influenced by the environment, and those changes may have an impact on the environment as well. This reciprocal relationship is what enables everything to change and evolve throughout time, including technology, society, and the natural world.

Week 1 Assignment – Self-Avoiding Walk

For this week’s assignment, I chose to make a random self-avoiding walker. First, I started by looking at the P5JS example of it and took inspiration from it.

But it wasn’t enough. So, I have started looking for ways to make the walk not get stuck. For that, I have modified  the approach to continuously attempt to find a path by using a backtracking method. It took me a few tries, but I have eventually got there.

After everything, I have added the function to change colors everytime it changes directions. This was not as hard because we have tried it in class.

 

 

let spacing = 20;
let cols, rows;
let x, y;
let grid;
let allOptions = [
  { dx: 0, dy: 1 },
  { dx: 1, dy: 0 },
  { dx: 0, dy: -1 },
  { dx: -1, dy: 0 },
];
let stack = [];
let currentColor;

function setup() {
  createCanvas(400, 400);
  cols = width / spacing;
  rows = height / spacing;
  x = floor(cols / 2);
  y = floor(rows / 2);
  background(51);
  grid = Array.from({ length: cols }, () => Array(rows).fill(false));
  grid[x][y] = true;
  stack.push([x, y]);
  currentColor = pastelColor();
}

function draw() {
  stroke(currentColor);
  strokeWeight(spacing * 0.5);
  point(x * spacing, y * spacing);

  let options = allOptions.filter((option) =>
    isValid(x + option.dx, y + option.dy)
  );

  if (options.length > 0) {
    let step = random(options);
    strokeWeight(1);
    stroke(currentColor);
    line(
      x * spacing,
      y * spacing,
      (x + step.dx) * spacing,
      (y + step.dy) * spacing
    );

    x += step.dx;
    y += step.dy;
    grid[x][y] = true;
    stack.push([x, y]);
    currentColor = pastelColor();
  } else {
    if (stack.length > 1) {
      stack.pop();
      [x, y] = stack[stack.length - 1];
    } else {
      noLoop();
    }
  }
}

function isValid(i, j) {
  return grid[i]?.[j] === false && i >= 0 && i < cols && j >= 0 && j < rows;
}

function pastelColor() {
  return color(random(200, 255), random(200, 255), random(200, 255));
}

For the future, I think that I would like to make it more complex. Maybe I can make two of them and make it collide and when they do something happens. Until then, I am pretty pleased with the outcome

Week 1- Reading Response

Reductionism and holism offer two different ways to understand complex things, whether it’s in science or something as simple as making lasagna. With reductionism, you break down the process—like learning to cook pasta perfectly, making a sauce, and picking the right cheese. You focus on each part separately, mastering them one at a time. Once you’ve got each piece down, you bring it all together step by step to create the final dish. This approach helps you understand every part deeply before putting it all together.

Holism, on the other hand, is about seeing the dish as a whole, thinking about how the ingredients and flavors interact to create something greater than just the sum of its parts. Instead of focusing only on individual components, you consider how they work together—like adjusting the seasoning based on the cheese or layering ingredients to balance flavors and textures. Holism encourages you to think about the overall harmony of the dish, resulting in a richer, more complex lasagna.

Using food to explain my thought process is easy because of my love for it, but on a more serious note, I believe that both reductionism and holism are valuable approaches. Depending on the situation, one might be more useful than the other. Sometimes it’s better to focus on the details, while other times it’s best to look at the big picture. Understanding when to use each approach can help you navigate and understand complex systems more effectively.

Week 1 – Dynamic Random Walker

This project explores a unique blend of randomness and user interaction through a dynamic color random walk. The random walker is designed with two key features that make its movement and visual output both unpredictable and engaging.

Key Features:

  1. Biased Random Movement:
    • The random walk incorporates a 40% probability of moving towards the direction of the user’s mouse, introducing an element of interactivity. The remaining 60% of the time, the walker moves in a random direction. However, this randomness is also biased; the walker does not have an equal probability of moving left, right, up, or down, which introduces subtle variations in the walker’s path and adds complexity to its movement.
  2. Dynamic Color Evolution:
    • The visual aspect of the walker’s path is enhanced by a dynamic color mapping that evolves as the walker moves across the canvas. The color of each point is determined by its x coordinate, creating a spectrum of hues that shift horizontally across the canvas. Simultaneously, the brightness of each point is mapped to the y coordinate, resulting in a gradient that changes vertically. This color evolution adds a rich, visual narrative to the walker’s journey.
  3. Spatial Harmony:
    • To ensure the visual clarity of the path, the walker only draws a point if it has moved a minimum distance from its previous position. This spacing prevents the points from overlapping, creating a more aesthetically pleasing and well-defined pattern.

Code

let walker;
let stepSize = 8;  
let minDistance = 30; 

function setup() {
  createCanvas(600, 600);
  walker = new ColorWalker();
  background(0); 
}

function draw() {
  walker.step();
  walker.render();
}

class ColorWalker {
  constructor() {
    this.x = width / 2;
    this.y = height / 2;
    this.prevX = this.x;
    this.prevY = this.y;
  }

  step() {
    let direction = random(1) < 0.3 ? 0 : 1;
    let moveX = 0;
    let moveY = 0;

    if (direction === 0) {
      if (mouseX > this.x) {
        moveX = stepSize;
      } else if (mouseX < this.x) {
        moveX = -stepSize;
      }

      if (mouseY > this.y) {
        moveY = stepSize;
      } else if (mouseY < this.y) {
        moveY = -stepSize;
      }
    } 
    else {
      let choice = random(1);
      if (choice <= 0.4) {
        moveX = stepSize;
      } else if (choice <= 0.6) {
        moveX = -stepSize;
      } else if (choice <= 0.8) {
        moveY = stepSize;
      } else {
        moveY = -stepSize;
      }
    }

    this.x += moveX;
    this.y += moveY;

    
    this.x = constrain(this.x, 0, width - 1);
    this.y = constrain(this.y, 0, height - 1);

    
  }

  render() {
    let distance = dist(this.x, this.y, this.prevX, this.prevY);
    
    if (distance > minDistance) {
      let hue = map(this.x, 0, width, 0, 360);
      let brightness = map(this.y, 0, height, 100, 50);
      
      colorMode(HSB, 360, 100, 100);
      strokeWeight(15); 
      stroke(hue, 100, brightness); 
      strokeWeight(15); 
      point(this.x, this.y);

      this.prevX = this.x;
      this.prevY = this.y;
    }
  }
}

Potential Improvements

I want to make this walker a self-avoiding one I think that would be interesting visualization.