Week 2: Generative Art

Concept

The idea of the project was to simulate stars in the night sky. Due to the rotation of the Earth, if we were to point a camera at a clear night sky full of stars, we would capture the movements of the stars. This movement resembles a circle with the centre at the North Star. I proceeded with the image of multiple concentric yellow circles which transformed to become more colourful as I wrote the code. The final image also resembled the rings on a heavenly body, such as Saturn. Also, if one were to look at it closely, it also appears to resemble an impressionist version of mandala art.

Code

Tracing the path of hundreds of stars was the most critical and the most difficult process in the project. In order to do it, I had to move the stars independently of one another. The simplest solution was to make each of the star as a single object. Thus, I made a class called Star and added attributes to it.

class Star {
  constructor() {
    // each star will have a random distance from the center
    this.radius = random(width);
    
    // each star has a random co-ordinate relative to the center
    this.xpos = center_x + random(-this.radius, this.radius);
    this.ypos = center_y + random(-this.radius, this.radius);
    
    // Calculating the angle of the star relative to the center.
    // A random constant is multiplied because without it the stars seems to only assume angle between -90 and 90 degrees. Try running the draw() function without this constant only once.
    this.angle = atan((center_y - this.ypos)/(center_x - this.xpos))*random(4, 9);
  }
  
  // function to display the star
  show() {
    noStroke();
    // changing color with respect to the count variable
    if (count % 100 === 0) {
      fill(color(random(10, 255), random(10, 255), random(100, 255)));
    }
    
    // star has a random diameter.
    circle(this.xpos, this.ypos, random(1, 3));
  }
}

This way, each star would have its own x-position, y-postition, radius and angle which can be modified independently of the others.

I proceeded to create hundreds of stars which would be displayed onto the canvas.

// count will change the color of the path traced by the stars.
let count = 1;

let num_of_stars = 200;

// co-ordinates of the center from where the stars will trace a circle
let center_x, center_y;

// will contain all the star objects.
let all_stars = [];

function setup() {
  createCanvas(700, 700);
  background(0);
  
  // centering the stars on the geometric center of the canvas
  center_x = width/2;
  center_y = height/2;
  
  // creating stars and appending it to the array
  let i = 0;
  while (i < num_of_stars) {
    all_stars[i] = new Star();
    i++;
  }
  
  // always start the trace with yellow.
  fill("yellow");
}

The while loop would create new stars and append it to the all_stars array.

function draw() {
  // modifying the attributes of each star, one at a time
  for (let i = 0; i < all_stars.length; i++) {
    let current_star = all_stars[i];
    
    // tracing a circle from center using the radius and the cosine and sine function
    current_star.xpos = center_x + current_star.radius * cos(current_star.angle);
    current_star.ypos = center_y + current_star.radius * sin(current_star.angle);
    
    // displaying the star onto the canvas
    current_star.show();
    
    // varying the angle to trace a circle
    current_star.angle += 0.01;
  }
  
  // incrementing count which is used in changing the color of the stars.
  count += 0.5;
}

The for loop will loop through all the stars, changes their attributes (essentially their position which traces a circle) and display them onto the canvas. The stars made a circle, as I implemented the change in x and y position through their polar co-ordinates counterpart in terms of radius and angle.

current_star.xpos = center_x + current_star.radius * cos(current_star.angle);
current_star.ypos = center_y + current_star.radius * sin(current_star.angle);

These two lines of code can be modified to create various other patterns and curves. For example, if we square the cos and sin in the function, we would receive a thicker circle, almost pixelated.

This looks almost like a mandala art (but not quite). Similarly, if we invert the cos and sin function (power -1), we would get something that resembles a top-down view of a well lit road junction.

Future Improvement

While I was messing around with the functions, I realised that there were many combinations that could be form with it. The two aforementioned modifications were two of the most noticeable ones. This called upon an improvement into the code, which has to do with the interactivity of the art. The idea would be to allow user to chose the function they would want to use. For instance, have a button to change the function from a cosine to a tangent.

Leave a Reply