Xiaozao Reading Reflection – Week#1

I really like the reading passage. It tells us about how different disciplines interact with each other and have shared underlying logic. The author mentioned two opposite theories, the reductionism and the holism. He said that these two theories won’t agree with each other because reductionism is about how we break down things in parts, and smaller parts, right to the quantum level, while holism is studying how simple things can form together into a more complex system. But from my perspective, these theories are not only contradictory but also complementary. When looking at something, we always look at it from “eye level”, which means we observe its appearance and try to get information about what it is naturally. Then we apply reductionism and break down its concepts. After that, we apply holism and analyze how it behaves in a larger context or environment. Finally we go back to the middle stage and will be able to get a clearer idea of not only “what it is”, but also “why it does this”. This is how we get to know every individual in the universe, and how we develop an interdisciplinary perspective.

There are many examples in life that prove the ideas of the author. For example, the clusters of galaxies in the field of astronomy are quite similar to neural networks in the field of neural science. And actually, the structure and logic of computers are inspired by the two. Many manmade things are bionic, meaning that they all got inspiration from the micro and macro world in nature. When we break them down, we will see similar basic patterns; and when we look from the macroscopic perspective, we will find they have similar behaviors under that respective context. As the author has mentioned, the invention of the computer brings all the subjects together and promotes communication between them. This is right because the computer simulators found out the similarity of structure and interaction type among them. Therefore, what we are doing in this class is very important to not only the application of computer programming, but also the discovery of nature theories.

Coding assignment – week 1

So for this week’s assignment I worked on 2 separate p5.js sketches. The first sketch is a progression on some of the generative code I created in class (sketch linked below).

https://editor.p5js.org/as13805/sketches/4bYDgmVvu

In the above sketch I built off of the randomness concepts we learnt in class to govern the movement of the walker’s in accordance to Perlin noise. In doing so, it provided smooth transitions between each new step the walker took. I also used the x and y coordinate values of the walker to control the dimensions of the walker (ellipse) and using the Perlin noise values of variable v to control the shade of the walker.

————————————————————

My second work (main assignment) is my attempt at creating a walker than follows Levy flight.

To my understanding, Levy Flight is a random walk where most often the walker takes many small steps in a small area but sometimes takes a much larger step of varying distance. Similar to how some animals forage for food, where they sniff continuously around one area and then suddenly move a long distance away to sniff a different area. They repeat this until satiated. Below are images of the phenomena from Wikipedia that I used to try to recreate.

In my p5.js sketch I also controlled the color of the walker using the randomness of the walker.

Below is the link to my p5.js sketch and the corresponding code.

https://editor.p5js.org/as13805/sketches/PVIa9w0zN

let chance = random(100);
  if (chance<2){
    direction.mult(random(25,100));
  }else{
    direction.setMag(4);
    stroke(this.pos.x,map(this.pos.y,0,600,0,255),chance);
  }

The code snippet above controls the randomness of the walker its erratic jumps. I believe this is the main part of my code.

Challenges:

I wanted to make a bigger spectacle using the perlin noise in this code but I did not know how to add it in time. Hopefully, if I start working on my next project earlier, I can take bigger creative decisions to make the code standout out more.

Inspiration:

I learnt a lot from this youtube video

Reading Response Week 1 – Omar ElGamal

For this reading, it covers some things that I am generally interested in like the emergence of properties in complex systems, and parallels between evolution and other seemingly unrelated processes. I liked the author’s use of examples to illustrate his point, like the simple concept of a deer evading prey to explain more complex phenomena of natural selection, and in general, I found that thinking of evolution in computational terms (describing it as a parallel system that has “fault tolerance” and reproduction being described as iteration and recursion) provides a helpful analogy.

From an IM & coding perspective, I think it’s an attractive idea that nature’s patterns are recurring, repeating, and simple, and definitely agree with this in some ways. Testing this idea by trying to mimic or simulate different natural phenomena using a set of small & simple rules sounds really fun and I believe the book as a whole can be very helpful in this regard. I’ve dreamt a lot of trying to make my own version of cellular automata and incorporating an evolutionary network but still keeping it relatively simple, just to see how far I can push it in terms of interesting emergent behaviors that might manifest.

