miyehn-Asemic

I started with some sketches as usual- I hesitated between making abstract encoding of existing alphabet and making real asemic symbols. I chose the later because I don’t think I can make any encoding of current alphabets better than the existing ones.

I sticked with my idea of doing something about stick figures throughout (wow my first time not abandoning my idea in the process). My inspirations include notes I took in lectures when half asleep, as well as a kind of poisonous mushroom that make people hallucinate and see small figures running around. Meanwhile, knowing this work is going to be plotted, I wanted to make them look handwritten other than printed (because otherwise a printer would be much faster).

The grey figures were where I started. I wanted to make something like them.

First try below, using Processing to randomly generate stick figures and connect their hands in some way.

Not great. Anyone can tell they’re randomly generated and don’t look like writing at all. Although some figures look expressive in a weird way, most of them are just… random. Nevertheless the ones that look expressive inspired me in my second try, where I added some manual control into the design of symbols.

So I started writing this program to use a curve stroke plus a circle to represent symbols, and I stored their vertices coordinates in a json file so I could access them when I rerun the program. I also made a hot key for adding vertices on the bottom left and right of symbols so they could seamlessly connect to each other when needed. I made these ↓

Hmm they’re…. okay-ish, but don’t really look like figures any more, maybe because they’re missing arms. I improved the symbol designing program so it supported multiple curve strokes in a symbol. Finally I made these ↓

Below is how I would make a symbol and save it.

I made a few separately because for example English writings sometimes are mixed with some other symbols like Arabic numbers. In these symbols in the second images, they’re different from the ones above because they cannot connect to each other and have more emphasis on 2D shapes than lines.

Finally I measured some postcards of mine and arranged these symbols into some writing on postcard. They were plotted onto an actual postcard of mine and voila!

Below is my code for laying out postcard design ↓ although it cannot run because I didn’t contain the two json files (wordpress doesn’t allow me to upload)

float gridw = 100;
float gridh = 240;
JSONArray numbers;
JSONArray letters;
JSONArray mix;
 
import processing.pdf.*;
int pdfOutputCount = 1; 
 
void setup(){
  size(432,306);
  noFill();
  numbers = loadJSONArray("alphabet_number.json");
  letters = loadJSONArray("alphabet_letter.json");
  mix = new JSONArray();
  for(int i=0; i<letters.size(); i++) mix.append(letters.getJSONArray(i));
  for(int i=0; i<numbers.size()-3; i++) mix.append(numbers.getJSONArray(i));
  noLoop();
}
 
 
void draw(){
  background(245);
  template();
  beginRecord(PDF, "miyehn_6in_4.25in" + pdfOutputCount + ".pdf");
 
  //left
  writeLine(new PVector(20, 68), 5);
  for(int i=0; i<7; i++){
    if(i==6)
    writeLine(new PVector(16+random(-7,7), 96+i*20), 6+(int)random(-2,3));
    else
    writeLine(new PVector(16+random(-7,7), 96+i*20), 11+(int)random(-2,3));
  }
  writeLine(new PVector(140,250), 4);
  //right
  numberLine(new PVector(width/5*3, height/2-30), 2);
  writeLine(new PVector(width/5*3+46, height/2-30), 4);
  writeLine(new PVector(width/5*3, height/2+3), 6);
  writeLine(new PVector(width/5*3, height/2+28), 8);
  numberLine(new PVector(width/5*3+6, height/2+55), 5);
 
  endRecord();
  pdfOutputCount++;
}
 
void template(){
  rect(0, 0, width, 54);
  rect(0, height-18, width,height);
  line(234, 0, 234, height);
  /*
  rect(width-60, 20, 40, 50);
  for(int i=0; i<4; i++){
    line(width/5*3+10, height/2+i*24, width-20, height/2+i*24); 
  }
  */
}
 
