Turtle graphics

Luxor provides some basic "turtle graphics" functions. Functions to control the turtle begin (somewhat unusually) with a capital letter: Forward, Turn, Circle, Orientation, Towards, Rectangle, Pendown, Penup, Pencolor, Penwidth, and Reposition, and so on, and angles are specified in degrees rather than radians.

using Luxor, Colors
Drawing(600, 400, "../assets/figures/turtles.png")
origin()
background("midnightblue")

๐Ÿข = Turtle() # you can type the turtle emoji with \:turtle:
Pencolor(๐Ÿข, "cyan")
Penwidth(๐Ÿข, 1.5)
n = 5
for i in 1:400
    global n
    Forward(๐Ÿข, n)
    Turn(๐Ÿข, 89.5)
    HueShift(๐Ÿข)
    n += 0.75
end
fontsize(20)
Message(๐Ÿข, "finished")
finish()

turtles

List of words the turtle knowsAction
ForwardMore forward by d units
TurnIncrease the turtle's rotation by n degrees
CircleDraw filled circle centered at current pos
HueShiftShift the Hue of the turtle's pen color by n
MessageOutput text
OrientationSet the turtle's orientation to n degrees
Pen_opacity_randomSet opacity to random value
PencolorSet the Red, Green, and Blue values
PendownStart drawing
PenupStop drawing
PenwidthSet the width of the line to n
PopMove turtle to the value stored on the stack
PushSave the turtle's position on the stack
Randomize_saturationRandomize the saturation of the current color
RectangleDraw filled rectangle centered at current pos
RepositionPlace turtle at new position
TowardsRotate turtle to face towards a point

The turtle commands expect a reference to a turtle as the first argument (it doesn't have to be a turtle emoji!), and you can have any number of turtles active at a time.

quantity = 9
turtles = [Turtle(O, true, 2ฯ€ * rand(), (rand(), rand(), 0.5)...) for i in 1:quantity]
Reposition.(turtles, first.(collect(Tiler(800, 800, 3, 3))))
n = 10
Penwidth.(turtles, 0.5)
for i in 1:300
    global n
    Forward.(turtles, n)
    HueShift.(turtles)
    Turn.(turtles, [60.1, 89.5, 110, 119.9, 120.1, 135.1, 145.1, 176, 190])
    n += 0.5
end
finish() # hide

many turtles

A turtle graphics approach lends itself well to recursive programming. This short recursive function draws a Hilbert curve.

function hilbert(t::Turtle, level, angle, lengthstep)
    level == 0 && return

    HueShift(t, 0.1)

    Turn(t, angle)
    hilbert(t, level-1, -angle, lengthstep)

    Forward(t, lengthstep)
    Turn(t, -angle)
    hilbert(t, level-1, angle, lengthstep)

    Forward(t, lengthstep)
    hilbert(t, level-1, angle, lengthstep)

    Turn(t, -angle)
    Forward(t, lengthstep)
    hilbert(t, level-1, -angle, lengthstep)

    Turn(t, angle)
end

@draw begin
background("black")
setline(2)
setlinecap("round")

hilbert(Turtle(first(BoundingBox()) + (12, 12), true, 0, (1, 0, 0)),
        6,  # level
        90, # turn angle, in degrees
        6   # steplength
        )
end

hilbert turtle