On a slightly more unrelated point, the adaptation section piqued my interest the most, especially the bit about learning, evolution, and cultural adaptation being the same process on different time scales. I’ve watched a couple of lectures from developmental biologist Michael Levin (A really interesting one is Intelligence Beyond the Brain on Youtube), and in it, he proposes this idea that intelligence is more or less the same across different physical scales and that all intelligence is collective intelligence (since everything is made of parts). He talks about the similarities between types of intelligences that we often think of as vastly different or even completely overlook. Like how cells came together as separate individual intelligent agents and gave rise to multicellular intelligence able to solve more complex problems (emergence), and then how these multicellular intelligences can be organs (that can themselves be considered intelligent) that come together to make organisms that are able to solve & work towards more even complex goals (although at the most basic level, they seem to me more or less the same goals of reproduction, food prosperity, etc.. just on larger scales). Sometimes I like to theorise that any group of intelligent agents is eventually bound to come together and give rise to something more complex, and I think that humans are just going through their evolutional journey of figuring out how to connect, communicate and work together seamlessly (almost like cells do), to give rise to an agent that’s on a different plane of intelligence, capable of much more than we are able to imagine. I think we would need a real technological revolution in communication, but sometimes I feel like it’s almost inevitable. In the lecture I mentioned earlier Michael Levin points out how cells don’t know that they are part of a human they’re just doing their thing, and I think that even if they had some sort of awareness that they are part of a system or working within a larger group, the problems and aspects of human life are simply incomprehensible to a single cell because they exist on a different scale. So, maybe we already are part of an intelligent agent and we just don’t know it, an agent that exists in a realm beyond our comprehension or understanding.

Reading Response – Week #1

The author says, “Reductionism fails when we try to use it in the opposite direction.” I do not completely agree with this statement. From what I understand, reductionism is breaking down a complex system into smaller parts, until it cannot be broken down further, and studying the system at this core level. This gives us a lot of information on how the individual elements of a system work, but this is not the final step. The ultimate goal is to understand the system itself. That can only happen if, after reductionism, we let ourselves use the knowledge of these individual simpler units to build back up the full system and study it as a whole – how are these individual agents interacting with each other and what does that tell us about the system? This is a bottom-up approach, i.e., understanding reductionism in reverse.

In fact, the author himself touches upon this and contradicts himself when he quotes Bertand Russel in the beginning, “The point of philosophy is to start with something so simple as to not seem worth stating, and to end with something so paradoxical that no one will believe it.” This is nothing but reverse reductionism. This is what we often do in math too. We start with an obvious (trivial) statement that no one will seem to contradict, and then build something upward from there, leading to a complex proof or a result that may be counterintuitive or ‘mind-boggling’ as the mathematicians say. Since most of the sciences depend on math, they follow a similar pattern of experimentalism and theorization. And what does science aim to do? Science studies and tries to explain the daily observations and occurrences in nature. So, doesn’t this tell us something about nature as well? Yes, it does. And it is that nature itself governs by the law of reverse reductionism. Nature defines how the individual elements behave and then puts them together, letting them run free reign – agents interacting as they wish – and thus creating complex systems.

Hence, if we wish to understand the complex systems in nature, we must employ the strategy of reverse reductionism after reductionism. Understanding reductionism in the reverse direction does not fail us, but rather it is an essential next step.

Assignment 1 – Ayush

 

My inspiration for this project comes from this video by Veritasium.

Pathfinding have a ubiquitous presence in the real world. Their applications range from everyday navigation tools like Google Maps and logistics optimization for companies like Amazon. They are also used in guiding the movements of autonomous vehicles.

Through this project I wanted to experiment with more than just a random walk. I wanted to see if we can put some brain into our walker, so it doesn’t just go towards random directions, but makes some decision in order to find the destination.

Here’s the p5.js sketch:

https://editor.p5js.org/ap6178/sketches/Wi7864pjq

 

The walker performs multiple succeeding walks, from one cell to the other. But then it realizes that the direction it’s taking is not the correct one. When this happens, it tries a new path. Each of these paths have some metrics that tell the walker whether it’s going towards the correct direction or not.

To put brain into the walker, I have used the A* search algorithm. It basically takes two things into consideration in order to be able to make decisions:

  • The cost it took for the walker to get to the current point.
  • An estimate of how far the walker thinks it is from the destination.

This estimate is called the heuristic function in A* search algorithm. The total estimated cost is given by the following equation:

f(n) = g(n) + h(n)

At any node n, the estimated cost of the path is calculated i.e. f(n)
f(n) requires two other costs: the cost to reach node n i.e. g(n) and the estimated cost to reach the goal node i.e. h(n)

h(n) in this equation is called the heuristic function. There are many heuristic functions we can use, but in this project, I decided to use the Manhattan distance heuristic since we’re dealing with cells on the grid. The Manhattan distance is the sum of horizontal and vertical cell distances to the goal node.

