Hilbert
// Hilbert L System - Jim Bumgardner, for both Processing and Processing.js
String axiom = "A";
String[] rules = {"A", "lBfrAfArfBl", // production rules copied from wikipedia article on Hilbert curve
"B", "rAflBfBlfAr"};
HashMap rulesH = new HashMap();
int nbrGenerations = 4;
float lineLength = 0;
String lsys;
void setup()
{
size(500,500);
noLoop();
setupLSystem();
}
void setupLSystem()
{
for (int j = 0; j < rules.length; j += 2) {
rulesH.put(rules[j], rules[j+1]);
}
}
String lsysGen(String lsys, String[] rules, int nbrGenerations)
{
while (nbrGenerations > 0) {
String dst = "";
for (int i = lsys.length()-1; i >= 0; --i) {
String ch = lsys.substring(i,i+1);
if (rulesH.containsKey(ch))
dst += rulesH.get(ch);
else
dst += ch;
}
lsys = dst;
--nbrGenerations; // 1 down
}
return lsys;
}
// Angles are in integer amounts (1 = 90 degrees) to avoid rounding error
void lsysDraw(String src, float sx, float sy, float len, int angD)
{
// Table of 90 degree sin/cos values
int[][] sincos = {{1,0},{0,1},{-1,0},{0,-1}};
float px = sx;
float py = sy;
// println("Drawing at " + px + "," + py);
beginShape();
vertex(px,py);
for (int i = 0; i < src.length(); ++i) {
String ch = lsys.substring(i,i+1);
if (ch.equals("f")) {
px += sincos[angD][0]*len;
py += sincos[angD][1]*len;
vertex(px,py);
} else if (ch.equals("l")) {
angD = (angD+3)%4; // Counter-clockwise turn
} else if (ch.equals("r")) {
angD = (angD+1)%4; // Clockwise turn
}
}
endShape();
}
void draw()
{
lsys = lsysGen(axiom,rules, nbrGenerations);
// println("--> " + lsys);
background(255);
stroke(128);
noFill();
smooth();
float lineLength = width/2.0 * pow(.5, nbrGenerations-1);
strokeWeight(lineLength/2.0);
strokeCap(PROJECT);
// strokeJoin(ROUND);
lsysDraw(lsys, lineLength/2, height-lineLength/2, width/2 * pow(.5, nbrGenerations-1), 0);
}
void mouseClicked()
{
if (mouseX > width/2) {
nbrGenerations = min(8, nbrGenerations+1);
}
else {
nbrGenerations = max(1, nbrGenerations-1);
}
redraw();
}