Generative Text: Net

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;
  }
}

 

Response: “Digitizing Everything”

I liked how simple and straightforward this reading was, and I was especially drawn to the concept of the network effect that the author referred to in relation to the navigation app Waze. Essentially, the network effect is a “situation where the value of a resource for each of its users increases with each additional user.” So as the amount of users increases, the overall quality of the app increases, and this is because user input is crucial to the accuracy of the app’s results. User input, in this instance, does not only mean manual information provided by users (typing in traffic updates, warnings of accidents, etc.), it also means gathering information from each mobile device’s sensors, processors, and transmitters.

Another interesting, relevant point raised in the chapter was the idea that “new ideas yield new recipes”. The author uses the example of Waze to contextualize the idea of using layers and generations of digitization within the application. Here, the oldest layer would be digital maps, then GPS location information, then social data. Social data refers to the point raised above about the network of everything and how users directly contribute information about various factors affecting one’s transportation from A to B, almost like crowdsourcing data. After social data comes sensor data, which utilizes every car using the app to collect data. This is where sensors, transmitters, and processors come to play. This data is calculated and converted into the app to help people find the quickest, most reliable routes, amongst other services.

So, Waze used an already existing technology or system: GPS navigation. However, they increased its potential to a very great degree by adding two more layers to the system: social data, and sensor data. I think this is a very important aspect of modern-day innovation. Technology has come a far way, and sometimes we become too pre-occupied with the idea of creating entirely new technology, or finding brand new breakthroughs, that we don’t think of the ways we can massively improve already existing technology with our newly-found knowledge and capabilities.

 

 

Response: “Design Meets Disability”

Design depends largely on constraints.

There’s a preconceived belief about discretion and invisibility being the priority in designs for disability, but in this chapter, to argue against this, the author proposes the example of eyeglasses, and how they’ve become not only accepted but also sought after as fashion statements. This acceptability is not due to their invisibility, and their ability to blend discreetly with a human’s features, etc. but that does not mean that some people do not still opt for invisibility, seeing as many people use contact lenses. However, the significance of this lies in the fact that people use both. Even when an option for complete invisibility exists, people still choose to use glasses.

So how can we design for disability, without allowing the product to become a stigma of some sorts?

The author made an interesting point about semantics or terminology in relation to design. He explains how eyeglasses are called “eyewear”, which suggests that you wear spectacles rather than just use or carry them, in a way, “wearer sets up a different relationship between the designer and the person being designed for” and this changes the perspective of prescription from “medical model” to “social model”, which is what destigmatizes medical design and allows it to become a part of the social sphere, in a way. It becomes a form of fashion, a statement, where you’re able to use your own style and customize its use based on your taste.

Towards the end, the author also mentions the importance of simplicity, as opposed to being “all things to all people”, which I whole-heartedly agree with. Especially because cognitive accessibility is an important yet overlooked aspect of disability design, perhaps because it is harder to quantify than say, disability on the basis of sight or hearing. But simple products are the most culturally and cognitively inclusive. (p.85)

Art Using OOP: Abu Dhabi From Day to Night

For this assignment, we were asked to create a piece of art or a game using object-oriented programming (OOP). I immediately thought of re-creating some significant piece of art using processing and adding randomized, generative elements to it. When I started thinking of pieces that were predominantly geometric, I immediately thought of Piet Mondrian’s work. I thought it would be interesting to see abstractness become randomized, in a way. After this, I searched for Mondrian + Generative Art. I did not expect to find that many results. Mondrian and code, Mondrian and generative art, Mondrian and processing. There even was an entire programming language called Piet. It was way, way too overdone to the point where I couldn’t think of any way I could create my own take on it- so I had to change my idea.

So, inspired by the rainfall over the weekend, I created a rainy skyline of Abu Dhabi from day to night. First, for the sky, I had to think on paper:

Here is the final result, the “time of day” changes with the movement of the mouse:

