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.
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?
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.
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.
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.
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 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:
Connections combines two concepts: Levy flight motion and dynamic bezier curve connections between particles. Levy flight is a type of random walk where the step length follows a heavy-tailed probability distribution, resulting in a long erratic movement. It represents a dynamic system of particles moving within the canvas, with real-time changing edges connecting them. My sketch draws inspiration from concepts in computational art to explore the interplay between randomness and controlled forms in a dynamic particle system.
A ‘Particle’ class encapsulates the behavior and properties of individual particles. Each particle is initialized with a random position (x,y) within the canvas and a random color with alpha transparency. The particles move according to Levy flight motion and can change direction when they come into close proximity to each other.
Particle Movement – Levy Flight:
Using the update() function, a random length and direction is calculated and is reflected on the particle’s movement. Since stepDirection is a random angle, cos(stepDirection) and sin(stepDirection) generate random values between -1 and 1. These values are then multiplied by stepLength, which is a random value as well. The use of cosine and sinus ensures that the particle can move in any direction as stepDirection can take any value between 0 and 2π.
// Levy flight movement
update() {
let stepLength = random(3);
let stepDirection = random(TWO_PI);
this.x += cos(stepDirection) * stepLength;
this.y += sin(stepDirection) * stepLength;
// Keep particles within bounds
this.x = (this.x + width) % width;
this.y = (this.y + height) % height;
}
Particle Appearance:
The display() method draws each particle as a white ellipse with random alpha to create a glowing effect.
Particle Interaction:
As the particles come too close to each other, they both change their respective directions. It is handled by the changeDirection() function.
Particle Connection – Lerp:
If two particles come within a certain distance, a bezier curve is drawn between them. Linear interpolation is used twice for each pair of connected particles: once to determine the position of the first control point (x1,y1) and again for the second control point (x2,y2). It allows for fine-tuning the curvature of the bezier curve between them.
// Control points for bezier
let control1X = lerp(particles[i].x, particles[j].x, 0.1);
let control1Y = lerp(particles[i].y, particles[j].y, 0.4);
let control2X = lerp(particles[i].x, particles[j].x, 0.9);
let control2Y = lerp(particles[i].y, particles[j].y, 0.9);
// Combines the colors of the particles it connects
stroke(lerpColor(particles[i].color, particles[j].color, 0.5));
bezier(particles[i].x, particles[i].y, control1X, control1Y, control2X, control2Y, particles[j].x, particles[j].y);
The color of each bezier curve is a combination of the colors of the two connected particles, creating a smooth color transition along the curve (using Lerp again).
Challenges:
Achieving a balance between randomness and control in the particle movement can be tricky as an excess in randomness can result in chaos and unpredictable behavior. I was able to do that by fine-tuning these parameters and following a trial and error process.
Possible improvements:
Particle attraction: add forces of attraction
User Interaction: let the user interact through clicks or mouse movement
So, for this week’s coding assignment, I tried to implement the self-avoiding walk. I am a mathematics major too and I wanted to explore a mathematical concept through what we’ve been learning in class. In mathematics, a self-avoiding walk (SAW) is a sequence of moves on a lattice path that does not visit the same point more than once. To make it more interesting and look like a computer chip, or gaming area (of pac-man, say), or a network of pipelines, or points and paths on a map, I played around with the color() and strokeWeight() property of the lines and dots I was plotting. With someone randomness using noise as we learnt in class, I was able to achieve interesting and fascinating results!
EMBEDDED SKETCH
WORKING VIDEO
See my self-avoiding walk walking! 🙂
KEY TECHNICAL ASPECTS
There are 2 code snippets I would like to highlight:
1. First is the core concept of the self-avoiding walk – how it chooses which direction to go next and how it avoids itself. For this, I populated an array with available spaces for the walker to move on the basis of which vertices were already visited or not. And then, instead of randomly choosing from numbers between 1-4, the walker randomly chooses a place to go from this array of available spaces.
this.matrix = []; // holds position where all the walker has been --> initially populated to false, changed to true when walker visited that spot
// for populating the spaces available to walker
let options = []; // to store which options available to go to
if (this.isValid(this.x+1, this.y)) //i.e. right available space
options.push(0);
if (this.isValid(this.x-1, this.y)) //i.e. left available space
options.push(1);
if (this.isValid(this.x, this.y+1)) //i.e. up available space
options.push(2);
if (this.isValid(this.x, this.y-1)) //i.e. available space
options.push(3);
// for choosing where to go from the available spaces
let choice;
if (options.length > 0) {
choice = (random(options));
if (choice == 0)
this.x++; // go right
else if (choice == 1)
this.x--; // go left
else if (choice == 2)
this.y++; // go up
else if (choice == 3)
this.y--; // go down
this.matrix[this.x][this.y] = true; // mark this place as visited
}
else {
print("OVER");
// text("OVER", width/2 - 10, height/2);
noLoop();
}
isValid(i, j) { // checks if this matrix space / vertex is available to visit or not
if (i < 0 || j < 0 || i >= num_rows || j >= num_cols)
return false;
return (!this.matrix[i][j]);
2. The second thing I want to highlight is my code for random colours and dot sizes.
// for randomizing dot size based on random gaussian
let w = randomGaussian(5,3);
strokeWeight(w);
// for randomizing stroke color based on noise
let n1 = noise(t);
let n2 = noise(t+50);
let n3 = noise(t+100);
t += 0.5;
let c1 = map(n1, 0, 1, 0, 255);
let c2 = map(n2, 0, 1, 0, 255);
let c3 = map(n3, 0, 1, 0, 255);
let c = color(c1,255-c2,c3)
//plot the point / dot
stroke(c);
point(this.x * this.step + this.step/2, this.y * this.step + this.step/2);
// plot the line
strokeWeight(1);
line(this.prev_x * this.step + this.step/2, this.prev_y * this.step + this.step/2, this.x * this.step + this.step/2, this.y * this.step + this.step/2);
IMAGE GALLERY
Some more drawings that occurred in the process:
FURTHER DEVELOPMENTS
Currently, the self-avoiding walk gets stuck once it reaches a point and has no more places to go. It has travelled to all its neighbouring points and since it is self-avoiding, it can’t cross itself again. This is what we call a ‘dumb’ self-avoiding walk, which just randomly chooses a point to move to next without thinking about the future – whether this will lead me to continue on a longer path or this move will get me stuck. Hence, the next step would be to implement a ‘smart’ self-avoiding walk, which can keep track of whenever it gets stuck and go back and choose a better move which will allow it to continue for longer. The algorithm for this is rather complicated as it requires backtracking and dynamic programming, but still doable and somewhat similar to the computer algorithms for solving mazes.
Inspiration Behind the Project: Aside from this project being an assignment, I was inspired to implement this virtual orchestra using the skills learned in class from this an old new article from 2008 on the world’s first virtual online collaborative orchestra that allowed musicians all over youtube to collaborate and create a musical masterpiece. I found it particularly interesting, because when I think of such technological advancements, interactivity and collaborations I associate them to more recent projects, however this project was initiated back in 2008!
Brief Description: In this program, I created a walker that has a 50% chance of the it’s patterns being drawn based on the location in which the user hovers the mouse, and the other 50% chance is simply based on the basic uniform randomness of the walker. (Shown in code below)
Alongside this movement, I also implemented an orchestra like user interaction by including an audio file that plays based on where the user hovers over the screen. Instead of using just shapes, I used an orchestra man instead of the circle, and an orchestra background for better visualization.
let r = random();
if (r < 0.5) { //Here we have created a 50% chance of the walker's patterns being drawn based on the location in which the user hovers the mouse
this.x=mouseX;
this.y= mouseY
} else {
let choice = floor(random(4)); // and for the other 50% chance the walker continues to move randomly by taking a random number from 1 to 4 and ensuring its an integer value
if (choice === 0) {
this.x+=20; //note that I used plus 20 so the random movement can be more obvious
} else if (choice == 1) {
this.x+=20;
} else if (choice == 2) {
this.y+=20;
} else {
this.y+=20;
}
}
In the first chapter of the book Computational Beauty of Nature, author Gary William Flake begins by delving into the concept of looking at the universe through reductionism and how it is a concept that is definitely applied to various fields of sciences. However soon after setting the definition of reductionism and providing examples, Flake goes on to argue that at some point reductionism must stop for science to advance. This reminded me of a biology topic we had discussed in one of our classes. Scientist’s Gregor Mendel and Thomas Hunt Morgan research had more of a reductionist and gene-centric view studies on inheritance of traits in fruit-flies, which led to many discoveries however at some point became problematic because over complex view of inheritance allowed for scientists to ignore the interactions between genes, proteins, and environmental factors.
An example Flake mentioned that really stood out to me was the Psychologists use certain computer simulations to better analyze cognitive models of the brain. Flake includes other examples as cited: “Physicists study the flow of plasma and the annealing of metals. Economists have modeled various types of economies,”. What would have been better perhaps is of Flake further delved into at least one of applications of computer stimulations, rather than just listing them, this slightly weakens his argument, especially since he mentions that his book’s focus is primarily on computational topics. In fact due to the vagueness of his examples, I began to wonder whether the use of computer simulations can lead to flaws in cognitive models or any scientific model in general?
Computational Beauty of Nature presents a nuanced perspective on the concept of reductionism and its relevance in scientific research, sparking reflection on the nature of our understanding of complex systems. It underscores the balance between recognizing the benefits of reductionism and acknowledging its limitations. In Biology, reductionism has proven successful in studying life forms at various organizational levels, from whole organisms down to tiny molecules. Yet, while valuable, reductionism may not always give us the full picture. Understanding how things interact and the emergent properties that arise is as crucial in scientific exploration as tracing them back to the quantum level.
It is worth noting the author’s subtle inclination towards favoring a more holistic perspective on understanding complex systems as he continuously hints at possible limitations in the reductionist approach. Despite the bias, the reading encourages a deeper appreciation for the different natures of scientific investigation and suggests that embracing various perspectives can enrich our comprehension of the world’s intricacies. As for personal beliefs, the reading didn’t necessarily change them but prompted some introspection. I believe that combining both methodologies will result in a much richer understanding of the world around us. However, it did leave me with thought-provoking questions regarding how incompatible or complementary reductionism and holism are together, and if a balance is realistic.
The first chapter of “The Computational Beauty of Nature” serves as the cornerstone for delving into the realm of computational aesthetics. It lays down the fundamental concepts, highlighting the crucial role of mathematics in our comprehension of natural beauty. Additionally, it underscores the multidisciplinary character inherent in this field, where mathematics, computer science, and other disciplines converge.
In this chapter, the notion of algorithmic information theory is introduced as a powerful framework for grasping the patterns found in the natural world. It posits that these patterns can be succinctly encapsulated by algorithms, offering a means to measure their complexity. This concept, in turn, has profound implications for our perception and quantification of beauty within our surroundings.
However, it’s important to note that this approach has its own set of challenges. The computation of algorithmic complexity for extensive datasets or intricate systems can often become intractable, hampering its applicability in real-world scenarios that demand efficient and scalable methods. Furthermore, AIT has faced criticism for its limited empirical validation in practical situations.
Despite its theoretical elegance, AIT’s capacity to provide precise predictions and elucidate intricate natural phenomena remains a subject of ongoing exploration. Its interdisciplinary nature, while advantageous in its breadth, can also present difficulties in achieving deep specialization in specific domains.
My concept this week is “RADAR”. It is an art piece in which there are multiple walkers located randomly on the canvas and walk towards the cursor and then after a few seconds they scatter back to their initial positions. There are horizontal and vertical lines which gives the image the feel of a radar.
This is my step function, the part I’m particularly proud of is how I manage to make the walkers go back to their initial positions after the bool variable becomes true. (This variable flips every 400 frames)
Challenges:
In this week’s assignment, I had 1 main issue, which was the lag caused by the code. I decided to decrease the number of walkers I had from 200 to 100, which greatly decreased the amount of lag in the sketch while still maintaining the integrity of the art piece.
Future Improvements:
There are some improvements that can be made to this assignment. For example, I can add a line that rotates and ‘detects’ the circles. When detected the circles can increase in opacity, then slowly decrease until the line touches them again.