void writeLine(PVector pos, int num){
  pushMatrix();
  translate(pos.x-16,pos.y);
  for(int i=0; i<num; i++){
    translate(16, 12.8);
    rotate(radians(random(-2, 2)));
    translate(0, -12.8);
    any(new PVector(0,0), new PVector(0.16,0.1));
  }
  popMatrix();
}
 
void numberLine(PVector pos, int num){
  pushMatrix();
  translate(pos.x-16,pos.y);
  for(int i=0; i<num; i++){ translate(16, 12.8); rotate(radians(random(-2, 2))); translate(0, -12.8); number(new PVector(0,0), new PVector(0.16,0.1)); } popMatrix(); } void any(PVector pos, PVector scale){ int ind = (int)random(mix.size()); JSONArray symbol = mix.getJSONArray(ind); renderSymbol(symbol, pos, scale); } void letter(PVector pos, PVector scale){ int ind = (int)random(letters.size()); JSONArray symbol = letters.getJSONArray(ind); renderSymbol(symbol, pos, scale); } void number(PVector pos, PVector scale){ int ind = (int)random(numbers.size()); JSONArray symbol = numbers.getJSONArray(ind); renderSymbol(symbol, pos, scale); } void renderSymbol(JSONArray symbol, PVector pos, PVector scale){ PVector c = new PVector(symbol.getJSONArray(0).getJSONObject(0).getFloat("cx"), symbol.getJSONArray(0).getJSONObject(0).getFloat("cy")); c.x*=scale.x; c.y*=scale.y; if(c.x>1)ellipse(pos.x+c.x, pos.y+c.y, 30*max(scale.x, scale.y), 30*max(scale.x,scale.y));
  for(int h=0; h<symbol.size(); h++){//loop through all segments
    beginShape();
    noFill();
    for(int j=0; j<symbol.getJSONArray(h).size(); j++){
      if(!(h==0 && j==0)){
        JSONObject obj = symbol.getJSONArray(h).getJSONObject(j);
        curveVertex(pos.x+obj.getFloat("x")*scale.x, pos.y+obj.getFloat("y")*scale.y);
      }
    }
    endShape();
  }
}
 
void mouseClicked(){
  redraw();
}

And below is my symbol designing program. It needs a json file called “alphabet2.json” containing an empty array to start.

float gridw = 100;
float gridh = 240;
ArrayList<ArrayList> V;
ArrayList Vc;
PVector C;
PVector l1, l2, r1, r2;
boolean active = true;
boolean drawmode = true;
boolean circlemode = false;
JSONArray values;
 
void setup(){
  size(800,300);
  V = new ArrayList<ArrayList>();
  Vc = new ArrayList();
  C = new PVector();
  l2 = new PVector(0, gridh/5*4);
  l1 = new PVector(-120, gridh/5*4+20);
  r2 = new PVector(gridw, gridh/5*4);
  r1 = new PVector(gridw+120, gridh/5*4-20);
  values = loadJSONArray("alphabet2.json");
}
 
void draw(){
  background(245);
  if(drawmode)drawFigure(new PVector(200, 20));
  else {
    scale(0.5,0.5);
    displayFigures(new PVector(10,20), new PVector(10, 260));
  }
}
 
void drawFigure(PVector pos){
  noFill();
  stroke(180);
  strokeWeight(1);
  rect(pos.x,pos.y, gridw, gridh);
  stroke(50);
  strokeWeight(5);
  //beginShape();
  for(int h=0; h<V.size(); h++){
    beginShape();
    for(int j=0; j<V.get(h).size(); j++){
      curveVertex(pos.x+V.get(h).get(j).x, pos.y+V.get(h).get(j).y);
    }
    endShape();
  }
  beginShape();
  for(int i=0; i<Vc.size(); i++){ curveVertex(pos.x+Vc.get(i).x, pos.y+Vc.get(i).y); } if(active){ curveVertex(mouseX, mouseY); curveVertex(mouseX, mouseY); } if(C.x>1)ellipse(pos.x+C.x, pos.y+C.y, 30, 30);
  endShape();
}
 
