Fun with turtle graphics and stars

After Saturday’s post on using turtle graphics to draw letters, I wanted to get back into drawing some fractals. Fractals are cool.

In particular, there’s this one fractal that I always used to draw in middle/high school by hand. It got a little complicated after a few iterations, but it was a good way to keep my hands busy during class. Anyways, without further ado, here’s what I’m trying to generate:

Sort of a combination star/snowflake/spirally thing. In any case, it turns out the code to draw it isn’t actually that terribly complicated:

(define (draw-star! t d n)
  (let loop ([d d] [n n] [skip 5])
    (set-pen-color! t (color (random 256) (random 256) (random 256)))
    (when (> n 0)
      (turn-to! t 0)
      (repeat 4
        (turn! t 90)
        (when (not (= (mod skip 360) (mod (turtle-direction t) 360)))
          (block t
            (move! t d)
            (let* ([d2 (* 0.5 (sqrt 2) d)])
              (block t
                (turn-and-move! t -135 d2)
                (turn-and-move! t -90 d2)
                (move-and-turn! t (- d2) 45)
                (let loop ([i 10] [d3 (* 0.5 (sqrt 2) d2)])
                  (when (> i 0)
                    (move-and-turn! t d3 -45)
                    (loop (- i 1) (* 0.5 (sqrt 2) d3))))))
            (loop (/ d 2) (- n 1) (+ 180 (turtle-direction t)))))))))

Perhaps the most interesting bit is the variable skip. The goal is that when you expand out in a direction, you only recursively expand in the three directions other than the one you came from. If you take out the skip code, you get something more like this:

Still neat, but not what I was going for. As a side note, I started with (= skip 5) basically because none of the branches are going to be at 5 degrees. Originally, I started with skip as #f, but that didn’t work so well with =. So it goes.

I used a few helper functions to shorten the turn/move blocks, but they’re obvious enough (I’m actually considering adding them to the API though):

(define (turn-and-move! t turn move)
  (turn! t turn)
  (move! t move))

(define (move-and-turn! t move turn)
  (move! t move)
  (turn! t turn))

To draw it, this is all you need:

(let ([turtle (hatch)])
  (draw-star! turtle 100 4)
  (draw-turtle turtle))