Assignment 3: OOP Generative Art

Concept:

I was very intrigued with our discussion last on chaotic pieces of art and as I walked around campus for inspiration for this assignment, I noticed that a lot of things in nature are quite chaotic. For instance, tree branches sprout in no particular order or even cobwebs have no particular pattern to them. I wanted to mimic my work through replicating these chaotic traits in nature.

Usually, I go over the top and add some cool interactivity or motion in my assignments, but this time I wanted to keep it simple and draw a still portrait so the viewer can take their time and digest the piece of art.

Thought Process and Code

For this assignment, I decided to draw a chaotic cobweb. I found the shape at which webs were made quite random and intriguing, hence the reason why. Most of the time, spiders tend to make ordered shapes but sometimes it gets chaotic and completely random. I wanted to mimic that randomness.

My initial instinct was to simply draw a bunch of random lines all over each other and that each line would have a random length and random angle of rotation on the cavas when I draw them.

class Web { 
  constructor() {
    this.string_len = random(init_length/2, init_length);
    this.string_ang = random(init_angle/2, init_angle);
  }
  
  drawLines() {
    line(0, 0, 0, this.string_len);
    translate(0, this.string_len);
  }
}

Hence, I drew this, but the preview that came out was essentially just the screen covered. You couldn’t see any lines all you could see was a blank screen and even when I tried using the noLoop() function, it wouldn’t pause it at the correct frame.

Hence, I thought maybe I should add some initial structure to it, hence I created an InitializeWeb() function which would take in the initial number of lines, length of the lines and angle of the lines (all of which are global variables to which the user can change). This function essentially starts to create a bunch of “string” objects from the Web class to create the overall Web structure.

Like all cobwebs, there’s a focal point, so I translated to the center of the canvas and planned to draw an initial set of lines from the center (at random angles). I would do this by creating new objects called “string” of type Web which would have its length and angle parameters as per the constructor.

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

function draw() {
    background(0, 0, 40);
    translate(width/2, height/2);
    InitializeWeb(init_length, init_num, init_angle);
}

function InitializeWeb(length, num, angle) {
    stroke(255, 80, 80);

    for (let i = 0; i < num; i++) {
      push();
      rotate(random(0, 360));    
      string = new Web(length, angle);
      Spread(string, length, angle);
      pop();
    }
}

Then I would draw the lines using the Spread() function where I continue to spread out lines throughout the canvas.

Ideally, I wanted this function to be inside the class as the variables and manipulations inside the function are to deal with the string object. However, it seems that p5js does not support recursion of functions within class definitions. Hence, I just created this function outside of the class.

Post Edit: I did not realize you could call the functions within a class through the “this” keyword, hence yes, you can use recursion of functions within classes. I was just unaware. In this case, I would use this.spread() as a function within the class rather than just another regular function.

function Spread(string, len, ang) {
  string.drawLines();
  
  len *= shrink_factor;
  ang = random(ang-30, ang+20);
  
  if (len > webbyness) {
        push();
        rotate(ang);
        Spread(string, len, ang);
        pop();

        push();
        rotate(-ang);
        Spread(string, len, ang);
        pop();
    }
}

The idea of Spread() is to recursively draw the lines and i’d continuously shrink the length of the lines by some factor. While the length isn’t bigger than a variable I like to call “webbyness” which is kind of like how thick the web structure is, then it will keep printing lines. Eventually, the canvas would be filled with a web like structure which is what I wanted to achieve.

Final Piece:

Concluding Thoughts and Improvements:

Overall, I think the piece looks very chaotic and like I lot of emotion and things are going on in it. It replicates that cobweb like structure and evokes some strange emotion to it even though it’s a still image which actually makes me pretty happy.

I feel that perhaps the density of the webbyness could’ve been evenly distributed throughout the canvas as an improvement.

Also to add some sense of movement if I wanted to, perhaps add some blinking or glistening/fading effects to enhance the emotion and mystery that comes out of my piece.

Assignment 2: Art and Programming

Concept:

Upon watching the video: Casey Rears – Chance Operations, I was quite inspired by the idea of programming fractals. The idea of fractal art has always piqued my interest as it always jelled in between states of chaos and order and it just always looked so mesmerizing. Hence, I decided to go along my assignment by creating a fractal piece of art.

Code and Thought Processes:

When I thought of fractals, my mind instantly went towards shapes such as diamonds, stars and multi-polygon shapes. Hence, after several testing, I decided to create some star like shapes. Upon exploring, p5js does not have a shape for stars, hence, I created a function that would generate a star for me:

function star(x, y, radius1, radius2, npoints) {
  let angle = TWO_PI / npoints;
  let halfAngle = angle / 2.0;
  
  beginShape();
  for (let a = 0; a < TWO_PI; a += angle) {
    let sx = x + cos(a) * radius2;
    let sy = y + sin(a) * radius2;
    vertex(sx, sy);
    
    sx = x + cos(a + halfAngle) * radius1;
    sy = y + sin(a + halfAngle) * radius1;
    vertex(sx, sy);
  }
  endShape(CLOSE);
}

I used this function from https://p5js.org/examples/form-star.html, where it essentially constructs a star shape. The arguments are the x and y coordinates of the shape (which is at the center), and I would have two radius, one for the horizontal shape of the star and one for the vertical shape of the star. I would also have the number of points the star can be. I essentially map the points together to create a star using the unit circle from trigonometry and connecting them together using the vector function.

