• fullscreen
  • Letter.pde
  • LetterGenerator.pde
  • LetterVisitor.pde
  • drawing_machine_16.pde
  • /* Letter
    Una clase para agrupar los puntos que componen un carácter en concreto.
    This class gathers together every point in a certain char.
    */
    
    class Letter {
      
      //The char
      String name;
      //The points
      RPoint[] rPoints; 
      
      //Constructor
      Letter (String name, RPoint[] rPoints) {
        this.rPoints = rPoints;
        this.name= name;
      }
      
      //Getters
      String getName(){
        return name;
      }
      
      RPoint[] getPoints(){
       return rPoints; 
      }
      
      //Display
      void display(int strk){
        stroke(strk);
        beginShape();
        for (int i=0; i<rPoints.length; i++){
          vertex (rPoints[i].x, rPoints[i].y);
        }
        endShape();
      }
      
      //In order to apply a Visitor pattern:
      void accept(LetterVisitor visitor){
        visitor.visit(this); 
      }  
    }
    
    /* FancyLetter
    Extiende a Letter, permitiendo que cada punto tenga un color propio.
    Extends Letter, allowing it to have different colors per vertex.
    */
    
    class FancyLetter extends Letter {
      
      //The colors
      int[] pntColors;
      
      //Constructor
      FancyLetter (String name, RPoint[] rPoints) {
        super (name,rPoints);
        pntColors = new int[rPoints.length];
      }
      
      //Getters
      int[] getCols() {
        return pntColors; 
      }
      
      //Display
      void display(){
        beginShape();
        for (int i=0; i<rPoints.length; i++){
          stroke (pntColors[i]);
          vertex (rPoints[i].x, rPoints[i].y);
        }
        endShape();
      } 
      
    }
    
    /* FancyLetterGenerator
    Clase generadora de FancyLetters.
    TODO: simplificar los métodos de generación creando los elementos comunes
    de código en métodos independientes. Hacer más genérica la creación de
    grupos de caracteres.
    A generator of FancyLetters.
    TODO: to simplify generation methods creating independent methods for
    common code blocks. To make more generic the creation of char groups.
    */
    
    class FancyLetterGenerator {
      
      //The font
      RFont theFont;
      
      //Constructor
      FancyLetterGenerator (String fontName, int fontSize, int fontMode){
        theFont = new RFont (fontName,fontSize,fontMode);
      }
      
      //To adjust the font
      void setSegments (int segmentLength, int mode){
        RCommand.setSegmentLength (segmentLength);
        RCommand.setSegmentator (mode);
      }
      
      //Create a centered char onto a given canvas
      FancyLetter generateCenteredChar (char ch, PGraphics pg){
          String strChar = str(ch);
          RGroup rG = theFont.toGroup (strChar);
          RPoint[] thePoints = rG.getPoints();
          
          //All this stuff is useful to center the char onto the canvas
          float x,y,maxX= 0f, minX = 0f, maxY=0f, minY=0f;
          for (int j=0; j<thePoints.length; j++){
            minX = minX < thePoints[j].x ? minX : thePoints[j].x;
            minY = minY < thePoints[j].y ? minY : thePoints[j].y;
            maxX = maxX > thePoints[j].x ? maxX : thePoints[j].x; 
            maxY = maxY > thePoints[j].y ? maxY : thePoints[j].y; 
          }
          x = (pg.width  - maxX + minX) /2;
          y = (pg.height - maxY - minY) /2;
          for (int j=0; j<thePoints.length; j++){
            thePoints[j].x += (x-minX);
            thePoints[j].y += y;
          }
        return new FancyLetter (strChar,thePoints);
      }
       
      /* This method is useless here, but it's more useful than previous one: it 
      generates a single line of chars, grouped into an ArrayList.
      */
      ArrayList generateLine (String srcTxt, float x, float y, float fixedTracking) {
    
        ArrayList Letters = new ArrayList <Letter> () ;
        
        for (int i=0,col; i< srcTxt.length(); i++){
          String strChar = str(srcTxt.charAt(i));
          RGroup rG = theFont.toGroup (strChar);
          RPoint[] thePoints = rG.getPoints();
          float maxX= 0f, minX = 0f;
          for (int j=0; j<thePoints.length; j++){
            minX = minX < thePoints[j].x ? minX : thePoints[j].x;
            maxX = maxX > thePoints[j].x ? maxX : thePoints[j].x; 
          }
          for (int j=0; j<thePoints.length; j++){
            thePoints[j].x += (x-minX);
            thePoints[j].y += y;
          }
          Letters.add (new FancyLetter (strChar, thePoints));
          x+= ((maxX-minX) + fixedTracking);
        } 
        return Letters;
      }
    }
    
    /* LetterVisitor 
     LetterVisitor es una interfaz que implementa un patrón Visitante.
     An interface in order to implement a Visitor pattern.
     */
    
    interface LetterVisitor {
      void visit (Letter letter);
    }
    
    /* EmergenceNoisyNormal
     Esta clase implementa la interfaz LetterVisitor, y modifica la posición
     de cada punto de la geometría de un objeto Letter, teniendo en cuenta la 
     posición de los puntos previo y siguiente en la cadena de la letra y una función 
     de ruido Perlin. 
     This class implements the interface LetterVisitor, and modifies the position
     of each point of a Letter object taking into account some Perlin noise and the
     positions of previous and next point in the shape.
     */
    
    class EmergenceNoisyNormal implements LetterVisitor {
    
      void visit (Letter letter) {
        RPoint[] pnts = letter.getPoints();
        for (int i=0,index,p,n,l; ++i<(l=pnts.length);) {
          p = (index=i-1) <0? l+index : index; //previous index
          n = (index=i+1)>=l? index-l : index; //next index
          PVector N = new PVector (  pnts[n].y - pnts[p].y, pnts[n].x - pnts[p].x ); 
          N.normalize ();
          N.mult ( noise(i*.5)*.5);
          pnts[i].x += N.x;
          pnts[i].y += N.y;
        }
      }
    }
    
    /* NoisyPalette
     Esta clase también implementa la interfaz anterior y colorea los puntos de una Fancy
     Letter, escogiendo colores de una paleta dada siguiendo una distribución Perlin.
     This class is another Visitor that defines the colour of the points of a Letter, making a noisy
     distribution of the colors in a given palette.
    */
    
    class NoisyPalette implements LetterVisitor {
     
      int[] palette;
      float f;
     
      //Constructor, using varargs
      NoisyPalette (float f,int... palette){  
        this.palette = palette;
        this.f= f;
      } 
      
      //Visit
      void visit (Letter letter) {
        int[] cols = ((FancyLetter)letter).getCols();
        for (int i=0; i<cols.length; i++){
          cols[i] = palette [ int(noise(i*f)*palette.length) ];
        }    
      } 
    }
    
    /*DrawingMachine#16 -- 2012, Ale González -- a(en)60rpm.tv -- Dominio Público
    *
    * Esta aplicación es un experimento formal, que aplica un principio de emergencia
      a los puntos de una tipografía. Cada punto se mueve en una dirección que depende 
      sólamente de la posición de los puntos previo y siguiente en la curva de la letra,
      con una velocidad generada mediante ruido de Perlin.
      TODO: arreglar la unión no deseada de vértices lejanos
    *
    * This app is a formal experiment that applies an emergence-kind of force to the points of a 
      typography. Each one of these move in a direction that depends only of the positions
      of the previous and next point in the shape, with a force determined by Perlin noise.
      TODO: to fix the undesired joint of far-away vertices 
    *
    */
    
    
    import geomerative.*;
    
    final int BG = #D6C6B5;
    
    FancyLetterGenerator letterGenerator;
    FancyLetter letter;
    EmergenceNoisyNormal newPositions;
    NoisyPalette newColors;
    
    boolean playing = false;
    
    /* Setup && Loop
    */
    
    void setup(){
      //General Settings
      size (750,750,P2D);
      background (BG);
      stroke (0x05000000);
      strokeWeight(1.1);   
      smooth ();
      noFill();
      //Object settings
      RG.init (this);
      letterGenerator = new FancyLetterGenerator ("FreeSansBold.ttf", 550, RFont.CENTER);
      newPositions    = new EmergenceNoisyNormal();
      newColors       = new NoisyPalette(.5,0x052a3941,0x053e5664,0x05bcd3dd,0x50ffffff,0x50fd520c); 
      letterGenerator.setSegments(3, RCommand.UNIFORMLENGTH);
    }
    
    void draw(){
      if (playing && letter!=null) {
        letter.accept  (newPositions);
        letter.display ();
      }
    }
    
    /* Interaction 
    */
    
      // To toggle the loop 
    void mousePressed(){
      playing=!playing; 
    }
    
      // To create a new char
    void keyPressed(){
      if (key == KeyEvent.VK_SPACE){
        return;
      } else if (key!= CODED){
        background (BG);
        letter = letterGenerator.generateCenteredChar (key,g);
        letter.accept  (newColors); 
        letter.display (-1);
      }else{
        return;
      }
    }
    

    code

    tweaks (0)

    about this sketch

    This sketch is running as Java applet, exported from Processing.

    license

    advertisement

    Ale

    DrawingMachine#16

    Add to Faves Me Likey@! 13
    You must login/register to add this sketch to your favorites.

    This app is a formal experiment that applies an emergence-kind of force to the points of a typography. Each one of these move in a direction that depends only on the positions of the previous and next point in the shape, with a force determined by Perlin noise.
    Uses Geomerative library and FreeSans font.

    Interaction:
    - Press any key to select a char.
    - Press any mouse button to begin-toggle the loop.

    javi
    9 Jul 2012
    master,...!

    este es mi colenga,..je ;)
    Ale
    9 Jul 2012
    Gracias Javi! ;-)
    very nice!
    Ale
    6 Aug 2012
    @Giovanni: Glad you like it!
    Dushan Milic
    23 Oct 2013
    Incredibly cool!
    You need to login/register to comment.