And, here is my code:

//arrayList to hold all stars
ArrayList<Star> stars = new ArrayList<Star>();


Moon moon = new Moon();
int modifier;
float raindrop; 
int red, green, blue;

void setup()
{
  size(585,430);
  background(0);
  raindrop= 0; 
  
  //generate 30 random stars
  for (int i = 0; i < 30; i++)
  {

    stars.add(new Star());
  }
}

void draw()
{
  

  raindrop = raindrop + 4; //speed
  
  //if raindrop falls below canvas, reset to zero
  if (raindrop >= height)
    raindrop = 0;
  
  //map mouseX to rgb values of background
  red = int(map(mouseX, 0, width, 83, 0));
  green = int(map(mouseX, 0, width, 157, 0));
  blue = int(map(mouseX, 0, width, 253, 0));


  modifier = int(map(mouseX, width/2, width, 29, 0));
  
  
  background(red, green, blue);
  
  if (mouseX > width/2)
  {
    for (int i = 0; i < stars.size() - modifier; i++)
    {
      Star s = stars.get(i);
      s.drawStar();
    }
  }
  
  moon.update();
  moon.drawMoon();
//rainfall
  
  fill(211,211,211);
rect(10, raindrop, 2, 5);
rect(50, raindrop+20, 2, 5);
rect(80, raindrop, 2, 5);
rect(110, raindrop+100, 2, 5);
rect(140, raindrop+150,2, 5);
rect(180, raindrop-200, 2, 5);
rect(200, raindrop-150, 2, 5);
rect(240, raindrop-50, 2, 5);
rect(240, raindrop, 2, 5);
rect(300, raindrop+20, 2, 5);
rect(440, raindrop, 2, 5);
rect(440, raindrop, 2, 5);
rect(550, raindrop+100, 2, 5);
rect(530, raindrop-250, 2, 5);
rect(530, raindrop-200, 2, 5);
rect(580, raindrop-300, 2, 5);
rect(300, raindrop-400, 2, 5);
rect(140, raindrop-350, 2, 5);
rect(400, raindrop-300, 2, 5);
rect(400, raindrop-250, 2, 5);
rect(400, raindrop-200, 2, 5);
rect(550, raindrop, 2, 5);

//this part of my code uses & adapts from "skyline" by Shiwen Qin on OpenProcessing

 //building 1
  fill(250);
  rect(35,255,5,55);
  fill(250);
  rect(40,250,40,60);
  fill(51, 51, 51);
  quad(80,250,80,310,95,310,95,260);
  fill(106,106,71);
  for (int y=258; y<310; y+=8){
    fill(106,106,71);
    rect(36,y,2,2);
  }
  for (int y=258; y<300;y+=10){
    for(int x=44; x<78; x+=10){
    fill(106,106,71);
    rect(x,y,3,3);
    }
  }
  
   //building 2
  fill(51, 51, 51);
  rect(93,265,40,60);
  for (int y=270; y<300;y+=10){
    for(int x=96; x<130; x+=10){
    fill(165,160,102);
    rect(x,y,5,3);
    }
  }
  
    //building 3
  fill(220,220,220);
  rect(150,225,15,120);
  fill(220,220,220);
  rect(164,215,10,140,6);
    fill(169,169,169);
  rect(166,218,2,140,7);
  fill(105,105,105);
  arc(170,250,70,70,-PI/2,0);
  rect(170,250,35,140);
    fill(192,192,192);
  arc(170,250,60,60,-PI/2,0);
  rect(170,250,30,140);
   fill(192,192,192);
  arc(170,250,40,40,-PI/2,0);
  rect(170,250,20,140);
  
  
    //fourth building
  fill(250);
  fill(250);
  rect(235,225,5,75);
  fill(250);
  rect(240,225,40,80);
   fill(106,106,71);
  for (int y=258; y<310; y+=8){
   fill(106,106,71);
    rect(236,y,2,2);
  }
  for (int y=258; y<300;y+=10){
    for(int x=244; x<278; x+=10){
   fill(106,106,71);
    rect(x,y,3,3);
    }
  }
  
   
 // fifth building
 fill(102, 102, 102);
 rect(300,185,36,120);
 fill (51, 51, 51);
 rect (295, 185, 5, 120);
 rect (305, 185, 5, 120);
 
  //sixth building
  fill(51, 51, 51);
  rect(376,172,2,10);
  rect(375,180,3,15);
  quad(350,206,350,316,380,316,380,190);
  fill(102, 102, 102);
  quad(375,198,375,316,405,316,405,215);
  fill(51, 51, 51);
  rect(387,215,1,115);
  rect(396,215,1,115);
  
  //seventh building
  fill(51, 51, 51);
  rect(430,200, 40 ,150);
  fill(250);
  rect(430,200, 40 ,5);
  rect(470,200, 2 ,150);

  //seventh building .2
  fill(192,192,192);
  rect(490,200, 40 ,150);
  fill(250);
  rect(490,200, 40 ,5);
  rect(500,200, 2 ,150);
  
  
  
  //eighth building
   fill(51, 51, 51);
  rect(225,225,10,120);
  rect(270,225,10,120);
    //building 8
  arc(540,190,70,70,-PI*4/6,-PI*1/6,CHORD);
  quad(523,159,523,325,570,325,570,172);
  for(int y=170;y<325 ;y+=5){
   fill(106,106,71);
  quad(523,y,570,y+2,570,y+4,523,y+2);
  }
  
  //ninth building
  fill(51, 51, 51);
  quad(585,165,615,155,620,325,585,325);
  fill(31,30,72);
  triangle(614,155,622,158,619,325);
  for(int y=210;y<325 ;y+=5){
   fill(106,106,71);
  quad(585,y,615,y-1,615,y+1,585,y+2);
  }
  for(int y=210;y<325 ;y+=5){
   fill(64,64,34);
  quad(615,y-1,621,y,621,y+2,615,y+1);
  }

  //shore
  fill(69, 137, 163);
  rect(0,310,900,400);
  
   //mangroves
   for(int x=0;x<900;x+=20){
   mangroves(x,310,10,10,3,28,5,255);
   //varying parameters for mangroves
      mangroves(x+10,305,8,8,6,41,8,255); 
      mangroves(x+5,300,5,4,14,62,17,255);
       
   }
}

