How many ways to create A-Z alphabet table on the sketch

edited November 2015 in Questions about Code

I would like to create data visualization to display how many letters was repeted from the "String" I already had on A-Z table.

But first I would like to create A-Z alphabet table on my sketch.

As far as I know, I can make each alphabet in svg. and then import them and rearrange each of them on my sketch.

But I saw the on the processing/example/Typography/Letters which is already arranged all the alphabets. Screen Shot 2015-11-25 at 23.33.43

this is the default code:

/**
 * Letters. 
 * 
 * Draws letters to the screen. This requires loading a font, 
 * setting the font, and then drawing the letters.
 */

PFont f;

void setup() {
  size(640, 360);
  background(0);

  // Create the font
  printArray(PFont.list());
  f = createFont("Georgia", 24);
  textFont(f);
  textAlign(CENTER, CENTER);
} 

void draw() {
  background(0);

  // Set the left and top margin
  int margin = 10;
  translate(margin*4, margin*4);

  int gap = 46;
  int counter = 35;
  
  for (int y = 0; y < height-gap; y += gap) {
    for (int x = 0; x < width-gap; x += gap) {

      char letter = char(counter);
      
      if (letter == 'A' || letter == 'E' || letter == 'I' || letter == 'O' || letter == 'U') {
        fill(255, 204, 0);
      } 
      else {
        fill(255);
      }

      // Draw the letter to the screen
      text(letter, x, y);

      // Increment the counter
      counter++;
    }
  }
}
 

but I don't know how to edit this file.
1. I would like to know if it's possible to make it shows only A-Z on the sketch? Because as far as I try change to larger size in setup() it shows more of the other letters as if the size is only to frame them.
2. Is it possible to play with these alphabet or actually it's for display.


another amateur question, please be patience with me.

