Back to draw-Gnuplot

Turtle graphics

The idea of this toy package arose during a conversation between Rafa Rodríguez and me in Vigo (Galicia - Spain). It was in july of 2008 when we met there during a course on free maths software at the School of Telecommunications Engineering. His talk was about Octave and mine on Maxima.

While drinking some beers he told me that he was an enthusiast of the Logo programming language and asked me if it could be possible to perform turtle graphics with Maxima. I considered this question as a nice challenge and here is a (very) simple implementation of the idea, in part due to Rafa's idea, in part due to the beers.

The idea is to define a new object called turtle, such that we can pass to it as arguments sentences in logo-like style. This is the list of available sentences:

Objects of type turtle can live together with other draw2d objects, such as explicit, parametric and so on. Also, turtle graphics should be compatible with draw's graphics options.

After loading package turtle.mac we are ready to do some simple things.

load("path/turtle.mac")$ 

These examples look better on a proportional canvas. Here we set once and for the rest of the session this option as default.

set_draw_defaults(
  terminal          = svg,
  dimensions        = [350,350],
  proportional_axes = xy) $ 

A square in blue. See how we can control the x and y ranges and the color with standard draw options:

draw2d(
  xrange = [-25, 75],
  yrange = [-25, 75],
  color  = blue,

  turtle(
    forward(50),
    right(90),
    forward(50),
    right(90),
    forward(50),
    right(90),
    forward(50)) ) $ 
turtle1

Sort of flower made with squares. With to we define a procedure named square and with repeat we draw the squares and make rotations. Angles are always measured in degrees:

draw2d(
  turtle(
    to(square,[side],
       repeat(4,
       forward(side),
       right(90))),
    repeat(10,
           square(100),
           left(36))) ) $ 
turtle2

A colored flower. Here we make use of the turtle commands to control the colors. Also, command make is used to assign values to variables; Maxima's colon (:) operator shouldn't be used here. Colors are defined by integers from 1 to 16: black, blue, green, cyan, red, magenta, yellow, white, brown, #d2b48c, forest-green, aquamarine, salmon, purple, orange, grey :

draw2d(
  turtle(
    setpensize(2),
    to(square,[],
       repeat(4,
              forward(100),
              right(90))),
    make(col,1),
    repeat(20,
           setpencolor(col),
           make(col,col+1),
           square(),
           left(18))) ) $ 
turtle3

An ellipse of varying width. Command setheading sets the orientation of the turtle's head in degrees. arc(a,r) draws an arc, where a is the angle and r the radius, the center being the position of the turtle. Note that the turtle is always at (0, 0):

draw2d(
  turtle(
    make(ancho, 1),
    make(orienta, 90),
    repeat(71,
           setpensize(ancho),
           setheading(orienta),
           arc(10,5),
           make(ancho,ancho+0.1),
           make(orienta,orienta+5)))) $ 
turtle4

Two turtle graphics. Note how we play with commands penup, pendown and sety to move the turtle to a new position. penup and pendown are called as functions without arguments:

draw2d(
  turtle(
    make(ancho, 1),
    make(orienta, 90),
    repeat(71,
           setpensize(ancho),
           setheading(orienta),
           arc(10,5),
           make(ancho,ancho+0.1),
           make(orienta,orienta+5)),
    to(cuadrado,[],
       forward(sqrt(2)*9),
       right(90)),
    setpensize(2),
    setpencolor(10),
    penup(),
    sety(9),
    pendown(),
    setheading(-45),
    repeat(4,
           cuadrado()) ) ) $ 
turtle5

A circumference. In this case, the turtle walks along the curve:

draw2d(
  turtle(
    to(circunferencia,[],
       repeat(360,
              forward(1),
              right(1))),
    circunferencia()) ) $ 
turtle6

A circumference formed by a polygonal line:

draw2d(
  turtle(
    to(poly,[side,angle,times],
       repeat(times,
              forward(side),
              right(angle))),
    poly(10,92,100)) ) $ 
turtle7

Spiral:

draw2d(
  turtle(
    to(espi,[side,angle,inc,times],
       /* arguments to procedures can't
          be changed; we can create a new
          variable */
       make(lado,side),
       repeat(times,
              forward(lado),
              right(angle),
              make(lado, lado+inc))),
    espi(1,10,5,200)) ) $ 
turtle8

Rotated square:

draw2d(
  turtle(
    to(square,[side],
       repeat(4,
              forward(side),
              right(90))),
    right(70),
    square(20)) ) $ 
turtle9

Playing with arc:

draw2d(
  turtle(
    penup(),
    make(radius, 10),
    repeat(10,
           arc(360, radius),
           forward(5),
           make(radius, radius-1))))$ 
turtle10

Nested loops:

draw2d(
  turtle(
    setpencolor(5),
    repeat(24,
           repeat(3,
                  forward(35),
                  right(120)),
           right(15) ) )) $ 
turtle11

Colored random walk. To force multiple evaluations of Maxima's random function inside the loop, don't forget to write the simple quote operator:

draw2d(
  turtle(
    repeat(50,
    setpencolor('random(16)),
    forward('random(50)),
    right('random(180))) ) ) $ 
turtle12

Variable repcount stores the number of the iteration being executed in the most internal loop; in this case, from 1 to 200:

draw2d(
  turtle(
    setpencolor(3),
    make(counter, 1),
    repeat(200,
           forward(counter),
           make(counter, counter+1),
           right(89)))) $ 
turtle13

Multiple polygons:

draw2d(
  turtle(
    to(poly,[n],
       repeat(n,
       forward(1),
       right(360 / n))),
    make(counter, 3),
    repeat(16,
           setpencolor(counter),
           poly(counter),
           make(counter, counter + 1)) )) $ 
turtle14

Random curve. Example with the ifelse command:

draw2d(
  turtle(
    repeat(100,
           make(direction, 'random(5)),
           make(rotation, 'random(30)),
           forward(direction),
           ifelse(direction=0,
                  [left(rotation)],
                  [right(rotation)])) ) ) $ 
turtle15

© 2011-2016, TecnoStats.