void cloud(int x,int y,int w,int h,int red,int green,int blue,int a){
 fill(red,green,blue,a);
 ellipse(x,y,w,h);
}

//sets variables they're being created in
void mangroves(int x,int y,int w,int h,int red,int green,int blue,int a){
 fill(red,green,blue,a);
 ellipse(x,y,w,h); 
 ellipse(x+5,y+5,w,h);
 ellipse(x-5,y-3,w,h);
 ellipse(x+3,y-5,w,h);
 ellipse(x-3,y+5,w,h);
}
class Moon
{
  int x;
  int y;
  int sizeMod = 0; 
  
  Moon()
  {
 
    this.x = 60;
    this.y = 90;
  }
  
  void drawMoon()
  {
    int blue, green;
    
     //map mouseX to green and blue rgb values for moon
     green = int(map(mouseX, 0, width, 221, 250));
     blue = int(map(mouseX, 0, width, 0, 205));
     
     noStroke();
     fill(255, green, blue);
    
    //map mouse X to rgb values for background/sky
    int bg_red = int(map(mouseX, 0, width, 83, 0));
    int bg_green = int(map(mouseX, 0, width, 157, 0));
    int bg_blue = int(map(mouseX, 0, width, 253, 0));
    
    //map mouseX to variable sizeMod, starting at 0, ending at 20
    sizeMod = int(map(mouseX, 0, width/6, 0, 20));
     
    //width/6 divides canvas into 6, for each moon/sun phase
    if (mouseX <= width/6)
    {
      //sizeMod decreases size of moon, starts at 80, ends at 80 - 20 = 60
      ellipse(x, y, 80 - sizeMod, 80 - sizeMod);
    }
    else if (mouseX > width/6 && mouseX <= 2 * (width/6))
    {
      arc(x, y, 60, 60, HALF_PI, 3 * HALF_PI, OPEN);
    }
    else if (mouseX > 2 * width/6 && mouseX <= 3 * width/6)
    {
      ellipse(x, y, 60, 60);
      //draw two overlapping circles to give illusion of crescent moon
      fill(bg_red, bg_green, bg_blue);
      ellipse(x + 10, y, 50, 50);
    }
    else if (mouseX > 3 * width/6 && mouseX <= 4 * width/6)
    {
      ellipse(x, y, 60, 60);
      //can't figure out how to flip arc, just cover with rectangle
      fill(bg_red, bg_green, bg_blue);
      rect(x - 30, y - 30, 30, 60);
    }
    else if (mouseX > 4 * width/6 && mouseX <= 5 * width/6)
    {
      ellipse(x, y, 60, 60);
      //draw two overlapping circles to give illusion of crescent moon
      fill(bg_red, bg_green, bg_blue);
      ellipse(x - 10, y, 50, 50);
    }
    else
    {
      ellipse(x, y, 60, 60);
    }
  }
  
