### The Ikea Lillabo Processing code

By popular demand... here's the code, written in Processing that actually draws the train sets. I hadn't released it because I didn't think it was very interesting, but you are welcome to it.

// --------------------------------------------------------------------------

//

// Small program to draw pictures of Ikea Lillabo track layouts using

// instructions derived from my Perl program.

//

// Written by John Graham-Cumming (http://www.jgc.org/)

//

// Released under the General Public License, version 2

//

// --------------------------------------------------------------------------

// This is the cursor position (x, y) coordinates and angle to the

// horizontal

float x, y, a;

// The length in pixels of a single straight piece

float len = 40;

// See the Perl program for a full explanation, but there are 8 curves

// in a circle and from that the radians of curve arc, the length of the

// straight line between the curve ends and the curve angle to the

// horizontal can be calculated.

float curves_in_circle = 8;

float radians_in_curve = 2 * PI / curves_in_circle;

float curve_angle = radians_in_curve / 2;

float curve_length = len * 2 * cos(PI/2 - radians_in_curve/2);

// The Processing equivalent of main()

void setup() {

// Set up the basic parameters for the drawing: a 1000x1000 canvas,

// with a white background. None of the elements drawn will be filled

// and the lines will be four pixels wide.

size(1000,1000);

background(255,255,255);

strokeWeight(4);

noFill();

// These are the nine possible layouts discovered by the Perl program

// and were copy/pasted here. Clearly this would be better done

// dynamically with this program reading the Perl program's output.

int layouts = 9;

String s[] = new String[layouts];

s[0] = "AAAACCAAAASSAAB";

s[1] = "CCCCCCSSAAAAAAB";

s[2] = "CAAAAACASSAAAAB";

s[3] = "CAAAAASCASAAAAB";

s[4] = "CAAAAASSCAAAAAB";

s[5] = "AAACAACAAASSAAB";

s[6] = "ACAAAASACSAAAAB";

s[7] = "ACAAAASSACAAAAB";

s[8] = "AACAAASSAACAAAB";

// (row, col) is the row and column position of the next layout to draw

// starting from the top left of the canvas. Since we know there are

// 9 the loop below lays them out 3x3. h is the height of space

// reserved for a layout.

int row = 0;

int col = 0;

int h = 250;

int w = h + 50;

for ( int j = 0; j < layouts; j++ ) {

// Start 200 pixels from the top left corner and with an initial

// angle of 0

a = 0;

x = 200 + w * col;

y = 200 + h * row;

col++;

if ( col == 3 ) {

col = 0;

row++;

}

for ( int i = 0; i < s[j].length(); i++ ) {

switch(s[j].charAt(i)) {

case 'B':

bridge();

break;

case 'C':

clockwise();

break;

case 'A':

anticlockwise();

break;

case 'S':

straight();

break;

}

}

}

}

// Function to draw a piece and update (x, y) and a

void draw_piece( float l, // Length of piece to be drawn

float ang ) // The angular change due to the piece

{

// If the ang is zero then this is a straight piece so use line(), if

// non-zero then it's a curve and so use arc()

if ( ang == 0 ) {

// (dx, dy) is the end of the piece truncated (the 0.8 multiplier)

// to leave a little gap between pieces.

float dx = x + l * 0.8 * cos(a + ang);

float dy = y + l * 0.8 * sin(a + ang);

line( x, y, dx, dy );

} else {

int h = (ang<0)?-1:1;

// (ox, oy) is the location of the centre of the circle on which the

// arc we are drawing lies. s and e are the starting and ending angles

// of arc to draw. Note that s must be less than e. Note the 1.5 here

// is used to shorten the arc to leave a small gap between pieces.

float ox = x - h * len * cos(PI/2-a);

float oy = y + h * len * sin(PI/2-a);

float s = a;

float e = a + ang * 1.5;

if ( s > e ) {

float t = e;

e = s;

s = t;

}

// The PI/2 adjustment here is needed because the angles in s and e are

// derived from a which is to the horizontal and the arc() function needs

// angles to the vertical

ellipseMode(CENTER);

arc( ox, oy, len*2, len*2, s - h * PI/2, e - h * PI/2 );

}

// Update (x,y) and a to be at the end of the new piece that's been

// added and with the correct orientation.

x += l * cos(a + ang);

y += l * sin(a + ang);

a += 2 * ang;

}

// Four functions to draw the four pieces giving them different colours.

void bridge()

{

stroke(255,0,0);

draw_piece(2*len,0);

}

void straight()

{

stroke(0,255,0);

draw_piece(len,0);

}

void clockwise()

{

stroke(255,0,255);

draw_piece(curve_length,curve_angle);

}

void anticlockwise()

{

stroke(0,0,255);

draw_piece(curve_length,-curve_angle);

}

Labels: pseudo-randomness

*If you enjoyed this blog post, you might enjoy my travel book for people interested in science and technology: The Geek Atlas. Signed copies of The Geek Atlas are available.*

<$BlogCommentBody$>

Create a Link

<< Home