Answers

  • You don't know how to edit it because you don't understand what it is doing. Instead, of trying to understand complex code all at once, you could start with something simple and work your way up to the sketch you want.

    For example, here is a super basic, simple sketch:

    void setup(){
      size(350,200);
    }
    
    void draw(){
      background(0);
    }
    

    It has two functions. The first, setup() runs once when the sketch starts. It calls size() to set the width and height of the sketch. The other, draw(), then runs over and over again to redraw what is visible inside the sketch. In this case, a black background is drawn by a call to background().

  • Actually the one you told. I already know. So what's about my question.

  • Let's step it up a bit now and draw something. Like some text.

    void setup() {
      size(350, 200);
    }
    
    void draw() {
      background(0);
      text("Hello world! I am some text!", 20, 30);
    }
    

    This is like telling an artist what to paint. A black background. And then some text. The text is "Hello word! I am some text!". The 20 and 30 are the x and y positions we want the text drawn at.

  • yes, that one I already knew that too. Thank you seriously. ok, then I should better type A,B,C,D,E,F..? and then adjust the gap? But still you didn't answer my question :(

  • edited November 2015

    But that's not the text we want. We just want letters. Let's start by just having one letter.

    void setup() {
      size(350, 200);
      fill(255, 0, 0);
      textAlign(CENTER, CENTER);
      textSize(32);
    }
    
    void draw() {
      background(0);
      text("A", 25, 25);
    }
    

    Notice that I've added some functions to setup() now. These change the way things are drawn. The fill(255,0,0) means to draw in red. textAlign() is centering the text at the X and Y positions in calls to text(). textSize() says how large to draw the text. As you can see, the result is a larger, red letter A that is centered at (25,25).

  • edited November 2015 Answer ✓
    void setup() {
      size(350, 200);
      fill(255, 0, 0);
      textAlign(CENTER, CENTER);
      textSize(32);
    }
    
    void draw() {
      background(0);
      for(int i=0; i<7; i++){
        text("A", 25+50*i, 25);
      }
    }
    

    I'm getting there. What we really want is lots of letters. But I don't want to have to do a text() call for each of them. Let's start by adding a loop that does a ROW of letters.

  • ok ok, I'm following.

  • So what is next.

  • And now another loop to do many rows.

    void setup() {
      size(350, 200);
      fill(255, 0, 0);
      textAlign(CENTER, CENTER);
      textSize(32);
    }
    
    void draw() {
      background(0);
      translate(0,-5);
      for(int j=0;j<4;j++){
        for(int i=0; i<7; i++){
          text("A", 25+50*i, 25+50*j);
        }
      }
    }
    
  • edited November 2015

    That's great. Now we have many letters. But we don't always want the letter to be 'A'. We want to start with 'A' and then next one is 'B', and so on.

    Now this is where some smarts about computers kicks in. Your computer doesn't think using letters. It uses numbers instead. Specifically, for doing characters, it represents different characters in its memory using different numbers. Look:

    println('A');
    println(int('A'));
    

    You can ask it what number it thinks the character 'A' is. Turns out that it uses 65 to mean 'A'. 'B' is 66. 'C' is 67. And so on.

    You can also ask it what letter it thinks a number is!

    println(90);
    println(char(90));
    

    How does this help us? Well, we're using numbers - i and j - to loop in our code. If we base the letter to print at a position based on the numbers used to offset the letters to those positions, then we can get it to print different numbers.

    void setup() {
      size(350, 200);
      fill(255, 0, 0);
      textAlign(CENTER, CENTER);
      textSize(32);
    }
    
    void draw() {
      background(0);
      translate(0,-5);
      for(int j=0;j<4;j++){
        for(int i=0; i<7; i++){
          text(char('A' + i), 25+50*i, 25+50*j);
        }
      }
    }
    

    Here, I use the value of i to add to the value of 'A', so that letters in each ROW "increase" by one.

  • edited November 2015 Answer ✓
    void setup() {
      size(350, 200);
      fill(255, 0, 0);
      textAlign(CENTER, CENTER);
      textSize(32);
    }
    
    void draw() {
      background(0);
      translate(0,-5);
      for(int j=0;j<4;j++){
        for(int i=0; i<7; i++){
          text(char('A' + i + (j*7)), 25+50*i, 25+50*j);
        }
      }
    }
    

    And here, I use the value of j to "increase" the letters in the next rows by 7, 14, and 21. In the first row, j is 0, so 0 * 7 is 0, and there is no increase. In the forth row, j is 3, 3 * 7 is 21, and so the increase because of which row we're in is 21. See?

  • Aha, it's some kind of ACII number right? aha, now I get it.

  • Answer ✓

    But oh no! There are weird letters in there after Z! [ is 91 and \ is 92. So we can throw in some logic to make adjustments in the last row.

    void setup() {
      size(350, 200);
      fill(255, 0, 0);
      textAlign(CENTER, CENTER);
      textSize(32);
    }
    
    void draw() {
      background(0);
      translate(0,-5);
      for(int j=0;j<4;j++){
        for(int i=0; i<7; i++){
          if(!(j==3 && (i==0 || i==6))){
            text(char('A' + i + (j*7) + (j==3?-1:0)), 25+50*i, 25+50*j);
          }
        }
      }
    }
    

    Much better. We skip printing letters in the first and last slots in the last row, and we subtract 1 to the letter's number in the last row too. Together these give us a sweet looking alphabet.

  • Of course, I wouldn't do it that way. I'd do it this way:

    class LetterBlock {
      char a;
      float x, y;
      int count;
      LetterBlock(char ia, float ix, float iy) {
        a=ia;
        x=ix;
        y=iy;
        count=0;
      }
      void draw() {
        fill(255-count, count, 0);
        text(a, x, y);
      }
    }
    
    LetterBlock[] lbs = new LetterBlock[26]; 
    
    void setup() {
      size(350, 200);
      textAlign(CENTER, CENTER);
      textSize(32);
      int x = 0;
      for (int j=0; j<4; j++) {
        for (int i=0; i<7; i++) {
          if (!(j==3 && (i==0 || i==6))) {
            lbs[x] = new LetterBlock(char('A'+x), 25+50*i, 20+50*j);
            x++;
          }
        }
      }
    }
    
    void draw() {
      background(0);
      for (int i=0; i<lbs.length; i++) lbs[i].draw();
    }
    

    But wait, that looks exactly the same! Well yeah, it basically is. Except it's really not, because now my letters are a little more... free... to do their own thing...

  • For example, I can do this (point your mouse at a letter!):

    class LetterBlock {
      char a;
      float x, y;
      int count;
      LetterBlock(char ia, float ix, float iy) {
        a=ia;
        x=ix;
        y=iy;
        count=0;
      }
      void draw() {
        fill(255-count, count, 0);
        if( mouseOver() ) fill(128,128,255);
        text(a, x, y);
      }
      boolean mouseOver(){
        return(dist(mouseX,mouseY,x,y)<=20);
      }
    }
    
    LetterBlock[] lbs = new LetterBlock[26]; 
    
    void setup() {
      size(350, 200);
      textAlign(CENTER, CENTER);
      textSize(32);
      int x = 0;
      for (int j=0; j<4; j++) {
        for (int i=0; i<7; i++) {
          if (!(j==3 && (i==0 || i==6))) {
            lbs[x] = new LetterBlock(char('A'+x), 25+50*i, 20+50*j);
            x++;
          }
        }
      }
    }
    
    void draw() {
      background(0);
      for (int i=0; i<lbs.length; i++) lbs[i].draw();
    }
    
  • I have question about comment at 1:17AM

    Because of the "text(char..)" code right that make computer will automatically understand and change A to 65 and continue to (B)66,(C)67.. and so on.

  • Or this (click a letter!):

    class LetterBlock {
      char a;
      float x, y;
      int count;
      LetterBlock(char ia, float ix, float iy) {
        a=ia;
        x=ix;
        y=iy;
        count=0;
      }
      void draw() {
        fill(255-count, count, 0);
        if( mouseOver() ) fill(128,count,255);
        text(a, x, y);
      }
      boolean mouseOver(){
        return(dist(mouseX,mouseY,x,y)<=20);
      }
      void click(){
        if( mouseOver() ) count+=20;
      }
    }
    
    LetterBlock[] lbs = new LetterBlock[26]; 
    
    void setup() {
      size(350, 200);
      textAlign(CENTER, CENTER);
      textSize(32);
      int x = 0;
      for (int j=0; j<4; j++) {
        for (int i=0; i<7; i++) {
          if (!(j==3 && (i==0 || i==6))) {
            lbs[x] = new LetterBlock(char('A'+x), 25+50*i, 20+50*j);
            x++;
          }
        }
      }
    }
    
    void draw() {
      background(0);
      for (int i=0; i<lbs.length; i++) lbs[i].draw();
    }
    
    void mousePressed(){
      for (int i=0; i<lbs.length; i++) lbs[i].click();
    }
    
  • Answer ✓

    Yes, text() can print a single character as well as a string of them.

    If you have it print char(65), then that is the character represented by the value of 65. Which is 'A'.

    If we move over to the next letter, the variable i has changed from 0 to 1. Now we are doing char('A' + i). 'A' has the value 65, so this is really char(65+1), or char(66), or 'B'.

    It's ASCII.

  • Thank you so much, this is really helpful and thank you for those step by step things. I will go through your code and try to continue with my next step. :DD

  • edited November 2015

    I came back with more amateur question.
    1.Why I can't make a stroke, it seems not working when I tried to use stroke().
    2. If I want to play with each alphabet to make the repetition like AAAA in the A-Z table, I'm not sure should I convert them to shape first by Geomerative, may be?
    3.I try to println(font) and it's null. Is there's any ways to convert 'null' to string or shape?

    PFont font;
    class LetterBlock {
      char a;
      float x, y;
      int count;
      LetterBlock(char ia, float ix, float iy) {
        a=ia;
        x=ix;
        y=iy;
        count=0;
      }
      void draw() {
        noFill(); 
        stroke(255); 
        font = createFont("FreeSans.ttf", 100);
        textFont(font);
        fill(255);
    
        //stroke(255);
        if ( mouseOver() ) fill(128, count, 255);
        text(a, x, y);
      }
      boolean mouseOver() {
        return(dist(mouseX, mouseY, x, y)<=20);
      }
      void click() {
        if ( mouseOver() ) count+=20;
      }
    }
    
    LetterBlock[] lbs = new LetterBlock[26]; 
    
    void setup() {
      size(800, 600);
      textAlign(CENTER, CENTER);
      //textSize(50);
      smooth();
      int x = 0;
      for (int j=0; j<4; j++) {
        for (int i=0; i<7; i++) {
          if (!(j==3 && (i==0 || i==6))) {
            lbs[x] = new LetterBlock(char('A'+x), 50+115*i, 50+150*j);
            x++;
          }
          println(font);
        }
      }
    }
    
    void draw() {
      background(0);
      for (int i=0; i<lbs.length; i++) lbs[i].draw();
    }
    
    void mousePressed() {
      for (int i=0; i<lbs.length; i++) lbs[i].click();
    }
    
  • edited November 2015

    I dont know what's happening with my code up there, but I just added PFont and println(font). That's all.

  • Answer ✓
    1. Text is drawn in the color specified by fill(), not stroke(). If you want an outline around your text, there are ways to do it, but they don't involve using stroke().

    2. I don't know what you mean by this. Play how? Can you make and post a mock-up image that shows what you want to happen?

    3. The way you were creating the font was wrong. You don't need to specify the .ttf part. You also don't need to create the font every frame of drawing, for every letter drawn. Just once in setup() is fine, as the font doesn't change.

    Your code posted weird because you haven't learned how to format your code for posting on these forums. There is a sticky thread about it. Short version: Hilight code and press Ctrl+o.

    Working example:

    PFont font; 
    class LetterBlock { 
      char a; 
      float x, y; 
      int count; 
      LetterBlock(char ia, float ix, float iy) { 
        a=ia; 
        x=ix; 
        y=iy; 
        count=0;
      } 
      void draw() { 
        // Green "stroke" outline around text.
        fill(0,255,0);
        for(int dx=-1;dx<2;dx++){
          for(int dy=-1;dy<2;dy++){
            text(a, x+dx, y+dy);
          }
        }
        fill(255);
        if ( mouseOver() ) fill(128, count, 255);
        text(a, x, y);
      } 
      boolean mouseOver() { 
        return(dist(mouseX, mouseY, x, y)<=50);
      } 
      void click() { 
        if ( mouseOver() ) count+=20;
      }
    }
    
    LetterBlock[] lbs = new LetterBlock[26];
    
    void setup() { 
      size(800, 600); 
      textAlign(CENTER, CENTER);
      //textSize(50);
      font = createFont("FreeSans", 100);
      textFont(font);
      smooth(); 
      int x = 0; 
      for (int j=0; j<4; j++) { 
        for (int i=0; i<7; i++) { 
          if (!(j==3 && (i==0 || i==6))) { 
            lbs[x] = new LetterBlock(char('A'+x), 50+115*i, 50+150*j); 
            x++;
          }
        }
      }
    }
    
    void draw() { 
      background(0); 
      for (int i=0; i<lbs.length; i++) lbs[i].draw();
    }
    
    void mousePressed() { 
      for (int i=0; i<lbs.length; i++) lbs[i].click();
    }
    
  • edited November 2015

    @TfGuy44 thank you for your code,your answers and also taught me how to format the code. Here I attached the mock-up pictures for you.

    The aim of this project is data visualisation. I would like to visualise alphabets which have been counted from a music lyrics String. As you can see the repeated A is overlay on the same A position,for example. I gave you 2 pictures. So you can also see it in perspective, in case my explanation is not so clear.

    FinalOutcome_01-01 FinalOutcome_02-01

  • Answer ✓

    nice

    just count how many A's there are in the song lyric (call it x times)

    then just don't draw the A only once but x times, each time adding 1 to position x and y

  • edited December 2015

    @TfGuy44 what do you think? is my mock-up images are clear or you need more explanation

  • Answer ✓

    Your mock up images are fine. But where is the code of your attempt at doing it yourself? Chrisir has told you what the changes you need to make are. Count the letters. Draw each letter that many times, with some offset each time.

  • [continued in next discussion of boomp]

  • @chrisir sorry, but I still don't get it :(

  • Answer ✓

    see other thread please

  • @TfGuy44 I thank you for your help to create a stroke last time. After I was able to linked the data to the skecth it's turned out to be that for my data visualisation the A-Z need to be noFill and stroke(255) which will display the function of my sketch more accurately(the repetition of letters). I tried with Geomerative, NexText and PFont but it's not work with noFill at all, can you explain me why and any suggestion about what should I do? Sorry to bring this up again but I want to figure out :(

  • Answer ✓

    If you think I was creating a stroke last time, you obviously used my code without looking at what it did and completely failed to understand it. The color you set with stroke() is not used at all when you draw text. Only the fill() color matters. Thus, trying to do text() using noFill() is just not going to work.

    What you really need to do is make a mask image that is just the outline of the letters. Then use that mask on a solid colored image to get a colored outline that use can then draw several times.

    Here's an example. You'll need to do this for each letter. You will probably want to generate the mask images and colored letter outlines once for each letter.

    And UNDERSTAND IT THIS TIME.

    void setup(){
      size(200,200,P2D);
      PGraphics pg = createGraphics(200,200,P2D);
      PGraphics mk = createGraphics(200,200,P2D);
      mk.beginDraw();
      mk.background(0);
      mk.textSize(48);
      mk.fill(255);
        for(int dx=-1;dx<2;dx++){
          for(int dy=-1;dy<2;dy++){
            mk.text('A', 100+dx, 100+dy);
          }
        }
      mk.fill(0);
      mk.text('A',100,100);
      mk.endDraw();
      pg.beginDraw();
      pg.background(0,255,0);
      pg.endDraw();
    
      PImage A = pg.get();
      A.mask(mk);
    
      background(0);
      image(A,-10,-10);
      image(A,0,0);
      image(A,10,10);
    }
    
    void draw(){}
    
  • Answer ✓

    I tried with Geomerative, NexText and PFont but it's not work with noFill at all, can you explain me why and any suggestion about what should I do?

    Hard to tell, when we don't see what you have tried. The HelloWorld example from geomerative does exactly what you want, if you add noStroke() and fill(255).

    TfGuy44's example above should do the job, too. Maybe you try do understand what he is doing and ask, if something is not clear.

  • Answer ✓
    PImage[] listImages = new PImage[27]; 
    
    int i2 = 0;
    
    int offsetX=0;
    int offsetY=0;
    
    void setup() {
      size(1100, 500, P2D);
    
      int i=0; 
      for (char a1 = 'A'; a1 <= 'Z'; a1++) {
        listImages[i] = makeImage(a1); 
        i++;
      }
    }
    
    void draw() {
      // background(0);
    
      offsetX += 55; 
    
      translate (offsetX, i2*3+offsetY) ; 
    
      image(listImages[i2], -10, -10);
      image(listImages[i2], 0, 0);
      image(listImages[i2], 10, 10);
    
      i2++;
    
      if (i2==13) { 
        offsetY=100; 
        offsetX=20;
      }
    
      if (i2>=25)
        i2=25;
    }
    
    PImage makeImage (char charLocal) {
    
      PGraphics pg = createGraphics(200, 200, P2D);
      PGraphics mk = createGraphics(200, 200, P2D);
    
      mk.beginDraw();
      mk.background(0);
      mk.textSize(48);
      mk.fill(255);
      for (int dx=-1; dx<2; dx++) {
        for (int dy=-1; dy<2; dy++) {
          mk.text(charLocal, 100+dx, 100+dy);
        }
      }
    
      mk.fill(0);
      mk.text(charLocal, 100, 100);
      mk.endDraw();
    
      pg.beginDraw();
      pg.background(0, 255, 0);
      pg.endDraw();
    
      PImage A = pg.get();
      A.mask(mk);
    
      return A;
    }
    
  • @TfGuy44 Sorry, if my words made you feel that way of not trying to understand. Actually I know what's working on each part to creating the green outline from last sketch that it’s overlay each other. However at that time I don't know about "mask image”. My intension is to adjusting Typography and create transparent outline stroke in each letters. Since last last time you said noFill is not work, so I try to import library Geomerative and NextText to adjust the text. After all attempted it’s not work as it should be so here I came back to asking for your suggestion if any of that part that I'm missing or why it's not work like other text. Anyway thanks for your answer again. It's help me learn.

Sign In or Register to comment.