  void update()
  {
    x = mouseX;
  }
}
class Star
{
  int x;
  int y;
  
  Star()
  {
    //instantiate star with random x and random y values, every time you restart sketch it' random
    this.x = int(random(0, width));
    this.y = int(random(0, height/3));
  }
  
  void drawStar()
  {
    fill(255);
    ellipse(x, y, 1.5, 1.5);
  }
}

 

 

 

Generative Art: Recreating “Random Squares” by Bill Kolomyjec

For this assignment, we were asked to recreate one example from a previous Computer and Graphic Art magazine issue.

I picked Random Squares by Bill Kolomyjec, which was published in August 1977: In order to replicate it, I utilized the drawTarget() function, which is helpful when you’re trying to draw multiple separate targets. A few other important functions for making this work are translate(), pushMatrix(), and popMatrix(). I also found this Processing Cheat Sheet to be very handy, it covers most if not all of the basics.

I created a few variations, one that is true to the original, and two where I played around with colors and animation.

Here is the end result of the first variation. However, because the value for the number of squares drawn in each square is randomized, it is not completely identical to the original:

Here is my code:

  boolean playLoop = false; 
      
      void setup(){
        size(930, 1320);
         background(0);
         //frameRate(1); //for loop
         
      }
      void draw(){
      if(playLoop==false){
         for(float x = 0; x<250; x+=25){
         for(float y = 0; y<250; y+=25){
              drawTarget(10, 10, 130, 10); //naming function: first square
              drawsSequence(25); // naming function: translating the shape - repititon
         }
          }
         }
          }
            
            void drawTarget(float x, float y, float size, float scale){
              float space = size/scale; //distance between distinct squares
              float left= space/3; //tightening space between squares on top corner, to mimic visual pattern in the og image
         
              for (int i=0; i<scale; i++){
                rect(x+i*left,y+i*left, size-i*space, size-i*space);
                rectMode(CORNER); // to interpret first two parameters of rectangle as the upper-left corner of the shape
              }
            }
      
       void drawsSequence (int randomNumber){
      float x_=130;
       float y_=130;
        for (int i=0; i<7; i++){
          for (int m=0; m<10; m++){ 
             pushMatrix();
             translate(x_*i, y_*m); // adding new squares
             drawTarget(10,10,130, random(randomNumber)); // randomizing amount
             scale(0.5);
             //fill(112, random(255), 500); 
             //fill(random(255),231, 116);
             popMatrix();
           }
           playLoop = true; //to prevent loop
       }
      }

 

