este es mi colenga,..je ;)
/*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;
}
}
/* 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) ];
}
}
}
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.
Giovanni Carlo Mingati