Week 2 – Generative Art Megan

Concept

“The whole universe is based on rhythms. Everything happens in circles, in spirals.” — John Hartford

The idea of my artwork was that I wanted to create a spiral using the colors of the flower often called the “national Bolivian” flower, the kantuta. This flower is one of the most amazing ones, not only because of its vibrant colors, but also because it grows up to 3,800 meters above sea level, in its native land in the Andes. This flower has a lot of meaning for me, starting with its colors red, yellow, and green, which are those of the Bolivian flag, and also because it represents the nature and resilience of my home country.

Speaking of nature, I wanted to represent this flower through some kind of shape. Spirals are a shape that is found everywhere in nature and, for me at least, they are mesmerizing to look at and to understand. Inspired by the video we watched on randomness in digital art, I wanted to find an “organic” yet “random” way of showcasing the kantuta. The spiral has movement and flow without breaking its structure or bringing chaos. Moreover, it has such a unique presence, it almost calls the viewer to follow its path, and it feels like you’re watching something alive.

That’s why, and as I promised myself in the last exercise, I wanted to challenge myself, so I looked up many tutorials on how to create spirals in p5.js.

Run it and Click it!

Process

Most of my learning for this project came from these video tutorials on YouTube by Strive Math. First, I had to learn about transformations and translations in p5.js. It has to do with the coordinates in the canvas you’re creating. So, when you translate, you move the entire coordinate plane up, down, left, or right. And when you transform, you’re rotating the entire coordinate plane at an angle that you choose (you must select if the angle will be measured in degrees or radians first). It rotates clockwise if the number is positive and counterclockwise if it’s negative.

With transformations, you rotate the axis around the center point you chose when you did the translation. So, with this, I first learned how to draw a simple circle using these concepts. For example, if I translate the origin so it is right in the middle of the canvas, and I keep making this coordinate plane rotate clockwise while drawing a dot somewhere that is not the origin, the dot will keep moving with the coordinate plane and trace a circle when the coordinate plane completes a full 360° rotation.

This is how the code for that looks (this is no longer in code as such since it was just to practice and understand how it works):

function setup() {
  createCanvas(600, 600);
  angleMode(DEGREES)
}

let angle = 0

function draw() {
  translate(width/2, height/2)
  rotate(angle)
  angle++
  point(30,0)
}

The next step, was to think how this could turn into a spiral. Since the circle shape that I made is actually just a point following a path that is determined by the radius of the circle, if I increase the radius of the circle, and as the point moves more the radius also increases more, this will create a path of a spiral. Therefore now the code will look like this:

let angle = 0
let radius = 0

function draw() {
  translate(width/2, height/2)
  rotate(angle)
  angle+= 31
  radius+= 0.4
  strokeWeight(6)
  point(radius,0)

Now I can control the way the spiral looks by playing with the amount of degrees the angle of the coordinate plane is going to change every time and how wide will the radius of the circle increase be. A small issue with this was that the frame rate of how fast or how slow the points would appear will sometimes be too slow and I wanted to change that. Therefore, just like in the tutorial that i watched, I inserted a for loop to control the frame rate of everything, and for it to not change and save the sate of the canvas I used the ‘push’ and ‘pop’ commands so that the origin always stays in the center of the canvas and doesn’t move every time the for loop repeats.

As I said, I wanted to implement the concept of randomness, so I created random variables for the values of the angle and the radius to be able to make a different spiral every time you click on the screen. To make this happen, I added a mousePressed() function that resets the angle and radius to their initial values, generates new random values for the angle increment and radius increment, and clears the canvas:

function mousePressed() {
  angle = 0;               
  radius = 0;             
  angleValue= random(300, 3000); 
  radiusValue = random(0.009, 0.2);
  background("black");    
}

This way, every time the canvas is clicked, the spiral starts fresh with completely new random parameters, creating a unique pattern while keeping the interaction simple and intuitive. However, it took me a while to figure out this approach, because at first I tried using a boolean variable and a separate restart function in a more complicated way, and my code would get messy: sometimes the spiral wouldn’t appear, or new spirals would overlap with the old ones. Then I realized, why complicate things? I could just reset the main variables and redraw, and it worked perfectly.

Something I did very intentionally was set the limits of the random value of the angle to very big numbers and the numbers of the radius to very small decimals. I did this because I started playing around with those values and I realized the smaller the radius was the more dense the spiral looked and if the angle was a high number there was more chance of there being more ‘spiral lines’. I liked how this looked because it made the spiral look more like a piece of art. I also changed the background color to black so that the colors of the points would stand out more.

Code I am proud of

Then came the most important part: the color of the kantuta image. I uploaded the image to p5.js and made the spiral match the colors of the pixels by randomly selecting a pixel from the image and using its color for each point on the spiral.

let ix = floor(random(img.width))   
    let iy = floor(random(img.height))  
    let c = img.get(ix, iy)             
    stroke(c)

I’m really proud of this code because it wasn’t easy to get it right at first. I had to change the image I was using because the first one had too much black, which blended with the background and made the spiral almost invisible, and it also took too long to load. Then I realized that I needed to extract the colors pixel by pixel from the image, and I did this inspired by the p5.js example of pointillism, where each point takes the color of a random pixel from the image. This finally permited me to have a spiral that not only looked colorful and vibrant, but also represents the kantuta in a way that felt alive and organic, and I really liked it.

Final Code

//Image variables
let img;

//Image upload
function preload() {
  img = loadImage("kantuta.jpg");
}

//==============
//Setup
//==============
function setup() {
  createCanvas(600, 600);
  background("black")
  angleMode(DEGREES);
  frameRate(80);

  angleValue= random(300, 3000)
  radiusValue = random(0.009, 0.2)

  img.loadPixels(); // allow us to access image pixels
}

//Spiral variables
let angle = 0
let radius = 0

let angleValue
let radiusValue

//===================
//Drawing the spiral
//===================

function draw() {
  //To control the frame rate
  for (let i= 0; i<80; i++){
    
  push()//save the state of our canvas
  
  translate(width/2, height/2);
  rotate(angle);
  angle+= angleValue;
  radius+= radiusValue;
  strokeWeight(4);
    
  //Pick a color from the image
    let ix = floor(random(img.width))   
    let iy = floor(random(img.height))  
    let c = img.get(ix, iy)             
    stroke(c)                          
    
   point(radius,0);
  
  pop()//come back to the old state before 'push'
  }
}

// ===================
// Replay spiral on click
// ===================
function mousePressed() {
  angle = 0;               
  radius = 0;             
  angleValue= random(300, 3000); 
  radiusValue = random(0.009, 0.2);
  background("black");    
}

General Reflection

Overall, I think this project taught me a lot about patience, experimentation, and problem-solving. I also realized how important it is to simplify my approach: sometimes trying too many complicated solutions only slows you down, and the best results come from understanding the core idea and working with it directly.

I’m proud of how the final spiral turned out, not just technically but also conceptually. I feel like it feels alive, vibrant, and connected to something meaningful, which reflects the beauty of the kantuta and the creative process behind it. This project was the hands-on reminder of the video we saw that taught me that coding can be as expressive as painting or drawing, and that combining randomness, structure, and careful choices can create something truly mesmerizing.

Leave a Reply