In the second variation, I commented out all the playLoop (true/false) boolean variables , and set the frameRate() to 60 frames per second to animate the shapes. I also set a fill(100, random(100),random(100)) to get a range of randomized dark colors . Here’s how it looked:

And by simply increasing the strokeWeight() to 40, I was able to generate a more abstract form of the variation above. I thought the result was visually appealing. Some of the shapes look a little bit like Arabic characters, and it reminds me of abstract + minimalist calligraphy art:

 

 

 

Response: Casey Reas @ Eyeo2012

“The computer is a unique device for the arts since it can function solely as an obedient tool with vast capabilities for controlling complicated processes, but then again, full exploitation of these unique talents for controlled randomness and detailed algorithms could result in an entirely new medium-  a creative artistic medium.” – Micheal Noll

I really enjoyed this presentation by Casey Reas, and I was particularly fascinated by the idea of using code to create generative art where you’re able to control randomness. I especially liked ‘The Tissue Work‘, which was built around ideas from a book by neuroanatomist Valentino Braitenberg. By using software, Reas built a simulation of these conceptual vehicles, and what was interesting was that order began to emerge within their patterns and behaviors over time. To simulate this process, they used order with “a little bit of chance”.

I found the concept of limiting and controlling the amount of randomness in computer art pieces really interesting, and it’s an element that I want to attempt to add to my piece for this week’s assignment, where we are replicating pieces from old issues of a Computer Graphics and Art magazine. Reas mentioned that in one of his projects, they used randomness as a “jumping off point” and I like the idea of utilizing randomness in art as a means of exploring what you can do, but not letting it take up too much of the work’s identity, in a way.

When Reas was talking about chance in art, he provided a few early examples of artists whose works reflect that notion, such as Dada artist Jean Tinguely’s Meta-Matics, a series of machines which automatically produce infinite sequences of drawings:

I really liked this example, especially given that at the time it was made, it was created in response to the then growing commercialization of art and to question the role of the artist amidst the “threat” of industrialization and mass-production. But today, this work has acquired more meaning and it can also be viewed in relation to the idea of exploring technology’s potential as a new medium for art, rather than a substitute.

Response: “Emotional Design: Attractive Things Work Better”

In this chapter, Norman begins with an interesting anecdote about a study surrounding “attractive” ATM design by two Japanese researchers, and how people perceived attractively designed ATMs to be easier to use, even though they shared the same functions and buttons as some other, less attractive ATMs. Tracktinsy applied the same experiment to Israelis, thinking that “aesthetic preferences are culturally dependent”, and that the results stemming from Japanese culture would not apply to his experiment on Israelis. However, he was proved wrong and came to find that usability and aesthetics do correlate, contrary to his previous belief- and that to a large extent, they do so on a biological level, rather than a distinct cultural level.

Why do usability and aesthetics correlate, on a seemingly universal level?

Humans possess three levels of processing: visceral, behavioral and reflective. Each of these levels affect our interactions with design, objects and the environment. People are very similar at the visceral level, but it is at the behavioral and reflective levels that people differ and act differently. For one, we are genetically predisposed to have positive experiences with such things as smooth, symmetrical objects or “attractive” people or sensuous feelings, sounds and shapes (pp. 29). These “experiences” have been accumulated due to our evolutionary history, but humans also possess highly reflective abilities that enable us to, in a way, overwrite these biological histories.  Norman suggests that, in design, we need to cater to each of these three levels individually- but this also poses the question:  “How do each of the three levels compare in importance with the others?”. Norman proposes multiple solutions for this, but the solution I agree with the most is, satisfying the largest amount of needs by having a wide variety of products. An example of this which is mentioned in the chapter is magazines. No one tries to produce a magazine that caters to everyone, because it defies the point. Each magazine is special in its style, delivery, and audience.

