Week 3 Generative Art

Generative Art

This was inspired by one of the things we saw in class. For some reason, I cannot seem to find it, but it was a piece where lines go from a circumference of a circle inwards to fill the circle.

I had a plan in mind to have lines growing out of the center into a circle, but I did not like how it looked, as the lines were too sharp for my preference.

 

So instead I used the noise function to make random dots, on a 360-degree variation.

I wanted to make it look more natural, however, so I decided to also add some cloudy form around it.

When I saw this, I felt like it reminded me of a laptop screen saver, as the circles grow out and it progresses into what it is. Screen savers though, unlike this design above, have different circles it would usually be more than one, so using a random function, I generated the circles starting from a different center point every 100 frameCounts.

That, if I would let go on I would have gotten into a huge mesh after some time, so I called the background function after every 5 circular things are created.

Later I also edited the colors and added an alpha value to make the circles a little easier on the eye.

and to make it a little user-controlled, I called the background function and reset the center with each click on the screen.

 

I also decided to make it a full screen like a real screen saver.

video:

code:

main file:
Circles _circles;

int centerX = 0;
int centerY = 0;


void setup() {
  fullScreen();
  background(0);
  frameRate(10);
  _circles = new Circles(width/2, height/2);
}

void draw() {
  _circles.generate();
  if (frameCount%20==0){
    _circles.cloudy();
  }

  if (frameCount%100==0){
    _circles.setCenter(random(0, width),random(0, height));
  }

  if (frameCount%500==0){
    background(0);
  }
  
}



void mouseClicked(){
  background(0);
  _circles.setCenter(mouseX, mouseY);
}

 

Circle file:
class Circles {

  public float xcenter;
  public float ycenter;

  public float x_pt;
  public float y_pt;

  public int rad;

  public float[][] ptarr = new float[90][2];

  Circles(float _xcenter, float _ycenter) {
    xcenter = _xcenter;
    ycenter = _ycenter;
    rad = 4;
    setupp(30, xcenter, ycenter);
  }

  public void setupp(int num, float x, float y) {
    for (int i=0; i<90; i++) {
      x_pt = x + num*cos((float)radians(i*4));
      y_pt = y + num*sin((float)radians(i*4));
      fill(255, 50);
      noStroke();
    }
  }

  //getters and setters
  public void setCenter(float _xcenter, float _ycenter) {
    xcenter = _xcenter;
    ycenter = _ycenter;
    setupp(30, xcenter, ycenter);
  }

  public void generate() {
    int offset = 30+(frameCount%100)*5;
    float newoffset;
    float newoffset2x;
    float newoffset2y;
    fill(random(100, 200), random(100, 200), random(100, 200), 100);
    noStroke();
    for (int i=0; i<90; i++) {
      newoffset = noise(frameCount + i*0.01)*offset;
      
      newoffset2x= noise(frameCount + i*0.02)*cos((float)radians(i*4));
      x_pt = xcenter + newoffset*newoffset2x;

      newoffset2y= noise(frameCount + i*0.02)*sin((float)radians(i*4));
      y_pt = ycenter + newoffset*newoffset2y;

      circle(x_pt, y_pt, rad);
    }
  }

  public void cloudy() {
    fill(100, 30);

    float new_x = random(xcenter-(frameCount*20)%width/3, xcenter+(frameCount*20)%width/3);
    float new_y = random(ycenter-(frameCount*20)%height/3, ycenter+(frameCount*20)%height/3);

    for (int i=0; i<99; i++) {
      circle(random(new_x-width/10, new_x+width/10), random(new_y-height/10, new_y+height/10), random(40, 80));
    }
  }
}

 

 

 

Week 3: Generative artwork using OOP

Description:

For this week’s assignment, I created a generative artwork using Object-Oriented Programming. Using mainly ellipses, I tried to generate a spiral that contracts and expands continuously and repetitively. 

To improve the program’s clarity and organization, I utilized classes, variables, and a couple of functions.

Setup:

First, I had to set the display window’s size to 640 x 640 (1:1 aspect ratio) to get a square window, then used a pitch-black background.

void setup(){
  size(640, 640);  
  background(0);
}
Class:
Name & Attributes:

I have only used one class named Ellipse which has two float attributes (xradius, and yradius) that respectively store the width and height of the ellipse.

class Ellipse{
  float xradius, yradius;
}
Constructor:

The constructor here takes two float arguments (xradius and yradius) then sets the attributes to those values.

Ellipse(float xradius, float yradius){
  this.xradius=xradius;
  this.yradius=yradius;
}
Functions:

I have used two functions (one to draw a single ellipse, and the other to draw multiple ellipses). The first function takes xradius and yradius as arguments, then proceeds to draw an ellipse. The second is more complicated. In fact, it starts by moving the shapes to the middle of the display window by setting the x-axis offset to width/2 and the y-axis offset to height/2 using the translate() function, then inside the for() loop, the ellipses are generated with an xradius that depends on the frameCount. To get a sort of spiral, the window is rotated with an angle that equals the frameCount.

