Download the full procedural methods project here. The post-processing and additive faulting will be discussed in later posts. For a full catalogue of all 30 L-systems in this project see this post.
Turtle Graphics
The turtle I created for this application uses a dynamic texture as its canvas. At the start of a drawing the texture is cleared to black. When the turtle interprets a draw command it begins moving in the direction it is currently facing, leaving a 1-pixel-wide white trail behind it. There are 7 different commands the turtle can understand:
COMMAND_DRAW
COMMAND_MOVE COMMAND_TURN_LEFT COMMAND_TURN_RIGHT COMMAND_PUSH COMMAND_POP COMMAND_NOTHING |
Move forward in the direction currently facing while drawing to the texture.
Move forward in the direction currently facing, without drawing. Turn left (anticlockwise) by an angle in degrees. Turn right (clockwise) by an angle in degrees. Remember the current orientation and position and push them onto a stack. Revert to the last remembered position and orientation and remove it from the stack. Do nothing (useful for symbols which should not be interpreted by the turtle but which are used to control the evolution of the curve). |
L-Systems
As a quick example let’s assume the rule 'F' with production "F+F" and the rule '+' with production "+" (meaning that '+' is a constant in this system). Every character used in a production must have its own rule, even if that rule is just the character itself. With axiom "F" this produces the series: "F", "F+F", "F+F+F+F", "F+F+F+F+F+F+F+F" and so on. If this is then interpreted by the turtle with 'F' meaning draw a line and '+' meaning turn left 90°, this would start with a line and end up as a square that the turtle continually drew over itself.
Teaching a turtle to draw
bool TeachCommand(char symbol, std::string production, CommandType type, int amount = 0);
Once the turtle has all of the required commands in its vocabulary and any additional data has been set such as the axiom and the initial position and orientation of the turtle, it can begin iterating on the L-system and interpreting the resulting string as a drawing on the dynamic texture.
Since the turtle rendering system is based on the idea of a virtual drawing robot moving across a canvas, it can be animated to see the lines being drawn in real time. In this application the rendering can be done instantly so as to quickly iterate through levels of an L-system, or animated to see how the pattern emerges. For very high iterations of certain schemes the rendering can take tens of seconds to do all at once, so it’s recommended to animate it rather than just freeze the program. The speed of the turtle can be controlled in real time.
A problem of scale
The scale s at the nth iteration is based on the scaling factor f such that s = f^n . As an example let's assume the rule 'F', production "FF", scaling factor 0.5 and axiom 'F'. The scale for the initial drawing (or 0th iteration) would be s = 0.5^0 = 1, resulting in a straight line amount % across the texture. After 1 iteration the command string would be "FF" drawn at a scale s = 0.5^1 = 0.5, meaning each line is now (0.5 × amount) % long, resulting in the same length line overall. Regardless of how many iterations are performed, the scaling factor of 0.5 is the perfect amount for limiting the total size of this L-system such that it always occupies the same amount of space on the canvas. For some L-systems which model plants it may be appropriate to choose a non-perfect scaling amount so that the drawing appears to grow as the plant becomes more detailed.