Deep Mirror
05 May 2014I threw together a CFDG inspired library for Racket, which I named Deep Mirror.
CFDG popped up in maybe 2004? 2003? Somewhere back there. I played with it some initially, then played with it again when the guys at Context Free Art made a version with a nice GUI.
Short version is, you write a bunch of rules which behave as a generative context free grammar. Various terminals in the grammar result in image elements being created, and annotations on terminals (and nonterminals) result in the state of the drawing system being altered. If you want to make images out of recursive elements, this is a pretty good way to go.
I made some pictures with it, but the version of the language out then didn’t allow you to write functions, or, as I recall, perform any arithmetic at all. People did some neat things, and made some attractive art, but I got bored.
For whatever reason, it popped back up in my mind this week, and I thought I’d try and stuff something like CFDGs into Racket, while leaving you the full power of Racket. I wonder what else I might’ve concocted if I’d had the entirety of the math library available to me back then.

I arranged my library to behave a bit differently from the other tools. Instead of applying arguments to the various rules/shapes, they just inherit whatever the current drawing state is, sort of like OpenGL.
You can only multiply new transformations
(x
, rotate
, sheary
, etc) into
the current transformation matrix; no forcing the rotation or
translation to specific values. But the hue, saturation, brightness
and alpha can all be set to a specific value (with hue=
,
brightness=
, etc), or you can multiply the existing value
by a new one (with saturation
, alpha
, etc).
The state gets pushed and popped onto a stack, either with the
scope
macro, or by calling a rule. scope
is convenient when a rule is going to branch, and you want to define
the changes for each branch in terms of your rule’s starting state,
rather than defining the second branch’s state in terms of the first’s.
Please note! I’d be happy to take pull requests for this stuff, or anything else that would be neat.
I want to get some continuation manipulation stuff going to rearrange the order in which evaluation occurs. First (read: simplest) I want to change the recursion to be breadth first, instead of depth first. That’d take care of my tentacle problem above.
Second, I’d like to experiment with rearranging evaluation so that the scale of the current transformation matrix is used to reorder all the outstanding rules from largest to smallest. Or vice versa. Keeping an eye on the current scale would also let me cut off recursion sooner. Once you’re down to drawing subpixel elements… well. You’d have a lot of work to do to influence the final output.
Third, I’m hoping that while playing with these static alterations to control flow, I might come up with some neat way for the user to specify control flow, which fits with the style of CFDGs.
I’d also like to fiddle with the parameterization of the state. I’m a little worried that what I’m doing to keep the state hidden in the background is doing tragic things to the performance.
Oh! Layers, so you can manipulate the z-index. Which would be another way of getting my uncooperative tentacles arranged neatly.