So, coming back to the question of usability and aesthetics. Pleasurable aesthetics increase the usability of objects, on all three processing levels. Attractive objects trigger positive emotions, which in return enable our mental creativity and make us more tolerant of errors or difficulties in their design.

Response: “Her Code Got Humans on the Moon”

In addition to the multitude of lessons to be learnt from her brief history, Hamilton’s story is also incredibly inspiring. As a spaceship programmer in the sixties, she was quite literally one of a kind, and she was undoubtedly extraordinary as she completely revolutionized and transformed the potential of technology and software all the while navigating a male-dominated industry. This article made me realize the way technology can immensely improve and become more complex yet at the same time also become more simplified- in the span of a few decades. Back then, during Hamilton’s time, programming a spaceship meant punching holes in stacks of punch cards and threading copper wires through magnetic rings- and the computers processing these “words” or commands could only store and compute at a very limited level and speed. Today, this notion has been completely transformed, and programming has become transformed into a series of more “simplified” languages that a computer can understand, with many more options and larger capacities for data storage and computing speeds. To me, reading about the early stages of programming and software building is fascinating but also wildly incomprehensible. How do you encode data on a spaceship using something as “raw” as hole-punched cards? This may be an oversimplification of the process, but it is a question I often found myself asking. I also thought there was a valuable lesson to be learned about testing and troubleshooting from the Appolo 8 flight, what we may think “would never happen” can very much end up happening, and this can be applied all the way from large ventures such as spaceship flights bringing humans to the moon, to smaller-scale projects like our weekly class assignments.

Self-Portrait Using Processing

For this project, we were asked to create a self-portrait using processing. I drew an image of myself using primitive shapes, which was difficult at first but it became fun as soon as I became more familiar with shape coordinates. I wanted to create something that’s simple yet also visually appealing. To add an extra element to my self-portrait, I created an array of three images for my background, where I had three different “shades” of one image so that the background changes every time you click the mouse. This is what it looks like: 

And here’s my code:

  //my self-portrait 

float PImage;
PImage im ;                        
PImage [] backgrounds = new PImage[3]; // background array of 3 images
int currentBgNumber = 0;

void setup()
  {
     
     size(852, 480);

   backgrounds = new PImage[3];
    backgrounds[0] = loadImage("1.jpg"); 
    backgrounds[1] = loadImage("2.jpg");
    backgrounds[2] = loadImage("4.jpg");

   }
  
  void draw() 
  {
    
    background(backgrounds[currentBgNumber]);
    
    //hair
    stroke(0);
    fill(0);
    rect(100, 50, 400, 100);
    rect(100, 150, 400, 100);
    rect(100, 200, 400, 100);
    rect(100, 300, 400, 100);
   rect(100, 350, 400, 200);
  
    fill(247, 166, 79);
  
    //neck and body
    
    strokeWeight(4);
    stroke(15, 139, 141);
    fill(224,172,105);
    rect(235, 350, 75, 100);

    fill(224,172,105);
    rect(100, 405, 350, 375, 45);
    
    //shirt
    fill(250);
    rect (140, 405, 260, 200); 
    strokeWeight(4);
    //line (140, 450, 397, 450);
    //line (140, 470, 397, 470);
    //line (140, 490, 397, 490);
    
    //ears
    fill(224,172,105);
    stroke(63, 124, 172);
    ellipse(100, 200, 60, 100);
    ellipse(440, 200, 60, 100);
    
    //earrings
    strokeWeight(1);
    fill(250);
    ellipse(90, 235, 5, 5);
    fill(220,220,220);
    rect(103, 236, 2, 30);
    ellipse(450, 235, 5, 5);
    rect(440, 236, 2, 30);
    strokeWeight(3);
    
    //head
    stroke( 166, 128, 140);
    ellipseMode(CENTER);
    fill(224,172,105);
    ellipse(270, 200, 300, 350);
    fill(0);
    strokeWeight(4);
   
    //bangs 
    stroke(0);
    fill(0); 
    ellipse(300, 35, 420, 100);
    rect(97, 25, 400, 100);
    ellipse(100, 100, 30, 150);
  
  
    //eyebrows 
    stroke(97, 63, 117);
    rect(305, 160, 90, 10);
    rect(145, 160, 90, 10);
  
 
    //eyes 
    stroke(250);
    strokeWeight(3);
    fill(250, 218, 221);
    fill(250);
    line(155,198, 225, 198);
    arc(190, 200, 70, 60, 0, PI);
    line(315,198, 385, 198);
    arc(350, 200, 70, 60, 0, PI);
    //pupils
    fill(84, 42, 14);
    arc(190, 202, 40, 50, 0, PI);
    arc(350, 202, 40, 50, 0, PI);
    //lines
    strokeWeight(0.5);
    stroke(84, 42, 14);
    line(180, 240, 190, 240);
    line(350, 240, 360, 240);
 
   //nose
    stroke(0);
    strokeWeight(2);
    line (275, 230, 260, 260);
    line (260, 260, 275, 260);
      
    //mouth
    
    ellipseMode(CENTER); 
    strokeWeight(7);
    stroke(219,112,147);
    fill(250, 218, 221);
    arc(270, 305, 70, 60, 0, PI);
    }
    
