Many of you have probably seen this old XKCD comic:

But it takes a special brand of geek to see that drawing as a challenge. Here’s my first attempt and its axiom:

Unfortunately, L-Systems aren’t really designed well for curves. You can draw them, but you’ve got to do something like “move forward small amount, turn 1 degree, repeat 180 times”. In L-System code this looks like this:

“DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DF”

DF = Move D forward, E+ = Turn 1 degree

But this is Valentine’s Day, and Valentine’s day should be a little hard. So here’s attempt 2:

As you can see a little closer to the mark, but we’ve got some overlap and the heart is kind of pointy at the curve transition. For attempt three I did a trick I used to do with cakes. Take a square, and add two-halves of a circle to two sides:

And then because it’s me, I thought, “can we make the heart just a tidge taller”:

Now most people would stop there, but I played around with a couple of other variants:

And then I thought, well now that I have this heart object, what else can I do with it?

Here’s the code for “Heart 3” my first successful attempt, which works with the programs in Chapter 4 of my book:

<?xml version="1.0"> <lSystemSpec> <imageAttr prefix="heart3LSys" lvl="6" scaling="0.5"></imageAttr> <ruleMappings turnAngle="15" length="250"> <rule cmd="forward" char="F"></rule> <rule cmd="right" char="+"></rule> <rule cmd="left" char="-"></rule> <rule cmd="begRecr" char="["></rule> <rule cmd="endRecr" char="]"></rule> <rule cmd="move" char="fg"></rule> </ruleMappings> <transformations axiom="Cg[X]BgA-TfRS-[X]S-RTfA-Bg[X]"> <replace char="X" replStr="Cg[X]BgA-TfRS-[X]S-RTfA-Bg[X]"></replace> <replace char="f" replStr="F"></replace> <replace char="R" replStr="DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DFE+DF"></replace> </transformations> <variables> <var char="A" value="9"></var> <var char="B" value="4.25"></var> <var char="C" value="-4.25"></var> <var char="D" value="0.034906585039886591538473815369772"></var> <var char="E" value="0.066666666666666666666666666666667"></var> <var char="S" value="3"></var> <var char="T" value="4"></var> </variables> </lSystemSpec>

Technically the “R’s” should be replaced with the whole long string and you can get rid of the R replacement rule, but I left it this way for readability. High-quality versions of the image are available by clicking on the image.

Happy Valentine’s Day, especially to you, the little red-haired girl 😉