void displayFigures(PVector pos, PVector pos2){
  if(values.size()>0)
  for(int i=0; i<values.size(); i++){ stroke(180); strokeWeight(1); float tlx = pos.x+i*gridw; float tly = pos.y; rect(tlx, tly, gridw, gridh); stroke(50); strokeWeight(5); JSONArray arr = values.getJSONArray(i);//for a whole symbol PVector c = new PVector(arr.getJSONArray(0).getJSONObject(0).getFloat("cx"), arr.getJSONArray(0).getJSONObject(0).getFloat("cy")); if(c.x>1)ellipse(tlx+c.x, tly+c.y, 30, 30);
    for(int h=0; h<arr.size(); h++){//loop through all segments
      beginShape();
      for(int j=0; j<arr.getJSONArray(h).size(); j++){ if(!(h==0 && j==0)){ JSONObject obj = arr.getJSONArray(h).getJSONObject(j); curveVertex(tlx+obj.getFloat("x"), tly+obj.getFloat("y")); } } endShape(); } } if(values.size()>15)
  for(int i=15; i<values.size(); i++){ stroke(180); strokeWeight(1); float tlx = pos2.x+(i-15)*gridw; float tly = pos2.y; rect(tlx, tly, gridw, gridh); stroke(50); strokeWeight(5); JSONArray arr = values.getJSONArray(i);//for a whole symbol PVector c = new PVector(arr.getJSONArray(0).getJSONObject(0).getFloat("cx"), arr.getJSONArray(0).getJSONObject(0).getFloat("cy")); if(c.x>1)ellipse(tlx+c.x, tly+c.y, 30, 30);
    for(int h=0; h<arr.size(); h++){//loop through all segments
      beginShape();
      for(int j=0; j<arr.getJSONArray(h).size(); j++){ if(!(h==0 && j==0)){ JSONObject obj = arr.getJSONArray(h).getJSONObject(j); curveVertex(tlx+obj.getFloat("x"), tly+obj.getFloat("y")); } } endShape(); } } } void mouseClicked(){ if(active && drawmode) { if(!circlemode) Vc.add(new PVector(mouseX-200, mouseY-20)); else {C.x = mouseX-200; C.y = mouseY-20;} } } void keyTyped(){ if(key=='z' && Vc.size()>=1){
    Vc.remove(Vc.size()-1);
  } else if(key=='p'){
    for(int i=0; i<Vc.size(); i++){
      println(Vc.get(i));
    }
  } else if(key=='l'){
    Vc.add(l1);
    Vc.add(l2);
  } else if(key=='r'){
    Vc.add(r2);
    Vc.add(r1);
  } else if(key==' '){
    active = !active;
  } else if(key=='s'){
    JSONArray segments = new JSONArray();
    for(int h=0; h<V.size(); h++){
      JSONArray vertices = new JSONArray();
      if(h==0){
        JSONObject cc = new JSONObject();
        cc.setFloat("cx", C.x);
        cc.setFloat("cy", C.y);
        vertices.append(cc);
      }
      for(int i=0; i<V.get(h).size(); i++){
        JSONObject obj = new JSONObject();
        obj.setFloat("x", V.get(h).get(i).x);
        obj.setFloat("y", V.get(h).get(i).y);
        vertices.append(obj);
      }
      segments.append(vertices);
    }
    values.append(segments);
    saveJSONArray(values, "alphabet2.json");
    println("saved.");
  } else if(key=='q'){ 
    drawmode = !drawmode;
  } else if(key=='c'){
    circlemode = !circlemode;
    if(circlemode)println("circle mode");
    else println("line mode");
  } else if(key=='n'){
    V = new ArrayList<ArrayList>();
    Vc = new ArrayList();
    C = new PVector();
  } else if(key=='b'){
    V.add(Vc);
    Vc = new ArrayList();
  }
}