// 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(); }