FORM+CODE in Design, Art, and Architecture

Repeat: RECURSIVE TREE

Within the domain of image making, recursion involves drawing a group of related, self-similar shapes. Treelike forms are a clear example — each branch spawns many smaller branches, which in turn spawn more branches. As a simple example, draw the letter Y on a sheet of paper. Now draw two smaller Ys sprouting from the top of each branch. After repeating this process a few times, the number of Ys drawn at each step has increased from 1 to 2, to 4, 8, 16, 32, 64, and so on.

While this type of tree makes a predictable shape, adding a small amount of randomness to the line lengths and number of branches can yield more organic forms. These treelike forms were created by drawing one circle at a time. Starting at the base, each circle was slightly rotated and scaled relative to the one before it. At random intervals during the growth, two smaller branches sprout to form new growths. This continues until the circles reach the minimum size set by the user.

/**  * Repeat: Recursive Tree  * from Form+Code in Design, Art, and Architecture   * by Casey Reas, Chandler McWilliams, and LUST  * Princeton Architectural Press, 2010  * ISBN 9781568989372  *  * This program is based on Context Free program   * "Foggy Tree by Chris Coyne:  * http://www.contextfreeart.org/gallery/view.php?id=4   *   * This code was written for Processing 1.2+  * Get Processing at http://www.processing.org/download  */ float dotSize = 9; float angleOffsetA; float angleOffsetB; void setup() {   size(900, 600);   noStroke();   fill(0);   smooth();   frameRate(1); // Redraw the tree once a second      angleOffsetA = radians(1.5); // Convert 1.5 degrees to radians   angleOffsetB = radians(50); // Convert 50 degrees to radians } void draw() {   background(255); // White background   translate(width/2, height); // Move to the center, bottom of the screen   seed1(dotSize, radians(270), 0, 0); // Start the tree } void seed1(float dotSize, float angle, float x, float y) {      if (dotSize > 1.0) {          // Create a random numbers between 0 and 1     float r = random(0, 1.0);          // 98% chance this will happen     if (r > 0.02) {       ellipse(x, y, dotSize, dotSize);       float newx = x + cos(angle) * dotSize;       float newy = y + sin(angle) * dotSize;       seed1(dotSize * 0.99, angle - angleOffsetA, newx, newy);        }     // 02% chance this will happen     else {       ellipse(x, y, dotSize, dotSize);       float newx = x + cos(angle);       float newy = y + sin(angle);       seed2(dotSize * 0.99, angle + angleOffsetA, newx, newy);       seed1(dotSize * 0.60, angle + angleOffsetB, newx, newy);       seed2(dotSize * 0.50, angle - angleOffsetB, newx, newy);     }    } } void seed2(float dotSize, float angle, float x, float y) {      if (dotSize > 1.0) {          // Create a random numbers between 0 and 1     float r = random(0, 1.0);          // 95% chance this will happen     if (r > 0.05) {       ellipse(x, y, dotSize, dotSize);       float newx = x + cos(angle) * dotSize;       float newy = y + sin(angle) * dotSize;       seed2(dotSize * 0.99, angle + angleOffsetA, newx, newy);     }      // 05% chance this will happen     else {       ellipse(x, y, dotSize, dotSize);       float newx = x + cos(angle);       float newy = y + sin(angle);       seed1(dotSize * 0.99, angle + angleOffsetA, newx, newy);         seed2(dotSize * 0.60, angle + angleOffsetB, newx, newy);       seed1(dotSize * 0.50, angle - angleOffsetB, newx, newy);     }   } }

Contributed Examples

DOWNLOAD ALL CODE EXAMPLES

We are looking for implementations of the code examples in other programming languages to post on the site. If you would like to submit a sample, or if you find a bug, please write to