void build(float xradius, float yradius){
  ellipse(0, 0, xradius, yradius);
}

void build_all(){
  translate(width/2, height/2);
  for (int i=0; i<400; i+=40) {
    float framecount = radians(frameCount);
    xradius = yradius - i*cos(framecount);
    rotate(cos(framecount));
    build(xradius, yradius);
  }
}
draw():

To get a sort of motion, I have set the transparency (alpha) to 85 instead of resetting the background at each frame.

void draw(){
  fill(0,85);
  rect(0,0,width,height);
  stroke(250);
  noFill();
  ellipse.build_all();
}

View post on imgur.com

Whole code:
// Ellipse Class
class Ellipse{
  // Attributes
  float xradius, yradius;
  
  // Constructor
  Ellipse(float xradius, float yradius){
    // Width of the ellipse
    this.xradius=xradius;
    // Height of the ellipse
    this.yradius=yradius;
  }
  
  // Generate one ellipse
  void build(float xradius, float yradius){
    ellipse(0, 0, xradius, yradius);
  }
  
  // Generate all ellipses
  void build_all(){
    // Move the shapes to the middle
    translate(width/2, height/2);
    for (int i=0; i<400; i+=40) {
      // Convert frameCount to rad
      float framecount = radians(frameCount);
      // Change the xradius depending on the framecount 
      xradius = yradius - i*cos(framecount);
      // Rotate the ellipses
      rotate(cos(framecount));
      // Call to the first function
      build(xradius, yradius);
    }
  }
}

Ellipse ellipse;

void setup(){
  size(640, 640);  
  background(0);
  // Create an ellipse
  ellipse = new Ellipse(380,380);
}

void draw(){
  // Add visible motion
  fill(0,85);
  rect(0,0,width,height);
  stroke(250);
  noFill();
  // Generate the ellipses
  ellipse.build_all();
}

Generative Art Piece

Description& Inspiration:

I wanted to create something simple yet eye catching, the first thing that came to mind was something like this, the picture on the  left  is a picture  of   mars,  while  the  right  is  how  I  imagined  I  can  bring  it  to  life  in  processing.

Process:

My focus in this project was creating an organized code and figuring out how to use Object-Oriented Programming rather than creating a complicated design. I started out as follows,  by laying out the needed standard functions such as setup() and draw(). Then I started planning and laying out all the variables I knew I was going to need. Starting out with drawing the actual sphere, the prices was quite long and a bit confusing however, after a lot of research and a lot of help from The Coding Train, I was able to get started. In order to create a sphere like shape (without resorting to the basic sphere function on processing),  I needed a longitude value (which is 'I' in the for loop) and latitude value (which is 'j' in the for loop).

with the above code only, the screen was still blank, in order to continue drawing the sphere the formulas for converting from latitude and logitude to coordinates were needed. Where theta refers to longitude and phi refers to latitude. 
 formulas are as follows :

Then I needed to give motion to the sphere by using rotateX() and rotateY(), then I used point(x,y,z) to actually finish the drawing. 

I also wanted to change the color of the sphere from red to yellow when any key is pressed so I used the mouse clicked for red and mouse pressed for yellow.  


Final Project:

I created two versions: one where I have decreased the detail level of the sphere and how fine the resolution is and one where I increased it.

 

 

This is the increased version:


This is the decreased version:

 

I also really wanted to tidy up my code and make it easy to understand to I created two function, displaySphere() and colorChange(), and added them both two one big function which is runSphere(), so the final code only had sphere.runSphere() in it.

Difficulties:

I would say that this is definitely the most challenging assignment I have gotten in the course so far in my opinion, the actual design was not very easy but what I found most difficult was trying to organize my code and figuring out the class. However, the way my code looks at the end was very worth it, and I will be able to use it later in other projects much easier.




Sources: 
The Coding Train: Spherical Geometry video
Sphere sphere;


void setup(){
  size(600,600,P3D);
 sphere=new Sphere();

}


void draw(){
  background(0);
sphere.runSphere();
 
}
class Sphere{

  float r;
  int total;
float x;
float y;
float z;
float lon;
float lat;
  
  
  Sphere(){
    
  r=200;
  total=100;
  x=r*sin(lon)*cos(lat);
  y=r*sin(lon)*sin(lat);
}
  
  
 
 void runSphere(){
    
displaySphere();
colorChange();
 }


void displaySphere(){
    background(0);
  noFill();
  lights();
  
//I needed a longitute value (which is 'i') and latitude value (which is 'j')
  translate(width/2,height/2);
  for(int i=0;i<150;i++){
 lon=map(i,0,total,-PI,PI);
   for (int j=0;j<150;j++){
   lat=map(j,0,total,-HALF_PI,HALF_PI);
   
 //as per the formulas for converting from latitude and logitude where theta refers to longitude and phi refers to latitude. 
 // formulas are as follows :
 //x=rsin(theta)cos(phi)
 //y=rsin(theta)sin(phi)
 //z=r*cos(theta)
   x=r*sin(lon)*cos(lat);
    y=r*sin(lon)*sin(lat);
    z=r*cos(lon);
    
 //this if for the movement of the sphere (rotation) using mouse events   
   rotateX(mouseY);
   rotateY(mouseX);
  
  point(x,y,z);
}
  }
   }
   
//changing the color from yellow to red by using mouse events as well
void colorChange(){
  if (mousePressed){
     stroke(255,0,0);
   } else if (keyPressed)
   {
     stroke(142,142,62);
   }
}
  }

 


	

Week 3 Assignment – Shanaia Paruthi

Description

Create a generative artwork using Object-Oriented Programming.

Process

I started with setting the background as black. This particular design has a monochrome theme, therefore I have only used the shades of black and white for this assignment.

I started by creating a spiral starting from the centre of the screen using the ellipse shape and sin and cos function to move it. I then created a circle in the centre and put its colour in a loop to give it an effect.

The main part of my design consisted of rotating square in the centre. By putting the square in a loop and a strokeWeight of 10, the square got its special effect. Then I increased the square angle  by 0.1 with every  frame.

VIDEO TO MY WORK:

https://youtu.be/lZz2NTa6jeU

//introducing variables 
float r = 0;
float theta = 0;
float angle;

void setup() {
  //setting the display size
  size(640, 480);
  
  background(0);//black
  fill (256/2,80); //grey
  circle(0, 0, 150);
}

void draw() {
  
  spiral();
  
  center(250);
  
  square();
}

void spiral(){
  //defining x coordinate to move the ellipse
   float x = r * cos(theta);
   //defining the y coordinate to move the ellipse
  float y = r * sin(theta);

  
  noStroke();
  //defning stroke Weight
  strokeWeight(0.5);
  //filling colour
  fill(random(100,150));
  translate(width/2,height/2);
  
  //creating the ellipse
  ellipse(x, y, 30, 30); 

  //increment of angle
  theta += 0.1;
  //increment of radius of the spiral
  r += 0.5;
}

void center(float h) {
  //defining the center circle 
  h-= 5;
  circle(0, 0, h+60);
  //giving it a zooming effect
  for (int i=0; i<angle; i++) {
    fill(100,80);
    line(h, h-2, h, i);
  }
  
  
}
void square(){
  //creating a loop
  for (int i=0; i<100; i++) {
    fill(random(100, 180), 85);
    stroke(0);
    strokeWeight(10);
    //scaling the square
    scale(0.95);
    
    //rotate
    rotate(radians(angle*1.5));
    
    //creating a rectangle
    rect(0, 0, 150, 150);
  }
  //increment of the angle
  angle+= 0.1;
}

 

Ocean Currents (Generative Art) – Jade

 

Description

This work was inspired by an artwork I saw on Youtube. I love the flowing lines, the dynamic movements, and the way it interacts with people.

In this work, I used the concepts of Object-Oriented Programming and the particle system. My favorite part of this project is the interaction with the cursor, that changes both the transparency of the background and the starting point of the particles. Also I added the two perpendicular lines to locate the cursor and to show how the particles change with the move of my mouse.

 

Code

This part is my class of the particles.

 class Particle {               
  float posX, posY, val=0, angle, speed=2;   
  color c;    
  float r, g, b;
    
  Particle() { 
    posX = random(width);
    posY = random(height);
  }
 
  // the main function of the class
  void run() { 
    update();
    add_color();
    check();
    generate();
  }
 
  // update the position of particles
  void update() {     
    float noise_val = noise(posX * 0.005, posY * 0.004, val);    
    val += 0.01;  
    angle = noise_val * TWO_PI;
    
    posX += speed * cos(angle);  
    posY += speed * sin(angle);
    
  }
  
  // when particles in the canvas, draw the particles
  void generate() {
    if (posX > 0 && posX < width && posY > 0  && posY < height) {
        lines();
        ellipse(posX, posY, 2, 2);
    }
  }
  
  // check if the particles are out of edges, so to place them back to the canvas
  void check() {   
    if (posX< 0 || posX > width) 
      posX = mouseX;
    if (posY < 0 || posY > height)
      posY = mouseY;
  }
  

  // generate slightly different blue colors
  void add_color() {
      float col = map(posY, 0, height, 255, 0); 
      c = color(30, col, 255); 
      fill(c);
  }
  
  // the lines intersecting at mouse coordinates
  void lines() {
     stroke(150, 150, 150);
     line(mouseX, 0, mouseX, height);
     line(0, mouseY, width, mouseY);
  }

}

The part below is my main function.

Particle[] particles;     
float trans;     
int nums = 500;
 
void setup() {
  size(300, 600);
  background(#070B46);
  noStroke();
  setParticles();         
}
 
void draw() {
  trans = map(mouseY, 0, width, 0, 50);  // transparency changes with mouseY
  fill(#070B46, trans);  // background    
  rect(0, 0, width, height);
  for (int i = 0; i < nums; i++) {
      particles[i].run();
  }
}
 
// make the particles
void setParticles() {        
  particles = new Particle[nums];  
  for (int i = 0; i < nums; i++) {        
    particles[i]= new Particle();   
  }
 
}-
 
// if pressed, regenerate all the particles
void mousePressed() {
  setParticles();
}

 

Process

I set the canvas to be size(300, 600) because I think this size fits the patterns best, and I think I want to create a bottle-like scene. When running this project, it first randomly generates 500 particles across the canvas. When you move the cursor up and down, it changes the transparency of the background, which results in the change of the density of the particles visually. As the particles strike the edges, new particles will generate at either (x, mouseY) or (mouseX, y). To be visually clearer, I added the two lines to better display where the particles appear, which turns out to be pretty cool. Since quite a few parameters are related to mouseX and mouseY, as you move the cursor around, it may create some artistic patterns and effects. Pressing mouse would regenerate the particles randomly, in other words, refresh the work.

One of the difficulties I encounter was to adjust the parameters of the particles, like their color, speed and angles. It takes time to experiment to achieve my expectation. I initially wanted to make the color change every time the particles are regenerated. So I included the code for color in the void generate() function, but it didn’t work out and only filled in the same color. After a few attempts, the approach I eventually take is to use the map function to make the color change with my mouseY.

The most challenging part is about the class/ struct. After writing different functions, I found it sometimes confusing when putting them together, especially when I wanted to use functions inside another function. As result, I also found it challenging to decide whether this function should be put in draw function or the setup function.

 

Conclusion

I think this project really improves my understanding of class and noise/map functions. And it is always interesting and surprising to see what will come out as I change the parameters. I feel that randomness is really an important part of Processing artworks. Randomness inspires me and leads me during the whole time.

Assignment 3: project oriented programming

inspiration & CONCEPT: Haunting Questions, Bursting Emotions

I intended to create repeating shapes and have them follow around the cursor. The mushrooming question marks describe the unfading nature of problems that never seem to go away. It shows how questions and emotions can loom in our minds and pulsate with time.

VIDEO DEMO

the codes

Twist [] myTwist;            

void setup() {
  size(1280, 720);
  
  //constructor
  myTwist = new Twist[25];
  for (int i=0; i<myTwist.length; i++){
    myTwist[i] = new Twist(i);
  }
}

//EXECUTION
void draw() {
  //background
  for (int i = 0; i < 1280; i += 128) {
    noStroke();
    fill(0+i/64*16*random(-10, 10)*noise(frameCount*0.01),49+i/64,156+i/64, 30);
    rect(0+i, 0, 128, 720);
  }
  
  //bursting emotions (two groups of circles )
  for (int i = 0; i<myTwist.length/2; i++){
    myTwist[i].runTwist();
    
    pushMatrix();               //save current coordinate system to the stack
    translate(50, 75);          //take the anchor coordinates from (0,0) to (width/2, height/2)               
  for (int l = myTwist.length/2; l<myTwist.length; l++ ) {
    tint(255, 156);
    myTwist[l].runTwist();
  }
    popMatrix();                //restore coordinate system
  }
}
//CLASS VARIABLES
class Twist{ 
  float posX, posY;     //inital coordinate of the circles
  float easing = 0.05;  //speed of the circles
  float diameter;       //size of circles
  color circleColor;    //color of the circles
  float speed;          //dictates how fast the circles move
  
//CONSTRUCTOR
Twist(float _speed){
  circleColor = color(200, 100, 100, 30);
  diameter = 100;
  speed =_speed;
}

//FUNCTIONALITY
//executes all functions 
void runTwist(){
  drawCircles();
  sizeCircles();
  drawText();
}

void drawCircles(){
  fill(circleColor);
  noStroke();
 //makes circles follow the cursor
  float targetX = mouseX;
  float dx = targetX - posX;
  posX += dx * easing * speed;
  
  float targetY = mouseY;
  float dy = targetY - posY;
  posY += dy * easing*speed;
  
  circle(posX+random(-10, 10)*noise(frameCount*0.01), posY+random(-10, 10)*noise(frameCount*0.01), diameter);
}

  //generates random question marks and the text in the middle of the circle
void drawText(){
  fill(255);
  text("why", mouseX, mouseY);
  fill(255, 180);
  text("?", random(width)-50, random(height/2)+400);
}

  //controls the size of circles
void sizeCircles(){
     diameter +=3;
  if (diameter>250){
    diameter = 100;
  }
}
}

PROBLEMS

Initially, I tried to create a group of circles that enlarges and shrinks to mimic a heart pulsating with its left ventricle. It does look like it’s pumping and it doesn’t look like a heart to begin with. I ay have to control the speed of the size changing and draw better next time.

Week 3 : Object Oriented Programming

WEEK 3 : OBJECT ORIENTED CYBER FIBER COMPUTER GRAPHIC

INTRODUCTION :

In week 3, we have to code in a more mature and reusable way. For that we learned object oriented programming. With the help of previous knowledge of 2D shapes, lines, arcs, built in functions, and arrays we must write reusable and managed code for computer graphics. We learned this week how to create classes and implement attributes and methods in it to initiate a class object. We have to implement some objects and make them dynamic to give it an animated look. We have to learn how to call functions.

IDEA FOR COMPUTER GRAPHIC:

Nowadays everything is connected, and communication is quick and reliable. The communication of devices today on networks is a paradigm similar to the manner in which body muscle fibers flow. The muscle tissues are connected to each other through small fibers that share the same structure as mesh cyber network in which communication is through different routes in some visible pattern.

CHALLENGES & PROBLEMS :

The graphic I decided to code was creative and it was very hard for me to understand and implement math into my code. It was challenging for me to provide random movements to the fibers to keep the flow. I used the hit and trial approach to check if the translation of objects is in the right direction which was quite time consuming. Giving angles to the fibers to keep them in flow was challenging which extended with some random movements. It was also very challenging for me to implement math equations in order to keep up the shape of fibers to randomly move between the four corners.

PROCEDURE:

The first step I took is to implement and initiate the built-in functions to create the screen for my graphics. I used setup () and draw () functions for that. Then I started implementing my Fiber class which shows pure use of object oriented programming. I initialized important attributes inside the fiber class which later changed their values during different function calls. I used PVector to give each fiber some specific directions which is randomly generated during function calls. Then, I implemented the constructor of fiber class which takes one parameter which is the size of the fiber. The size of the fiber is decided during object initialization outside the class. After that I began working on some major behaviors of graphics such as moving the fibers and the specific directions. As the fiber moves randomly it is generating more fibers. I made functions for the get random rotations and random addition of fibers during movement. In the movefiber() function I set the major attributes of the class. To display the fibers movement, I implemented displayfiber() function.



//for the movement of Fiber
  void MoveFibers()
  {
   Fiberrotationorignal=radians(random(360));
   translatingFiberrotation=MakeFiberRotate(0.1,2.0);
   Fiberaddition=GetMoreFibers(10000);
  }
  
  //for rotation of Fibers
  float MakeFiberRotate(float start , float end)
  {
    return radians(random(start,end));
  }
  
  //for addition of more Fibers
  float GetMoreFibers(int howmuch)
  {
    return random(howmuch);
  }

I used map function in it to transform the values from one range to another. I gave audio-like harmonic movements to additional fibers generated during movement by using noise() function. Subsequently, I angled the fiber vectors which are moving along x and y axes by using cosine and sine functions.
//for displaying Fibers
 void DisplayFiber()
 {
  float noi=map(noise(Fiberaddition),0,1,-20,20);
  direction.x=(size+noi)*cos(Fiberrotationorignal)*cos(Fiberrotationorignal)*cos(Fiberrotationorignal); 
  direction.y=(size+noi)*sin(Fiberrotationorignal)*sin(Fiberrotationorignal)*sin(Fiberrotationorignal);
  Fiberrotationorignal+=translatingFiberrotation;
  Fiberaddition+=0.01;
 }
I initialized global variables for the number of fibers to generate and initialized a global array for it. These are the initial fibers which were generated during movement. In setup () function I set the color mode to HSB to give hue, saturation and brightness to fibers strokes. I initiated the fibers in 2 halves with different sizes. We can see this in for () loop in setup function.
// Main setup functions to get screen size
void setup()
{
  //drawing screen width and height
  size(640,500);
 
  colorMode(HSB,360,100,100);
  
  stroke(255);
  
  for(int i=0;i<N;i++)
  {
    if(i<N/2)
    {
      p[i]=new Fiber(180);
    }
    else 
    {
      p[i]=new Fiber(230);
    }
  }
  
}
Then, in draw function I made use of the display function to show the movement of fibers along x and y axis. I used translate function to put my graphics on the center of the screen. To give different strokes to different fibers and initializing of fiber in specific direction, I used stroke and line function in nested for loop which runs for N times as long as all fiber objects displayed on the screen. The draw function is looping unlimited times and every time the fibers are being placed in new angles directions.

// For drawing loop of fibers
void draw()
{
  colorMode(RGB);
  background(0);
  colorMode(HSB,360,100,100);
  translate(width/2,height/2);
  
  for(int i=0;i<N;i++)
  {
   p[i].DisplayFiber(); 
  }
  
  for(int i=0;i<N;i++)
  {
   for(int j=i+1;j<N;j++)
   {
     
    if(p[i].direction.dist(p[j].direction)<120)
    {
      stroke(map(p[i].direction.dist(p[j].direction),0,80,50,200),100,100);
      line(p[i].direction.x,p[i].direction.y,p[j].direction.x,p[j].direction.y); 
    }
    
   }
  
}
  
}

FINAL WORK:

Below IS the code work for my computer graphic:

class Fiber
{
  //size of Fiber
  float size;
  
  //orignal rotation of Fiber cluster
  float Fiberrotationorignal=0;
  
  //for Fiber movement rotation
  float translatingFiberrotation;
  
  //direction of fiber
  PVector direction=new PVector();
  
  //for adding more Fibers in cluster
  float Fiberaddition;

  //constructor for Fiber
  Fiber(float s)
  {
   size=s;
   MoveFibers();
  }
  
  //for the movement of Fiber
  void MoveFibers()
  {
   Fiberrotationorignal=radians(random(360));
   translatingFiberrotation=MakeFiberRotate(0.1,2.0);
   Fiberaddition=GetMoreFibers(10000);
  }
  
  //for rotation of Fibers
  float MakeFiberRotate(float start , float end)
  {
    return radians(random(start,end));
  }
  
  //for addition of more Fibers
  float GetMoreFibers(int howmuch)
  {
    return random(howmuch);
  }
  
  //for displaying Fibers
  void DisplayFiber()
  {
   float noi=map(noise(Fiberaddition),0,1,-20,20);
   direction.x=(size+noi)*cos(Fiberrotationorignal)*cos(Fiberrotationorignal)*cos(Fiberrotationorignal); 
   direction.y=(size+noi)*sin(Fiberrotationorignal)*sin(Fiberrotationorignal)*sin(Fiberrotationorignal);
   Fiberrotationorignal+=translatingFiberrotation;
   Fiberaddition+=0.01;
  }
  
}




//Number of Fibers
int N=100;

//fibers array
Fiber p[]=new Fiber[N];




// Main setup functions to get screen size
void setup()
{
  //drawing screen width and height
  size(640,500);
 
  colorMode(HSB,360,100,100);
  
  stroke(255);
  
  for(int i=0;i<N;i++)
  {
    if(i<N/2)
    {
      p[i]=new Fiber(180);
    }
    else 
    {
      p[i]=new Fiber(230);
    }
  }
  
}

// For drawing loop of fibers
void draw()
{
  colorMode(RGB);
  background(0);
  colorMode(HSB,360,100,100);
  translate(width/2,height/2);
  
  for(int i=0;i<N;i++)
  {
   p[i].DisplayFiber(); 
  }
  
  for(int i=0;i<N;i++)
  {
   for(int j=i+1;j<N;j++)
   {
     
    if(p[i].direction.dist(p[j].direction)<120)
    {
      stroke(map(p[i].direction.dist(p[j].direction),0,80,50,200),100,100);
      line(p[i].direction.x,p[i].direction.y,p[j].direction.x,p[j].direction.y); 
    }
    
   }
  
}
  
}

CONCLUSION:

This assignment gave me the opportunity to learn object-oriented programming, how to define objects, and different ways to use them to sketch different objects. I learned how to manage the complex code and how to enhance the reusability of code during processing programming. I also learned more knowledge of how to give different angles to objects and how to map one range of values to another range to visualize some useful pattern. I also learned how to use arrays and array indexes to display different objects. I benefitted more in terms of knowledge and the learning of new aspects with this assignment by using arrays inside the for loop.

 

The Moon Of Neon Dandelions

This week’s project of creating generative art was really fun and interesting as I had a clear vision of what I wanted to achieve from the beginning of the process. I noticed that initially, as I started looking for inspiration for generative art online,  I was gripped by art that depicted nature in one way or another. Daniel Brown had a piece with flowers and the bright colors on it were something I wanted to have in my work in addition to elements of nature. Here’s the work:

Hybrid Landscapes by Daniel Brown

As I brainstormed, I finalized on an idea of creating a piece contemplating what’s on the other side of the moon – the far side that we never get to see. I wanted to begin with something very natural, something that looks like the moon, and then transition that to my wacky thoughts on the question to create an experience for the person who views the work.

The Moon

I began looking for works that have already achieved creating a realistic moon using processing but unfortunately, I couldn’t find anything. I didn’t want to give up on the idea of creating a realistic moon and I played around with processing to see if I could get close. This is when I came across a print by Anders Hoff’s:

Anders Hoff’s Inconvergence

The circle is made of a lot of lines to create a planet-like texture and I found this idea very intriguing and I decided to use this because his print looked like a planet, so my idea was that I could create something that resembled the moon. This concept of creating something that looks natural entirely out of straight lines was one of the most favorite things that I learned from this week. The idea was to connect random points of the circle with lines and to get patterns and I restricted the angles of the lines to different ranges over time. For the parameters of the line, I randomized the angles and took the sine and cosine of it, multiplied it by the radius of the circle to obtain points on the circle. This took some time to figure out because my positions kept showing up incorrectly even though mathematically it should be on the circle. Finally, I realized that I made a mistake with the radius, I had used diameter instead of it. 

In the background, I put in stars at first but I didn’t quite like how it looked. In the end, after trying out different things, I ended up creating this depiction of stars when photographed in a timelapse or a star shower. I used lines for the same.

My version of the moon

 

Neon Dandelions

After many many extreme ideas on what to put on the other side of the moon, ranging from cheese to flowers, I finalized on making them be made out of neon dandelions. I was intrigued by the shape of dandelions and wanted to work on making one, so I decided to make my moon be made of dandelions. My idea was to create this effect of getting gripped into the art as the moon gets constructed and then creating a swift transition to hallucinations where the neon elements appear, mimicking the process of when you get too carried away into something, you start imagining things. I used bright colors of yellow, purple, and pink.

I used a class for organizing my dandelions. It had the following features: X and Y coordinates for a position, the radius of the dandelion, the color of the dandelion, an array of colors. It had a constructor to initialize these positions, the color, and the radius. It had the functions of drawing dandelions and also a transition effect to show the transition from the moon to neon dandelions. There is a shadow of the moon in the transition and as an effect of one looking at the moon for a long time, you will see an illusion of a darker circle nearby over the neon lights (if you look at it long enough) which was a fun addition to the visual experience. 

I end the visuals with a quick blackout. 

I started off with the idea of presenting the other side of the moon by having the moon suddenly rotating to reveal the neon dandelions, but given that I made the moon by drawing lines one over the other, I couldn’t figure out a way to retain the idea of lines creating the moon and the rotation effect. I tried the 3d rotation in one of my trials, but it didn’t look quite as realistic as to how it did for a 2d version of the moon with lines. Here’s a video of the final output and the code is below that:

Code:

Dandelion[] dandelions = new Dandelion[500];
float radius=150;
float count=0;


color c1 =  #FFEB00; //yellow
color c2 = #5600CC; //purple
color c3 = #FF01D7; //pink




void setup() {
  size(640, 480);
  background(0);
  frameRate(500);
  
  //calling constructor to create Dandelion objects - colors are randomly assigned from the array of colors 
  for (int i=1; i<=dandelions.length; i++) {
    dandelions[i-1] = new Dandelion(int(random(3)));
  }
}

void draw() {
  
  //creating the moon scenery
  if (frameCount<3000) {
    stroke(202, 202, 202);
    moon();
    stars();
  }

  //transition to the "other side" of the moon - of neon dandelions
  if ((frameCount>=3000) && (frameCount<3010 )) {
    delay(100);
    for (int i=1; i<=dandelions.length; i++) {
      dandelions[i-1].transition();
    }
  }

 //momentary blackout
  if (frameCount==3010) {
    background(0);
  }

//dandelion moon
  if (frameCount>3005 && frameCount<6000 ) {
    for (int i=1; i<=dandelions.length; i++) {
      dandelions[i-1].dandDraw();
    }
  }


//final blackout
  if ((frameCount>=6000)) {
    background(0);
  }
}



void moon() {
  float i=random(0-count*PI/20, PI/20); //randomized angle of first line - the angles are restricted to give a patterned effect and it increases as frameCount increases
  float j=random(i, PI/20); //randomized angle of second line
  strokeWeight(0.1); //thinner strokes
  
  pushMatrix();
  translate(width/2, height/2);
  line((sin(i)*radius), (cos(i)*radius), (sin(j)*radius), (cos(j)*radius)); //gives chords
  if (frameCount%5==0) {
    count++;
  }
  popMatrix();
}

//shooting stars effect or a stars timelapse
void stars() {

  fill(255, 255, 255);
  stroke(255, 255, 255);
  float i = random(0, width);
  float j=random(0, width);
  line(i, j, i+40, j+20);
  rotate(90);
  delay(5);
  fill(0);//graying it out
  line(i, j, i+40, j+20);
  rotate(-90);
}

Dandelion Class –

class Dandelion{
 float posX;
 float posY;
 float dandRad; //radius of dandelion
 float colorPick;
 color[] colors ={c1, c2, c3}; 
 color dandColor;

 
 //constructor
 Dandelion(int colorPick)
 {  
   dandColor=colors[colorPick]; 
   
   posX=random(width/2-150,width/2+radius);
   posY=random(height/2-150,height/2+radius);
   
   //while condition to get points within the circle
   while(((posX- width/2)* (posX- width/2))+ ((posY - height/2)*(posY - height/2) )>=(radius*radius))
   { 
     posX=random(width/2-150,width/2+radius);
     posY=random(height/2-150,height/2+radius);
   }
   dandRad=5;
 }
 
//draw individual dandelions 
 void dandDraw(){
  fill(dandColor);
   //circle(posX,posY,dandRad);
   stroke(dandColor);
   strokeWeight(0.5);
   float l=random(20);
   line(posX,posY,posX+random(-l,l),posY-random(-l,l));
  
  }
  
  
//transition
  void transition(){
    fill(dandColor);
   stroke(dandColor);
   strokeWeight(0.5);
   float l=random(20);
   line(300,200,300+random(-l,l)*frameCount*0.5,300-random(-l,l)*frameCount*0.5);
}
}

 

References

http://danielbrowns.com/

https://img.inconvergent.net/print/706dbb4.html

 

Week 3: Generative Artwork

For this week’s task, I wanted to make a representation of a mathematical rule using “bubbles”.  However, I quickly ran into lag issues. Originally, I wanted to create 100 objects, but the program started lagging at a much lower count. I ended up discarding the original idea and started experimenting with other features such as random motion and color.

The sketch lags at 5 objects.

The sketch is less laggy at 1 object.

The bubbles start at a random colors of 7 previously determined colors. They then transition and span through the rest of the colors with the help of lerpColor(). The motion of the bubbles is randomized through noise() and is mapped on the entire screen. The size of the bubbles is also randomized on a predetermined range.

Challenges/concerns:

My code is relatively simple but the program lags a lot. I’m not sure what causes this lag. My guess is repeatedly calling noise() is inefficient, but I’m not sure how to optimize it while retaining the randomness of motion and color for all objects.

Code:

Thing[] things;
int thingsCount;


void setup() {
  size(640, 480);
  
  thingsCount = 5;
  
  things = new Thing[thingsCount];
  for (int i=0; i<things.length; i++) {
    things[i] = new Thing(random(0,width), random(0,height));
  }
}

void draw() {
  background(0);
  
  for (int i = 0; i<things.length; i++){
    things[i].display(); 
  }
}
class Thing {
  float x, y;
  float diameter;
  float tx, ty;
  float colorStage;
  int color1, color2, currColor;
  color[] palette;
  int colorFrequency;

  Thing(float xPos, float yPos) {
    x = xPos;
    y = yPos;
    diameter = random(70, 150);
    tx=random(0, 10000);
    ty=random(0, 10000);
    colorStage = 0;
    palette = new color[]{color(246, 0, 0), color(255, 140, 0), color(255, 238, 0), color(77, 233, 76), color(55, 131, 255), color(72, 21, 170)};
    currColor = int(random(0, 6));
    colorFrequency = 10;
  }

  void motion() {
    x = map(noise(tx), 0, 1, 0, width);
    y = map(noise(ty), 0, 1, 0, height);
    tx += 0.04;
    ty += 0.04;
  }

  color updateColor() {
    colorStage = (colorStage+colorFrequency) % 100;
    if (colorStage == 0) {
      currColor++;
    }
    currColor = currColor % palette.length;
    color1 = palette[currColor];
    if (currColor + 1 >= palette.length) {
      color2 = palette[0];
    } else {
      color2 = palette[currColor+1];
    }

    return lerpColor(color1, color2, colorStage/100);
  }

  void display() {
    color fillColor = updateColor();
    fill(fillColor);
    motion();
    stroke(255);
    ellipse(x, y, diameter, diameter);
    filter(BLUR, 8);
  }
}

 

Quite Geometric Tornado

For this week, I created a generative art piece using Processing. The project involved creating a simplistic art piece while implementing Object-oriented programming principles. My artwork includes a spiral, sort of Fibonacci spiral, using rectangles that have a random stroke color with fixed opacity and no fill.

Here are some images at different times into the artwork along with a video:

 

 

 

 

 

 

 

 

 

 

 

The design may seem like something very complex and difficult to implement but it actually is very simple. The only difficulty I encountered was when trying to implement it using OOP. Initially, it just would not work as intended. So, I started off by writing code in one piece and then sectioning it out. After that, I made the class and defined different functions and then played around with values to find some designs that I really like. Additionally, this time I worked on adding interactivity within the art. For this design, the user can choose to continue the spiral in the opposite direction once it has already ended. As its layout and final outcome is dependent on user liking, once the anti-clockwise spiral has completed, user can hold the mouse as long as they want until they achieve their final design.

I would happily say that this project has by far been the most fun. Even after deciding on a design initially, I tweaked the variables several times and found myself staring at amazing generative art on screen for an hour.

Here is the code for the art:

Spiral myspiral;

void setup(){
  size(600,600);
  background(0);
  noFill();
  rectMode(CENTER);
  frameRate(25);
  myspiral = new Spiral();
}

void draw(){
  //change to clockwise rotation once an anticlockwise spiral is completed
  //mouse is held
  if(mousePressed && myspiral.rect_height<=0){
    myspiral.draw_clockwise();
  }
  else{
    myspiral.draw_anticlockwise();
  }
}

public class Spiral{
  float rect_width;
  float rect_height;
  int change_width;
  int change_height;
  int initial_height;
  
  Spiral(){
    initial_height = 1500;
    rect_width = 0;
    rect_height = 1500;
    change_width = 3;
    change_height = 5;

  }
  
  void draw_anticlockwise(){
    if (rect_height>0) {
      //make it pivoted at center
      translate(width/2,height/2);
      //angle of rotation
      rotate(rect_width + noise(rect_width*0.01));
      //random color fill, fixed transparency
      stroke(random(255),random(255),random(255),100);
      //spiral series of rectangles
      rect(0,0,1080-rect_width, rect_height);
      //updating change
      rect_width += change_width;
      rect_height -= change_height;
    }
  }
  
  void draw_clockwise(){
    if (rect_height <= 0 && rect_height >= (-1 * initial_height)) {
      //make it pivoted at center
      translate(width/2,height/2);
      //angle of rotation
      rotate(rect_width - noise(rect_width*0.01));
      //random color fill, fixed transparency
      stroke(random(255),random(255),random(255),100);
      //spiral series of rectangles
      rect(0,0,1080 + rect_width , rect_height);
      //updating change
      rect_width -= change_width;
      rect_height -= change_height;
    }
  }
  
}