Friday, November 18, 2011

Simple L-system Processing.js Code

Here as promised is the code from my previous post:

<script src="http://processingjs.org/content/download/processing-js-1.3.6/processing-1.3.6.min.js" type="text/javascript"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/modernizr/2.0.6/modernizr.min.js" type="text/javascript"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/1.7/jquery.min.js" type="text/javascript"></script>
<div id="blogpostcontent"><!-- Blog Text -->
</div>
<div id="nocanvas" style="display: none; color: Red;"><!-- Fail Text -->
</div>
<div id="procanvas"><canvas id="processingCanvas"></canvas></div>
<div><!-- More Blog Text -->
</div>
<script type="text/javascript">
var words = $("#blogpostcontent").text().replace(/[\.,-\/#!$%\^&\*;:{}=\-_`~()]/g, "").replace(/\s{2,}/g, "").split(' ');
if (!Modernizr.canvas) { $('#nocanvas').show(); $('#procanvas').remove(); }
</script>
<script type="text/processing" data-processing-target="processingCanvas">

Tree tree;
int wordCount = 0;

class Stack {
ArrayList aList;

Stack() {
aList = new ArrayList(1024);
}

Stack(int initialSize) {
aList = new ArrayList(initialSize);
}

boolean isEmpty() {
if (aList.size() > 0) return false;
return true;
}

void push(Object obj) {
aList.add(obj);
}

Object pop() {
int n = aList.size();
if (n > 0) return aList.remove(n - 1);
return null;
}
}

class Branch {

float x = 0;
float y = 0;
float theta = 0;
float thickness = 0;

Branch() {
};

Branch (Branch branch) {
x = branch.x;
y = branch.y;
theta = branch.theta;
thickness = branch.thickness;
}
}

class Tree {

String axiom, currentString;
String productionRule;
Branch branch;
Stack branchStack;
int pos = 0;
color col;
float angle = PI/10;
float angleChaos = 1;
float initialThickness = 18;
float thickness = initialThickness;

Tree () {
axiom = "F";
currentString = axiom;
branch = new Branch();
productionRule = "F[+FF-F-F][-FF+F-F]";
branchStack = new Stack();
}

void grow() {
grow(1);
}

void grow(int generations) {
for (int i = 0; i < generations; i++) {
String nextString = "";
for (int j = 0; j < currentString.length(); j++) {
char c = currentString.charAt(j);
if (c == "F") {
nextString += productionRule;
}
else {
nextString += c;
}
}
currentString = nextString;
}
}

void draw() {
for (int i = 0; i < currentString.length(); i++) {
this.drawBranch();
}
}

void drawBranch () {
if (pos >= currentString.length()) return;
char c = currentString.charAt(pos);
switch (c) {
case "F":
fill(100 + random(-40, 40), 42 + random(-40, 40), 42);
String word = (wordCount < words.length - 1) ? words[wordCount++] : "noword";
branch.thickness = thickness;
textFont(createFont("Helvetica", branch.thickness));
pushMatrix();
translate(branch.x, branch.y);
rotate(branch.theta);
text(word, 0, 0);
popMatrix();
float extension = textWidth(word);
branch.x += extension * cos(branch.theta);
branch.y += extension * sin(branch.theta);
break;
case "-":
branch.theta -= (angle + random(-1.0 * angle * angleChaos, angle * angleChaos));
break;
case "+":
branch.theta += (angle + random(-1.0 * angle * angleChaos, angle * angleChaos));
break;
case "[":
branchStack.push(new Branch(branch));
if (thickness > 3) {
thickness -= 3;
}
else {
thickness = 1;
}
break;
case "]":
branch = (Branch)branchStack.pop();
thickness = branch.thickness;
break;
}
pos++;
}
}

void setup () {
size(500, 500);
background(#141414);
frameRate(60);
smooth();
tree = new Tree();
tree.grow(3);
}

void draw () {
translate(width/2, height);
rotate(1.5 * PI);
tree.drawBranch();
}

</script>

The L-system code is based on this Processing code written by Daniel Jones.

A Simple L-system in Processing.js

Recently I attended TEDxVancouver 2011 and my favourite talk by far was by a brilliant generative artist named Jer Thorp. I have always been a fan of generative art, but have never been motivated to create any of my own. Jer's talk inspired me to play with one of the tools that he uses to create his works;Processing, which is a Java-like programming language, development environment and runtime, optimized for creating images, animations, simulations and interactive visuals.

Processing projects or "sketches" are typically packaged as self-contained Java applets and can be embedded in web pages or run stand-alone. This however requires that a JVM is installed and that the user has given Java applets permission to run in the browser, so I was very happy to hear that Processing has been ported to JavaScript, which allows Processing sketches to be embedded in, or referenced by HTML pages, and run directly by any HTML5-capable browser. The new API, called processing.js, makes use of the new HTML5 Canvas element, and WebGL for 3D rendering. Processing.js supports about 90% of the Processing language.

Processing.js provides three ways to reference a sketch in an HTML page:
  1. You can reference the file that contains the Processing source code in the same way you would reference an external JavaScript file.
  2. You can embed the Processing script directly in-line in the HTML, again in the same way you can embed JavaScript directly in an HTML file.
  3. You can use Processing.js as a pure JavaScript API.
In the first two cases Processing.js parses the Processing code and converts it to JavaScript. This obviously has performance implications, but it is very convenient to be able to prototype your sketches in the Processing IDE, and the DOM and other JavaScript embedded or referenced in the page is still accessible to your Processing code. If you want a richer development experience there is also a Processing plug-in for Eclipse, and the Processing API has also been ported to other languages including Ruby, Scala and Clojure.

For my initial project I decided to build a simple L-System, to simulate the growth of a plant and then progressively render the resulting simulation. A Lindenmayer System is a string-rewriting technique that can be used to simulate plant growth. I also wanted to experiment with having the Processing code interact with the DOM and other JavaScript in an HTML page, so I decided that I would wrap my experiment in a blog post and use the words in the blog as the "branches" of the plant.

It took me a few hours to implement an L-Systems in Processing, and then a few more to get my code working as embedded Processing.js code in a simple web page. I also spent a couple of hours researching how to deal with older browsers that do not support HTML5 and the Canvas element, but in the end I decided to simply fail elegantly (I hope) in the absence of support for the Canvas element, which I detect using Modernizr.

And then I tried to get it all working inside a Blogger blog post. This was probably the hardest, most frustrating and time-consuming part of the whole process. After a good four hours of finding the right CDN for each script, modifying script load orders, editing the blog template, and minifying my code, I got it all working. I have tested it on IE 6 through 8 (elegant fail), IE9 (success!) and a number of versions of Firefox, Safari and Chrome, but you never know;if it causes your browser to throw an exception, I apologise.

And here is the final result (which has probably completed animating while you read the post so go ahead and refresh the page):

Update (March 16th, 2012): I finally got the code in this post working again. The reason that it broke is that both the Blogger web editor and Windows Live Writer do some infuriating auto-formatting which breaks the inline Processing script! I broke the code by attempting to fix a typo using first one and then the other of the aforementioned tools. Two rounds of auto-meddling left the page totally broken. Fixing it was a pain in the arse, but here you go.


If anyone is interested I will post the code in a subsequent post. Everything is embedded in this very page, but finding it amongst all of the boilerplate/template markup is a pain in the arse.
I plan to make my L-System more complex and reflective of real plant growth so look out for more posts and more code.

Tuesday, November 8, 2011

All Your node Are Belong to IIS

I recently wrote a post in response to a criticism of node.js. The author’s major gripe was about the performance characteristics of node, which is essentially single-threaded. I asserted that you could probably address this by load-balancing across multiple instances of node on the same server. Well Tomasz Janczuk has developed a better solution, called iisnode, which allows you to host node in Internet Information Server and leverage some of IIS’ process management, security, logging, scalability and management capabilities.

Tomek has documented how to get iisnode up and running in his blog post titled Hosting node.js applications in IIS on Windows.

The prolific Scott Hanselman, who is the Kurt Vonnegut of software development bloggers, has a great post about iisnode titled Installing and Running node.js applications within IIS on Windows - Are you mad?. It provides a thorough overview of iisnode and also includes some interesting performance data.