For this assignment, we were asked to create a generative text or data visualization piece. I’m interested in both, but I especially wanted to experiment with text. In the beginning, I wanted to create some form of a playful horoscope generator but the structuring of words, their sentence placement, and concepts such as context-free grammar were a little bit too difficult to understand.
Instead, I created a piece where there is a “net” of letters, and you have to click on the sketch to generate the word “net”. In the beginning, I thought of adding a scoreboard and turning it into a game where every time you generate the word, you earn a point–– but apart from the fact that it’s tricky, I realized it would defy the purpose of the sketch being a simple play on words where the user interaction is somewhat open-ended.
You can also refresh the letters by pressing the spacebar, the first press removes all the letters and the second press will rearrange them.
Here is the end result (I updated the video):
And here is an Arabic version:
And here is the code:
//Source: textArrayClass3-Bounce by Taylor Hedum on OpenProcessing String[] character = {"N", "T", "E", "N", "T", "E", "T", "T", "T", "N", "E", "T", "N", "E", "T", "N", "E", "T", "N", "T", "E"}; // //"E", "B", "E", "E", "B" //String[] character = {"N", "E", "T"}; //String[] character = {"ش", "ب", "ك", "ة", "ش", "ب", "ك", "ة", "ش", "ب", "ك", "ة", "ش", "ب", "ك", "ة"}; int tSize = 36; ArrayList<Chara> charas = new ArrayList<Chara>(); int charaLim = character.length; //int charaLim = 50; int randoChara; float spring = 0.3; float gravity = 0.1; float friction = -0.9; int charaCounter; boolean showLetters = true; //PImage bg; void setup() { size(500,500); textSize(tSize); textAlign(CENTER); //frameRate(4); for (int i=1; i<charaLim+1; i++) { //used to generate random character in character array randoChara = int(random(0, character.length)); //bg = loadImage("8.png"); //add all characters in character array to list of characters to get initial bouncing going charas.add(new Chara(i, randoChara, width/(charaLim+1)*i, random(height/2), tSize)); } } void draw() { background(220,220,220); for (int i = 0; i < charas.size(); i++) { Chara chara = charas.get(i); chara.collide(); chara.move(); chara.display(); } if (mousePressed) { //addOne(); } for (int i = charas.size(); i > 0; i--) { //starts deleting characters when the set limit of characters is reached //deletes character at the beginning of list, the oldest character so to speak if (charas.size() > charaLim*2) { deleteOne(1); } } } void mousePressed() { addOne(); } //adds new character upon mousePress void addOne() { randoChara = int(random(0, character.length)); //passes MouseX & MouseY to class constructor so that character is first drawn where the mouse is charas.add(new Chara(charas.size()+1, randoChara, mouseX, mouseY, tSize)); } void deleteOne(int delid) { //removes first character in arrayList since delid is always passed as 1 charas.remove(delid-1); //moves up the other character's IDs by one for (int i = delid-1; i<charas.size(); i++) { Chara chara = charas.get(i); chara.reOrder(); } } void keyPressed(){ if (key == ' '){ showLetters = !showLetters; } } class Chara { int id; int whichChara; float x, y; float diameter; float vx = 0; float vy = 0; float xx = random (0, 500); float xS; int offSet = 250; float r; float rd = 1; Chara(int idint, int randoChara, float xin, float yin, float din) { id = idint; whichChara = randoChara; x = xin; y = yin; diameter = din; r = random(width/4, width/2); } void collide() { for (int i = 0; i < charas.size(); i++) { Chara others = charas.get(i); if (others != this) { float dx = others.x - x; float dy = others.y - y; //pythogonal distance float distance = sqrt(dx*dx + dy*dy); //draws line between characters if they're close enough float minDist = others.diameter/4 + diameter/4; if (distance < minDist*8) { line(x, y, others.x, others.y); } //makes characters bounce of each other if they come within minDist of each other if (distance < minDist) { float angle = atan2(dy, dx); //angle determined by atan2 and distance between characters float targetX = x + cos(angle) * minDist; float targetY = y + sin(angle) * minDist; //acceleration float ax = (targetX - others.x) * spring; float ay = (targetY - others.y) * spring; vx -= ax; vy -= ay; others.vx += ax; others.vy += ay; } } else { fill(0); } } } void move() { vy += gravity; x += vx; y += vy; //if character hits/goes past right sides of the canvas, //reset x so it seems to bounce off the edge of canvas, //then change direction of x-movement if (x + diameter/2 > width) { x = width - diameter/2; vx *= friction; //likewise but for left side of canvas } else if (x - diameter/2 < 0) { x = diameter/2; vx *= friction; } //likewise but for height if (y + diameter/2 > height) { y = height - diameter/2; vy *= friction; } else if (y - diameter/2 < 0) { y = diameter/2; vy *= friction; } } void display() { fill(0); //if showLetters is true (toggled by space bar), draw the letter if (showLetters) { text(character[int(whichChara)], x, y+diameter/3); } stroke(135,206,235); strokeWeight(1); } void reOrder() { id-=1; } }