This idea of calculating heuristic for each step makes the walker intelligent.

 

Code

Each node has the following properties as described by the Node class.

class Node {
  constructor(i, j) {
    this.i = i;
    this.j = j;
    this.f = 0;
    this.g = 0;
    this.h = 0;
    this.wall = random(1) < 0.30; // there's a 30% chance of being a wall
    this.previous = undefined;
  }

  show(col) {
    fill(col);
    if (this.wall) {
      fill(59, 25, 25);
    }
    rect(this.i * cellSize, this.j * cellSize, cellSize, cellSize);
  }

  getNeighbors() {
    const neighbors = [];
    const i = this.i;
    const j = this.j;

    if (i < cols - 1) {
      neighbors.push(grid[i + 1][j]);
    }
    if (i > 0) {
      neighbors.push(grid[i - 1][j]);
    }
    if (j < rows - 1) {
      neighbors.push(grid[i][j + 1]);
    }
    if (j > 0) {
      neighbors.push(grid[i][j - 1]);
    }

    return neighbors;
  }
}

The main brain of the walker lies on this heuristic measure. It calculates the Manhattan distance between two nodes nodeA and nodeB required for our estimation function.

function heuristic(nodeA, nodeB) {
  // Manhattan distance (sum of horizontal and vertical distances)
  const dx = abs(nodeA.i - nodeB.i);
  const dy = abs(nodeA.j - nodeB.j);
  return dx + dy;
}

With the help of this heuristic, the function values: f, g, and h are then updated and required actions are taken.