I knew I was going to overlap my crystals over each other, however I wanted them to have some movement, hence I made them rotate at different speeds. This way it gives this really cool effect where they each sometimes align or sometimes are completely chaotic. It fits well with that chaos/order theme I was going for so it was a great addition. To do this, I created another function called drawCrystals(spin) which would draw a bunch of crystals over each other where spin is just the number of crystals spinning.

function drawCrystal(spin) {  
  for(let i=0; i<spin; i++) {
    rotate(frameCount/-1000);
    
    if (fade<0) fadeAmount=0.005;
    if (fade>255) fadeAmount=-0.005; 
    fade += fadeAmount; 
    fill(0, 0, blue_shades[i], fade);
    
    star(0, 0, ((10*spin + 70) - 10 *i)/2.333, ((10*spin + 70) - 10*i), 4);
  }
}

The size of the shape (determined by the radii) is simply calculated through a series of incremented sizes so that they all look congruent rather than weird shapes and sizes.

I decided to also add a cool fade effect. It’s really awesome because the background is black so it looks like they disappear momentarily and then appear back to life. This fade effect was inspired from another sketch which is linked here: https://editor.p5js.org/remarkability/sketches/rtM08miUD however I tweaked the values so it would fit with my code.

I also filled them with different shades of blue to fill that diamond-ish colouring, plus blue looks cool and is one of my favourite colours.

Finally, in the draw function, I simply just pushed, translated to a random coordinate on the canvas and drew the fractal shape with a random number of fractals and then popped. I repeated this process several times until all the fractals kind of covered the screen. With this, I was happy with my finished product.

Final Sketch:

Overall Thoughts and Improvements:

Overall, I think i’m happy with how it turned out, it was essence I was looking for when I wanted to create my artwork. Although some improvements I could have added are:

  • Perhaps some sort of glistening effect on the fractals.
  • Perhaps a 3D rendering of the fractals.
  • A cool idea would be where the fractals could grow and shrink at random sizes and intervals.
  • Maybe it would be cool is the fractals could move about the canvas to give it some nice lively effect to the art.

Assignment 1: Self Portrait

For my first assignment, we were tasked with creating a self portrait of ourselves using p5js. I’ll be honest, I’d say this was a pretty nice intro and learning experience to p5js and arguably one of the funniest moments i’ve had when it came to coding.

I’ve always done coding with a serious intent and I think that took the fun away from my projects, hence I wanted my portrait to reflect that. Thus, I decided to just wing it and make the funniest, interactive and outgoing portrait I could think of XD.

Portrait:

Idea and Process: 

My initial thought was that I want my portrait to have movement instead of just a static image because then it sort of brings it to life. I first drew myself using some basic shapes such as circles, ellipses, bezier curves etc. However, I had difficulty thinking of how I could incorporate this movement idea with myself.

After thinking and reviewing some of the examples, I figured I could try making my eyes follow the user’s cursor, that way it’s pretty fun and fits that movement aspect. For this idea, I decided to create the pupils at the center of the eye and it would sort of be constrained within the radius of the eye depending on the X and Y coordinate of the user’s mouse. I used some calculations for this as shown below:

circle(103+(0.03*mouseX), 187+(0.03*mouseY), 20);
circle(161+(0.03*mouseX), 187+(0.03*mouseY), 20);

I wanted to have a little bit of fun and add my own humour (pretty cursed) into the portrait so I added the impostor from the hit game Among Us into the portrait cause why not I thought it’d be funny. I used a variety of shapes such as ellipses and rectangles to construct it.

Later on, I decided, why not add a feature for if the user presses the mouse. I didn’t know exactly what to do but I figured I would piece it together as I went along coding.

As time passed I decided it would be funny if the impostor basically turned into some epileptic god, so I used the random() function to continuously change its colour. I also decided to edit my facial features and add golden hair (sort of resembling Goku going super saiyan) to add to the chaos and kinda act like I was ascending.

However, it still looked plain to me, hence, I decided to add some cool flickering stars in the background by using a for loop which would constantly add ellipse-like stars in the background at random points on the canvas as shown:

if(mouseIsPressed) {
   background("black"); 
   for (var i = 0; i < 10; i++) {
       var size = random(5, 15);
       ellipse(random(width), random(height), size, size);
   }
}

Overall Thoughts: 

Overall, I found it quite interesting with how many functions there were. One cool function I found was the translation function (used on the floating among us) which also added to the movement aspect of my portrait.

Dealing with shapes was tricky because I didn’t know which coordinates I had to put them at or where I would have to alter the control points for curves. Hence, I decided to add a sort of coordinate tracker for my cursor because I figured it would be really handy to when where I would like to place all of my shapes and curves, hence I added one on the top left.

One thing I would definitely improve is organizing my code. Most of the functions I used, the arguments were hard-coded and I feel like I could’ve used traits such as width and height to organize my code space. I could have also used functions such as drawFace() or drawClothes() to further organize my code.

Nonetheless, i’m no expert at art but this was a super awesome and fun assignment and I feel like I developed a strong foundation for some of the basic functions used in p5js.