void mousePressed(){
  currentBgNumber++;
  if (currentBgNumber>=3)
    currentBgNumber=0;
}

 

 

Midterm Project: Flying Paper Airplanes

For my midterm project, my initial proposal was to use sound, projection, and motors to create an installation piece. After hearing back from Aaron, I reconstructed the plan and instead used motors to create a paper airplane launcher using four geared motors, two servo motors, and an infrared distance sensor. The sensor is connected to the servo motors, which then launch the airplanes whenever the sensor detects movement.

As for the launcher’s structure, I made a platform using wood and cardboard with two wheels connected to the motors on each side, so four wheels in total. Here’s a very rough sketch of that thought process:

And here’s what it looked like:

From Below
From Above

However, I faced several challenges with making this work. Apart from the issues with wiring and code, designing the launcher proved to be really difficult. This meant having to make sure that the wheels were not too close to the cardboard, lining up the sticks for the “runway”, testing the angles for the servo motor launchers, etc. Another challenge I faced at the beginning was powering the wheels. At first, I was using regular DC motors and the issue was that they would take a while to reach full speed, and it was difficult to time them with the servo motors. As a solution to this, I used geared motors (included in the SparkFun kit), which can reach to full speed as soon as you turn them on.

Here’s a fritzing sketch I made of my circuit: 

Here’s the code:

#include <Servo.h>

float distance = 0;

Servo myservo;
Servo myservo2;

void setup()
{
  Serial.begin (9600);

  myservo.attach(9);
  myservo2.attach(10);

}

void loop() {
  //read distance
  distance = analogRead(A0);
  Serial.println("someone there yo");

  if (distance > 600) {          //close distance
    Serial.println("someone there yo");
    //this code moves the servo
    myservo.write(70);            //move servo
    myservo2.write(60);
    delay(50);
  } else {
    myservo.write(0);
    myservo2.write(0);
    delay(50);
  }
}

Here’s a video demonstration:

The idea behind this project is to trigger the servo motors whenever a person appears in front of the sensor, thus launching the airplanes as part of a “surprise”. This means that ideally, the structure would be placed somewhere unexpected, such as at the entrance of a door for example. It also works as a paper airplane tester or racer. This would mean that you’d be able to use it to “race” two paper airplanes, using the same speed and force, to test which airplane can fly the furthest.  So, ultimately, the idea behind this project was to create something playful and “surprising”, to explore different forms of interactivity, and to be able to experiment with a “game” type of interaction (the paper airplane racer). The issue with having these two different uses for the project is that with the airplane racer, I would have to change the affordances and indicators by adding a button instead of the sensor, for example. Whereas the sensor works perfectly for the surprise element.