// check neighbors and update their f, g, h values
const neighbors = current.getNeighbors();
for (let neighbor of neighbors) {
  if (!visited.includes(neighbor) && !neighbor.wall) {
    const g = current.g + 1;
    let newPath = false;
        
    if (unexplored.includes(neighbor)) {
      if (g < neighbor.g) {
        neighbor.g = g;
        newPath = true;
      }
    } else {
      neighbor.g = g;
      unexplored.push(neighbor);
      newPath = true;
    }
        
    // update values if path is new
    if (newPath) {
      neighbor.h = heuristic(neighbor, endNode);
      neighbor.f = neighbor.g + neighbor.h;
      neighbor.previous = current;
    }
  }

Future Improvements

An improvement to this project would be to be able to connect the path with lines and show a more artistic version of how the walker is choosing new paths. I would also want to add some kind of animation when it reverts back a few steps to continue to a new path.

Xiaozao Week1 Coding Assignment

This week, I tried on two different kinds of random walkers, which are the self-avoiding walker and the chance-control walker.

Self-avoiding Snake

Video: https://drive.google.com/file/d/1Y0-no7La1HUOdGIHNaVAoFkQJxFrM-Tg/view?usp=drive_link


P5js sketch: https://editor.p5js.org/Xiaozao/sketches/st5NS1k5R


(I’m sorry, something went wrong with my wordpress editor and I really don’t know how to insert the p5 sketch in this new editor. I will try to figure it out asap!!)


This project is inspired by the classic game “Snake”. Since the self-avoiding random walker moves either vertically or horizontally on a grid, why can’t I make a snake game by controlling the length of the path of this random walker, and placing some “apples” on the grid, so that whenever the snake touches an apple, it will eat it and grow in length? And the special property of the self-avoiding walker, which is that it will either find another path or terminate walking when it meets its own body, is very suitable for making a snake game.


I started with coding a self-avoiding random walker. I learned it from the coding train: https://youtu.be/m6-cm6GZ1iw?si=cbg0Dx-YE7jZplUc.

Basically, I first create a grid of size (rows, cols) and initialize the value of each pixel in the grid to be True, meaning that it’s empty and available to be occupied. And then, I create an array, which consists of every node of the snake’s body, and I change the status of the pixels that have been occupied by the snake’s body, meaning that they can no longer be stepping into when I’m considering the next step. After that, I begin to check the 4 neighbours of my current position (up, down, left and right), and if they are still empty and not occupied, I put them into my “available options” array. Finally, I choose a random direction from the available options, and go to the next step. This is how the self-avoiding walker works.

And then, I began to program the snake game. There are two main considerations of this game. Firstly, different from the original random walker, which draws every single node that I’ve been to, now I want to control the length of my snake. This can lower the chance of terminating the game too fast because a long body occupies a lot of space so there will be fewer choices in every step. To do this, I have to keep track of every node of the snake’s body, and pop the tail out if it’s too long. I made an array of nodes, and used the function splice() to pop out the older parts of the snake body.

The second important part is the apple-eating mechanism. Whenever I click the mouse, an apple will be placed at the same place and can be eaten by the snake. The snake’s length will plus by one every time it eats an apple. I made a class for the Apple objects, and came up with a formula that calculates the position to place the apples so that they will always be in the center of the pixels, so that they can be easily eaten by the snake.

Lastly, I placed a “keyboard” in the grid. The value of mouseY will control the frequency rate of the sound being played so it creates a really funny sound effect! (By the way, I recorded the sound on my own~)

Chance-control random walker

This is another experiment that comes from a mistake. Please look at the explanation below:

I mistakenly wrote the code when I was trying to create a uniform random distribution. Instead of generating a single random number and checking its value using if/else statement, I generated a brand new random number in each “else if” statement”. But it accidentally created a non-uniform random distribution which the chance of executing the second “else if” block is somehow dependent on the chance of executing the first “if” block, and so on. I then tried to pass the chance values for the four statements as parameters and map the hue of the random walker with the chance values. And the result turned out to be interesting!

Here is the code: https://editor.p5js.org/Xiaozao/sketches/vyNmsjMgc

There’s so much more to explore about this chance-controlling random walker!

Reading Reflection – Week#1

I enjoyed the reading as I feel like it is very relevant in many disciplines such as the sciences, computer science, maths, economics, meteorology. The reading starts off with the idea of reductionism and how a system can be understood by examining its individual parts and even though I did agree partially after reading this first statement, I definitely had some doubts. I did think of humans and emotional intelligence as an example. You may be able to describe the cells that make up a human, but you wont be able to study humans emotional intelligence without adding humans or animals into the study. And that is where the text takes us to and explains how the opposite idea of reductionism, holism may be a better way to explain life as a whole.

Holism – the theory that parts of a whole are in intimate interconnection, such that they cannot exist independently of the whole, or cannot be understood without reference to the whole, which is thus regarded as greater than the sum of its parts. Holism is often applied to mental states, language, and ecology.

This is the definition I got from Google and I agree with this idea more about we need to use the interdisciplinary to explain effects and reasoning of many things in the world. Reductionism looks at the world as the root of a tree structure and maybe cells or quantum qubits being the children of this tree but in reality, that root we saw as the world would be the children of another tree in a whole new universe.

I want to touch upon how the idea of computers combining experimental and theoretical have helped many disciplinaries work together and create revolutionary ideas. I really enjoyed the part on how simple and random are what make the complex and I can see that being applied in this course as we further discuss simple and random ways that make a ‘complex natural’ structure, contradicting ourself.

Reading Response Week 1

Before reading, a question has concerns me is what does the idea of “decoding nature” actually contains, and to say that all scientific terms could be categorized into “agents” and “interaction of agents” opened up my mind. That’s a way of explaining the phenomena in nature, using computational methods. I would think through out my working on project using what ways to simulate the interactions between the elements. I also realized that while decoding nature, we could code our future using the simplified patterns and generalizing ideas in nature.

Interdisciplinary knowledge is important in design: the chaos, fractional and other concepts are derived from mathematics, and one wouldn’t come to a conclusion that every science is reductionism without digging inside those knowlegde. I realize as the century progress, human are joining a new era of technology booming. As interaction artists, we are supposed to grasp the beauty within the novel ideas and innovations, then find the repetition in natural laws and new discoveries. However, is the sense of beauty embedded within our cognition, and how can the abstract relationship and law from natural science better our design thinking, as well as being applied into architectures and other life tools?

Coding Assignment – Week #1 – HSB Self avoiding walk

I decided to choose a self walking path that also changes colour with respect to where on the canvas the vertex is. I wanted to first try the self walking path without the colour change and once that was done, try to add the changing colours.

Firstly, I planned my grid as a 10 by 10 after researching how HSB works. H is for the ‘main colour’, S for saturation and B for brightness. I am not sure on how 3D modelling works so far so I want to make the x plane represent the saturation and the y plane represent the brightness.

This was the idea and I did some quick calculations on where I would want the dots to be places, in the middle of each ‘square’. After planning this out, I created a simple 2D array, 10 by 10.

let grid = [];  
for (let i = 0; i < gridSize; i++) 
  {
    grid[i] = new Array(gridSize).fill(false);  //fill false
  }

I have done something similar in Intro to Computer Science so I used very similar ideas in this code and had everything initialised to false so when checking which squares were taken, they would be marked as true.

My next problem was wondering how to plan the circles or dots and after researching, I saw some people use the beginShape() function which allows you to plot points and have lines be drawn between each new point.

https://p5js.org/reference/#/p5/beginShape

I also remember from my intro to CS class that we could use dictionaries and arrays to create possibilities of directions so I created one for the 4 possible movements: up, down, right, left. I also added a validation function to make sure it was never going out of bounds of the array.

let DIRECTIONS = [
  { dx: 1, dy: 0 },
  { dx: -1, dy: 0 },
  { dx: 0, dy: 1 },
  { dx: 0, dy: -1 },
];            //choice of directions for vertex

function isValid(i, j) 
{
  if (i < 0 || i >= gridSize || j < 0 || j >= gridSize) 
  {
    return false;
  }
  return !grid[i][j];
}

So at this point, I had something like this.

Now that I had the main part from list 1 completed, it was now time to tackle the colouring from the HSB scale. I wanted to complete the following: have the H colour always be randomised from the range 0-360 every click on the screen, have S and B be respective of where on the grid, and have the lines also blend nicely between the vertices.

I started off by randomly choosing a number between 0 and 360 with the simple random function. I also wanted to check how HSB colour mode would need to be implemented and have that implemented, I found the following 2 links.

https://p5js.org/reference/#/p5/random

https://p5js.org/reference/#/p5/color

strokeWeight(2);
colorMode(HSB);
stroke(colour_choice, (x*20) + gridSize, (y * 20) + gridSize);

I then got the following images.

Ideally, I would want to see the whole grid filled out and see how the colour grid looks like but the chances of the self avoiding walk ending that way is very low so I tried uploading images where a lot of squares were coloured.

Some parts were definitely fiddly such as trying to have the canvas reset after another click but I did end up getting there and made use of loop() functions and just having the grid reinitialised and so I am proud of that part of my code.

function resetSketch() 
{
  background(255);
  for (let i = 0; i < gridSize; i++) 
  {
    grid[i] = new Array(gridSize).fill(false);  //fill false
  }
  colour_choice = random(360); // choose from 360 of H values
  pathStarted = false; // reset 
  loop(); // Restart animation 
}

What would I change?

As I progress in class, I would like to try this again in a 3D model and have the H value be dependent on the Z axis. I would also like to try different models such as the H value changing and maybe the S being some random constant. I am sure there is an algorithm or some way to have the decision be a smart one so that they whole grid can be filled and we can see the true palette of that colours brightness and saturation.

I also saw some examples of where there as backtracking involved or recursion so maybe try to implement that and even possibly make this more interactive as a maze game.

Final code

https://editor.p5js.org/kk4827/sketches/6-NjjdarY

 

Coding Assignment – Week#1

For the first week’s project, I decided to implement a self-avoidant walk and boost it with changes in HSB according to the walker’s position on the 2D plane.

THE SKETCH:

https://editor.p5js.org/llluka/sketches/iYn-Ng2tv

The canvas is split into a grid of cells, with each square indicating a possible location for the self-avoiding random walker. As a result, a 2D array was formed to track the walker’s movement, with every element corresponding to a cell on the canvas. Such structure ensures that the walker does not revisit previously occupied cells and moves in an intricate pattern on the canvas. The walker begins its movement from the center of the canvas, and its movement is decided randomly. The path is finite, depending on how fast the walker ends up in a position where all of the neighbor cells are already occupied.

The coloring of the walker’s path is dynamically generated based on the walker’s position, both x and y coordinates, creating different gradients of hue, saturation, and brightness on different parts of the canvas. Hue is influenced by both x and y, while saturation varies vertically, and brightness varies horizontally. Here is the code I used to achieve that:

  // Influencing the hue based on both x and y positions
  let hue = map(x + y, 0, cols + rows, 0, 360);

  // Adjusting the saturation based on y so that the saturation varies vertically on the canvas.
  let saturation = map(y, 0, rows, 100, 255);
  
  // Adjusting brigthness based on x so that the brightness varies horizonatally on the canvas
  let brightness = map(x, 0, cols, 100, 255);

  // Set the stroke color using HSB color mode with adjusted saturation and brightness
  stroke(hue, saturation, brightness, 200);

For future advancements for this project, I would imagine implementing a backtracking algorithm that would allow the walker to backtrack and retrace its steps when it encounters a dead end. In such a way the walker’s journey could be extended, resulting in longer patterns. Nevertheless, this project was a great opportunity to practice 2D arrays. I remember making board games in my Intro to Computer Science class, and it was exciting to implement the same structures but in another language.

Here are a few images of the more beautiful patterns that occurred: