Week 4: generative typography

Description:

Creating a generative typography/text output.

Inspiration:

For this week’s assignment, I tried to remake the Digital Rain from the Matrix movie which consists of downward-flowing green characters representing the activity of the virtual environment of the Matrix on screen.

Process:

I have used two main classes: the first one represents a single character whereas the second class represents a combination of characters (vertical series of characters).

Let’s start with the first one. The “Letter” class includes a single function in addition to the constructor. The constructor takes two arguments representing both the x and y coordinates and randomly generates a character (Japanese character) using the ASCII table codes. Round() is used to find the closest integer, whereas the create() function prints the character on the display window.

// Letter class
class Letter{
  // Attributes
  char character;
  int xcoord, ycoord;
  
  // Constructor
  Letter(int xcoord, int ycoord){
    // x-coordinate
    this.xcoord=xcoord;
    // y-coordinate
    this.ycoord=ycoord;
    // Randomly generates a Japanese character (letter)
    character= char(round(random(12448, 12543)));
  }
  
  void create(){
    // Prints the character on the display window
    text(character, xcoord, ycoord);
  }
}

The second class representing the combination of characters includes two functions in addition to the constructor. One of its attributes is an array of “Letter” objects, which gets initialized in the constructor. I used a for loop to add the characters to the array, with the coordinates depending on the font size. The steps variable is used for the combination’s movement on the screen and is randomly chosen (between 5 and 10).  The generate() function is mainly a for() loop that goes through the combination (array) and prints every character keeping in mind that the first character’s (the one at the bottom) color is lighter than the other ones. The gradient was achieved using transparency (alpha). The move() function moves the combinations to the bottom of the screen and checks when it disappears so that it can be taken to the top again.

// Combination class
class Combination {
  // Attributes
  ArrayList<Letter> combinations;
  int steps, startingpoint;
  
  // Constructor
  Combination(int xcoord, int ycoord){
    combinations = new ArrayList<Letter>();
    startingpoint = ycoord;
      
    // Create the Letters and add them to the array
    for(int ycoord2=startingpoint; ycoord2<FontSize*round(random(10,25))+startingpoint; ycoord2+=FontSize){
      combinations.add(new Letter(xcoord, ycoord2));
    }
    // Steps or Speed of the combination
    steps = round(random(5,10));
  }
  
  void generate(){
    for(int i=0; i<combinations.size(); i++){
        // Change the color of the text to green
        fill(text_color, i*15);
        // Make the first char's color lighter
        if (i==combinations.size()-1){
          fill (firstchar_color);
        }
        // Print the letters
        combinations.get(i).create();
        // Move the combination
        move(i);   
    }
  }
  
  void move(int i){
    // Check when the combination leaves the screen 
    if (combinations.get(0).ycoord>height){
      for(int j=0; j<combinations.size(); j++){
        // Get the combination to the top
        combinations.get(j).ycoord=-FontSize*(combinations.size()-(1+j));
      }
    }
    // Move the combination
    combinations.get(i).ycoord += steps;
  }
}

In the Setup() function, I set the size to 854 x 480, and the textAlign to the center top, and I changed the font to “Courier New”. Then using a for loop, I added all the generated combinations to the main array.

void setup(){
 size(854, 480);
 background(background_color);
 textAlign(CENTER, TOP);
 F= createFont("Courier New", FontSize);
 textFont(F);
 
 // Add all the combinations to the array
 Combinations = new ArrayList<Combination>();
   for(int i=10; i<width-10; i+=FontSize){
     // Set the Y coordinate randomly
     Combinations.add(new Combination(i,round(random(0,height-200))));
   }
 }

The draw() function resets the background and prints the characters.

void draw(){
  // Reset the background
  background(background_color);
  // Print all the characters
  for (int i=0; i<Combinations.size(); i++){
    Combinations.get(i).generate();
  }
}

View post on imgur.com

Full Code:

PFont F;
int FontSize = 20;
color background_color = #161d20;
color text_color = #20c950;
color firstchar_color = #82e2a3;
ArrayList<Combination> Combinations;

// Letter class
class Letter{
  // Attributes
  char character;
  int xcoord, ycoord;
  
  // Constructor
  Letter(int xcoord, int ycoord){
    // x-coordinate
    this.xcoord=xcoord;
    // y-coordinate
    this.ycoord=ycoord;
    // Randomly generates a Japanese character (letter)
    character= char(round(random(12448, 12543)));
  }
  
  void create(){
    // Prints the character on the display window
    text(character, xcoord, ycoord);
  }
}

// Combination class
class Combination {
  // Attributes
  ArrayList<Letter> combinations;
  int steps, startingpoint;
  
  // Constructor
  Combination(int xcoord, int ycoord){
    combinations = new ArrayList<Letter>();
    startingpoint = ycoord;
      
    // Create the Letters and add them to the array
    for(int ycoord2=startingpoint; ycoord2<FontSize*round(random(10,25))+startingpoint; ycoord2+=FontSize){
      combinations.add(new Letter(xcoord, ycoord2));
    }
    // Steps or Speed of the combination
    steps = round(random(5,10));
  }
  
  void generate(){
    for(int i=0; i<combinations.size(); i++){
        // Change the color of the text to green
        fill(text_color, i*15);
        // Make the first char's color lighter
        if (i==combinations.size()-1){
          fill (firstchar_color);
        }
        // Print the letters
        combinations.get(i).create();
        // Move the combination
        move(i);   
    }
  }
  
  void move(int i){
    // Check when the combination leaves the screen 
    if (combinations.get(0).ycoord>height){
      for(int j=0; j<combinations.size(); j++){
        // Get the combination to the top
        combinations.get(j).ycoord=-FontSize*(combinations.size()-(1+j));
      }
    }
    // Move the combination
    combinations.get(i).ycoord += steps;
  }
}

void setup(){
 size(854, 480);
 background(background_color);
 textAlign(CENTER, TOP);
 F= createFont("Courier New", FontSize);
 textFont(F);
 
 // Add all the combinations to the array
 Combinations = new ArrayList<Combination>();
   for(int i=10; i<width-10; i+=FontSize){
     // Set the Y coordinate randomly
     Combinations.add(new Combination(i,round(random(0,height-200))));
   }
 }

void draw(){
  // Reset the background
  background(background_color);
  // Print all the characters
  for (int i=0; i<Combinations.size(); i++){
    Combinations.get(i).generate();
  }
}

 

 

 

2 thoughts on “Week 4: generative typography”

  1. Very nice job Badr. Did you use any sources as references or did you write it from scratch? Nice use of the ArrayList (we haven’t covered it) and good job on fading the fill.

Leave a Reply