Like the Circles in Space Series, this program demonstrates the advantages of creating images with code by using repetition, geometry and pseudo-randomness. The shapes of each grid are based on a pre-generated list of 1s and -1s. Each form recalls a galaxy, an effect that is reinforced by the black background and light green boxes.
The rest of this post will review the code for this series.
STYLE
Unlike the prevous samples of code I’ve reviewed, this program does not define its helper functions externally. Instead, functions like direction-list-maker and turtle-dragon are defined in a let statement included at the beginning of the image-series declaration.
(letrec ((direction-list-maker
(lambda (n)
(if (zero? n)
null
(append (direction-list-maker (- n 1))
(cons 1 (map (r-s * -1)
(reverse (direction-list-maker (- n 1))))))))))
(let* ((canvas (image-new width height))
(koopa (turtle-new canvas))
(iteration (+ 4 (modulo n 11)))
(direction-list (direction-list-maker iteration))
(distance (* 3 (/ width 100)))
(red-list (list "red" "maroon" "fuchsia"))
(blue-list (list "blue" "mediumslateblue" "cyan" "aqua" "azure"))
(green-list (list "mediumseagreen" "green" "springgreen" "olive" "lawngreen"))
(turtle-dragon! (lambda (x)
(turtle-forward! koopa distance)
(turtle-turn! koopa (* x 90)))))
Scheme let statements, like the one above, are composed of a series of statements. Each statement is surrounded by parentheses and composed of a variable name followed by a definition, also enclosed in parentheses. For example, the highlighted line in the let statement above tells the computer that the variable distance is equivalent to
(* 3 (/ width 100)
Whenever distance is used in the rest of the code (as it is in the definition of turtle-dragon!), the computer replaces the variable name with the value that results from its definition equation (in this case, (* 3 (/ width 100)).
Because the definition of turtle-dragon! relies on a variable that is defined within the same let statement, the student includes an asterisk after let to indicate that the let statement definitions are interrelated. If the asterisk was omitted, the use of distance within turtle-dragon! would return an error because distance is undefined.
The other form of the let statement used in the example above is letrec. A letrec statement allows functions to be defined recursively.
Although let statements are helpful for defining simple variables like distance, long let statements with multiple definitions or let statements with complex definitions are often difficult for readers to understand, and external helper functions should be used in these cases. Fortunately, most of the definitions provided by this student are short.
TECHNIQUE
The student’s code uses the turtles graphics model, in which digital “turtles” are used for drawing. To use a turtle, the student calls the built-in turtle-new procedure to generate a new turtle for the given canvas. Turtle-new must be called within a definition so that the new turtle is immediately assigned a name for the student to refer to later. In the let statement above, line 10 names a new turtle “Koopa.” After “Koopa” is created and named, it can be used as a parameter for turtle functions to draw on the canvas.
There are six core turtle operations in the Mediascripting Library. Four of these operations are used for moving or orienting the turtle on the canvas. They include:
(advances the turtle the specified amount, drawing if the pen is down.turtle-forward!turtleamt)(turns the turtle clockwise the specified number of degrees.turtle-turn!turtledegrees)(moves the turtle to a particular column and row.turtle-teleport!turtlecolumnrow)(makes the turtle face a direction the specified number of degrees clockwise from right.turtle-face!turtledegrees)
As in the turtle-dragon! procedure above, these four operations can be combined to create more complex move sets.
The other two procedures are used for manipulating the turtle’s “pen.” The turtle’s pen is the current brush, so it retains the size, style and color of the current brush. The two operations that control the turtle’s pen are:
(lifts the turtle’s pen.turtle-up!turtle)(drops the turtle’s pen.turtle-down!turtle)
When a turtle moves forward with its pen down, it creates a brushstroke. Conversely, if the pen is up, no marks are made on the canvas. With these tools, users can move the turtles around the screen to “draw” on the canvas without using the mouse or paintbrush tool.
For the grid shapes in the images above, the student has created the turtle-dragon! procedure. When turtle-dragon! is called, it moves the turtle a uniform distance forward then turns it left or right, depending on the next value in the list “direction-list”, which is generated by the function direction-list-maker. Because “koopa” may only turn left or right, he leaves behind a box pattern with the brush.
To get the various colors for the turtle lines, the student creates three lists of colors: “red-list,” “blue-list,” and “green-list.” Depending on the value of n, the student selects the color of the turtle’s brush from one of the three lists. If n is less than 333, the brush’s color will be from “blue-list.” If n is greater than or equal to 333 but less than 666, the brush’s color will be from “red-list.” Finally, if n is greater than or equal to 666, brush colors from all of the lists will appear in the generated image. This strategy not only ensures that the program will generate at least 1000 images, it also adds interest to each image created.


I’d recognise that fractal anywhere! Looks very slick, do you know about the relationship of the dragon-curve and Base −1±i ?
http://en.wikipedia.org/wiki/Complex_base_systems#Base_.E2.88.921.C2.B1i
Yes! It’s one of the things we teach in our intro class.