REDUCE

18.3 Logo Turtle Graphics

18.3.1 Introduction

Logo Turtle Graphics3 (henceforth referred to as “LogoTurtle”) is a REDUCE emulation of traditional Logo turtle graphics with one turtle, modelled on Berkeley Logo by Brian Harvey and FMSLogo by David Costanzo (which is an updated version of George Mills’ MSWLogo, a multimedia-enhanced version for Microsoft Windows, which is itself based on Berkeley Logo). This manual section is derived primarily from the Graphics chapter of the Berkeley Logo manual available from GitHub.

This package is inspired by, and related to, the REDUCE Turtle package by Caroline Cotter (ZIB, Berlin, 1998), and the word “Turtle” below (with a capital T) will refer specifically to that package. Both packages are built on the REDUCE Gnuplot package, which itself uses Gnuplot to display plots. This means that plotting is not fully interactive as it would be in traditional Logo; a plot is constructed invisibly and only displayed when requested. However, turning on the LOGOTURTLE_AUTODRAW switch makes LogoTurtle as interactive as possible. This package aims to be more efficient, more authentic, more interactive and more complete than Turtle.

Note that LogoTurtle and Turtle cannot both be run in the same REDUCE session because they define some procedures with the same names.

18.3.2 Design

LogoTurtle is entirely functional. It uses “getters” and “setters”, and does not use any algebraic-mode variables (unlike Turtle). Most command names are as in Berkeley Logo and/or FMSLogo, and their function is the same or similar. (Identical behaviour is not always possible.) However, all commands are REDUCE procedure calls.

Getters (query procedures) return values that are accepted as input by their matching setters (command procedures). If more than one data value is involved then a list is used. For example, the LABELFONT query returns a list of the current label font face and size if both are set, which the corresponding SETLABELFONT command accepts as its argument.

LogoTurtle commands other than queries return nothing (nil) and plotting is achieved via side effects, not via returned values as for Turtle. A plot is displayed by calling the (non-traditional) DRAW command as for Turtle. The plot displayed need not be complete; DRAW displays the plot constructed so far, which allows an element of interactivity.

LogoTurtle makes essential use of commands to lower and raise the pen (unlike Turtle; see Pen and Background Control). Lowering the pen begins a “curve”, namely a sequence of points connected by straight lines, and raising the pen ends that curve. Each time the pen is lowered, the turtle moved and the pen raised, a distinct curve is produced.

LogoTurtle uses Lisp floating-point numbers internally and does not require any particular REDUCE number domain settings. However, all command arguments and list elements relating to turtle position must be expressions that can be evaluated to real numbers. All returned values and list elements relating to turtle position will be floating-point numbers. Note that LogoTurtle lists are REDUCE algebraic-mode lists delimited by curly braces, { }, not the square brackets used in traditional Logo, and that REDUCE list elements must be separated by commas.

18.3.3 User Interface

To use LogoTurtle, execute the REDUCE command

     load_package logoturtle;

LogoTurtle sets the scaling of the two axes to be the same so that the aspect ratio is 1:1 and geometry is correct (although beware that Gnuplot may not always honour this). By default, LogoTurtle scales the graphics window so that turtle coordinates \((-100,-100)\) and \((100,100)\) fit, and the center of the graphics window is turtle location \((0,0)\), i.e. the origin or home position. But this fixed window can be turned off so that Gnuplot automatically sizes the display to include the whole plot (as for Turtle). The position of the origin (the turtle home location \((0,0)\)) is then not fixed and may be different for different plots. The window size can also be changed; see Turtle and Window Control for further details.

Positive \(x\) is to the right; positive \(y\) is up. Headings (angles) are measured in degrees clockwise from the positive \(y\) axis. (Note that this differs from the common mathematical convention, also used by Turtle, of measuring angles counterclockwise from the positive \(x\) axis!) Initially, the turtle is at the origin (Cartesian coordinates \((0,0)\)) facing up (heading 0 degrees) with the pen up.

LogoTurtle uses by default a white background, and pen, fill and label colours chosen automatically by Gnuplot, but you can set all these to any colour provided by Gnuplot.

Note that LogoTurtle command names are shown using upper case letters in the descriptions after the example below to distinguish them clearly from their arguments, but LogoTurtle is case insensitive, so commands can be entered in either case.

Commands that never take any arguments use special syntax and need not be followed by empty parentheses. Query commands that take no arguments can be used like (read-only) variables. For example, the following command increments the \(x\)-coordinate of the turtle by 10 steps:

     setx(xcor + 10);

Multiple command arguments must be enclosed in parentheses; single or no arguments may be enclosed in parentheses, although parentheses can be, and usually are, omitted with a single argument or no arguments. However, if a single argument is an expression involving infix operators then it must be enclosed in parentheses.

When the switch TRLOGOTURTLE is on, LogoTurtle outputs Cartesian coordinates corresponding to every move of the turtle and DRAW outputs the list of curves that it is about to draw. When the switch TRPLOT is on, the commands sent to Gnuplot (but not the actual plot data) are also output. Turning the switch TRLOGOTURTLE on or off also turns the switch TRPLOT on or off. Both switches are off by default.

18.3.4 A Simple Example

This example assumes LogoTurtle has just been loaded but not yet used. If this is not the case then first execute the commands

  clearscreen; penup;

The following code draws an equilateral triangle with side length 100 centred on the origin, with one vertex on the positive Y axis. The sides are coloured red, green and blue. To make this example as interactive as possible, the plot is displayed after each side is drawn (but for this effect to be visible each line ending with draw; must be executed separately; if you input all the commands together then you will only see the complete triangle).

  forward(100/sqrt 3); pendown;
  setpencolor red; right 150; forward 100; draw;
  setpencolor green; right 120; forward 100; draw;
  setpencolor blue; right 120; forward 100; draw;

For more interesting examples, please see the files logoturtle.tst and mondrian.tst, which can be found online or in the packages/plot directory in a standard REDUCE distribution.

18.3.5 Turtle

The turtle is optionally displayed as an unfilled isosceles triangle; see Turtle and Window Control. The turtle is drawn using black default-thickness lines on top of the current plot; the colour and line thickness cannot currently be changed. The turtle is never wrapped, although it is clipped if any turtle mode is in effect, i.e. for drawing the turtle any turtle mode other than false is treated as window.

The turtle looks like an arrow head pointing in the direction of the turtle’s heading. The height of the isosceles triangle (i.e. the length of the turtle) is \(\ell (= 0.1)\) times the average of the maximum \(x\) and \(y\) coordinates set by the window size (even if windowing is not in effect) and the apex angle (at the head of the turtle) is twice \(\alpha (= 10^{\circ })\) (so that the two equal sides are at angles of \(\alpha \) to the turtle’s heading).4

The nominal turtle position is at the midpoint of the base (the short side). However, the turtle is drawn one step behind its nominal position, so that the display of the base of the turtle’s triangle does not obscure a line drawn perpendicular to it (as would happen after drawing a square).

18.3.6 Colours

LogoTurtle offers both the traditional Berkeley Logo palette model and some of the Gnuplot model, which is much more flexible and usually more convenient. Colours may be input and output in several different formats, but colour numbers and RGB lists are used only for input and only the formats accepted by Gnuplot are used for output, since these are the only formats used internally.

A colour number (input only)

is an integer between 0 and 15 inclusive. The initial colour assignments are

0 black 1 blue 2 green 3 cyan
4 red 5 magenta 6 yellow 7 white
8 brown 9 tan 10 forest 11 aqua
12 salmon 13 purple 14 orange 15 grey

but other colours can be assigned to numbers 8–15 by the SETPALETTE command. Colour numbers are useful for cycling programmatically through a range of colours.

An RGB list (input only)

is a list of three nonnegative numbers not greater than 100 specifying the percent saturation of red, green, and blue in the desired colour. RGB lists are also easy to use programmatically.

An identifier or string (input and output)

can be used to represent a colour in any way that is acceptable to Gnuplot, such as a colour name or hexadecimal number, e.g. red, "red" or "#FF0000".

The identifier FALSE(input and output)

means that no colour is set. In this case, Gnuplot uses its own automatic colour-choice algorithm.

18.3.7 Displaying Logo Turtle Graphics

Draw command
     DRAW

can be used at any time to display the current plot, i.e. the plot and/or labels constructed so far (provided there is something to display). It initially opens a Gnuplot window and subsequently updates it.

Autodraw switch

When the switch LOGOTURTLE_AUTODRAW is on, making any visible change to a plot causes it to be redrawn (or drawn) automatically. In this situation it can be useful to turn on display of the turtle (using SHOWTURTLE), since this makes the turtle’s heading and position visible even when the pen is up.

When using REDUCE programming constructs (e.g. group or loop statements) to run multiple LogoTurtle commands, it is best to have the LOGOTURTLE_AUTODRAW switch off, and instead to execute the DRAW command explicitly once the programming construct has completed, because intermediate changes to the plot will not be visible and repeatedly redrawing it is pointless.

18.3.8 Turtle Motion

Forward command
     FORWARD dist

moves the turtle forward, in the direction that it’s facing, by the specified distance (measured in turtle steps).

Back command
     BACK dist

moves the turtle backward, i.e., exactly opposite to the direction that it’s facing, by the specified distance. (The heading of the turtle does not change.)

Left command
     LEFT degrees

turns the turtle counterclockwise by the specified angle, measured in degrees. (A degree is 1/360 of a full circle.)

Right command
     RIGHT degrees

turns the turtle clockwise by the specified angle, measured in degrees.

Setpos command
     SETPOS position

moves the turtle to an absolute position in the graphics window. The input is a list of two numbers, the \(x\) and \(y\) coordinates, e.g. “SETPOS {50, 50}”.

Setxy command
     SETXY(xcor, ycor)

moves the turtle to an absolute position in the graphics window. The two inputs are numbers, the \(x\) and \(y\) coordinates.

Setx command
     SETX xcor

moves the turtle horizontally from its old position to a new absolute horizontal coordinate. The input is the new \(x\) coordinate.

Sety command
     SETY ycor

moves the turtle vertically from its old position to a new absolute vertical coordinate. The input is the new \(y\) coordinate.

Setheading command
     SETHEADING degrees

turns the turtle to a new absolute heading. The input is a number, the heading in degrees clockwise from the positive \(y\) axis.

Home command
     HOME

moves the turtle to its starting position (the origin) and orientation. Equivalent to “SETPOS {0, 0}; SETHEADING 0”.

Arc command
     ARC(angle, radius)

draws a circular arc centred on the turtle with the specified positive radius, starting at the turtle’s heading and extending clockwise through the specified angle (counter-clockwise if angle is negative). The turtle does not move and the arc is drawn as if the turtle mode is WINDOW for all modes unless windowing is turned off.

Circle command
     CIRCLE radius

draws a circle centred on the turtle with the positive radius specified. The turtle does not move and the circle is drawn as if the turtle mode is WINDOW for all modes unless windowing is turned off. Equivalent to ARC(360, radius).

Arc2 command
     ARC2(angle, radius)

moves the turtle around a circular arc that sweeps through the specified angle with the specified positive radius. The turtle always moves forwards: if angle is positive, then the turtle moves forwards in a clockwise direction; if angle is negative, then the turtle moves forwards in a counter-clockwise direction. At the end of the arc, the turtle’s heading is increased by angle.

Circle2 command
     CIRCLE2 radius

moves the turtle clockwise around a circle with the specified positive radius. The turtle ends in the same position in which it starts. Equivalent to ARC2(360, radius).

Ellipticarc command
     ELLIPTICARC(range, crosswise, inline, start)

draws an elliptic arc based on the turtle’s position and heading. The turtle does not move. The center-point of the ellipse is the turtle’s current position. The size and shape of the ellipse are determined by the specified positive crosswise and inline semi-axes. The crosswise semi-axis is the distance from the turtle to the ellipse in the direction perpendicular to the turtle’s current heading. The inline semi-axis is the distance from the turtle to the ellipse in the direction in which the turtle is currently heading. Hence the turtle’s heading determines the orientation of the ellipse. The elliptic arc starts at angle parameter start degrees and the angle parameter sweeps through range degrees. The elliptic arc is drawn clockwise if range is positive and counter-clockwise if range is negative.

Ellipse command
     ELLIPSE(crosswise, inline)

draws an ellipse based on the turtle’s position and heading. The turtle does not move. The center-point of the ellipse is the turtle’s current position. The size and shape of the ellipse are determined by the specified positive crosswise and inline semi-axes. The crosswise semi-axis is the distance from the turtle to the ellipse in the direction perpendicular to the turtle’s current heading. The inline semi-axis is the distance from the turtle to the ellipse in the direction in which the turtle is currently heading. Hence the turtle’s heading determines the orientation of the ellipse. Equivalent to ELLIPTICARC(360, crosswise, inline, 0).

18.3.9 Turtle Motion Queries

Pos query
     POS

returns the turtle’s current position, as a list of two numbers, the \(x\) and \(y\) coordinates.

Xcor query
     XCOR

returns a number, the turtle’s \(x\) coordinate.

Ycor query
     YCOR

returns a number, the turtle’s \(y\) coordinate.

Heading query
     HEADING

returns a number, the turtle’s heading in degrees.

Towards query
     TOWARDS position

returns a number, the heading at which the turtle should be facing so that it would point from its current position to the position given as the input in the form of a list of two numbers, the \(x\) and \(y\) coordinates.

Distance query
     DISTANCE position

returns a number, the distance the turtle must travel along a straight line to reach the position given as input in the form of a list of two numbers, the \(x\) and \(y\) coordinates.

As an example of using TOWARDS and DISTANCE, here is a somewhat convoluted way to angle the turtle towards, and then move it to, the position with coordinates \((1,2)\):

     setheading towards {1, 2};
     forward distance {1, 2};

18.3.10 Turtle and Window Control

Showturtle command
     SHOWTURTLE

makes the turtle visible (next time the picture is drawn).

Hideturtle command
     HIDETURTLE

makes the turtle invisible (next time the picture is drawn).

Clean command
     CLEAN

erases the graphics window. The turtle’s state (position, heading, pen mode, etc.) is not changed.

Clearscreen command
     CLEARSCREEN

erases and closes the graphics window, and sends the turtle to its initial position and heading. Like HOME and CLEAN together.

Setwindowsize command
     SETWINDOWSIZE n
     SETWINDOWSIZE(m, n)
     SETWINDOWSIZE {m, n}

with a single numerical argument \(n\) sets the size of the graphics window so that \(-|n| \le x,y \le |n|\); with two numerical arguments \(m, n\) or with a single list argument {m, n} in which \(m\) and \(n\) are numerical it sets the size of the graphics window so that \(-|m| \le x \le |m|, -|n| \le y \le |n|\). The default window size is \(-|100| \le x,y \le |100|\).

Wrap command
     WRAP

tells the turtle to enter wrap mode. From now on, if the turtle is asked to move past the boundary of the graphics window, it will “wrap around” and reappear at the opposite edge of the window. The top edge wraps to the bottom edge, while the left edge wraps to the right edge. (So the window is topologically equivalent to a torus.) This is the turtle’s initial mode. Compare WINDOW and FENCE.

Window command
     WINDOW

tells the turtle to enter window mode. From now on, if the turtle is asked to move past the boundary of the graphics window, it will move offscreen. The visible graphics window is considered as just part of an infinite graphics plane; the turtle can be anywhere on the plane. (If you lose the turtle, HOME will bring it back to the center of the window.) Compare WRAP and FENCE.

Fence command
     FENCE

tells the turtle to enter fence mode. From now on, if the turtle is asked to move past the boundary of the graphics window, it will move as far as it can and then stop at the edge with an “out of bounds” error message. Compare WRAP and WINDOW.

Setturtlemode command
     SETTURTLEMODE mode

sets the turtle (windowing) mode to one of WRAP, FENCE, WINDOW, with meaning as above, or FALSE, meaning that (like Turtle) there are no constraints on where the turtle draws.

Fill command
     FILL

fills the region of the graphics window bounded by the lines that have just been drawn, i.e. the current curve if the pen is down or the last curve if the pen is up (or the pen colour or size has been changed). The fill colour is the current pen colour and the pen size is ignored. The curve is implicitly closed but the turtle is not moved. For example, the following code draws a filled blue triangle and a filled green circle:

  clearscreen;
  setpencolor blue;
  pendown; setxy(0, 20); setxy(20, 0); fill;
  penup; setxy(50, 50);
  setpencolor green;
  pendown; circle(20); fill;
  draw;

Note that filling may cause the default pen (and hence fill) colour to change, but if the pen colour has been set explicitly then it will not change.

Filled command
     FILLED(colour, commands...)

executes the commands in the order written, remembering all points visited, and then draws the resulting curve, starting and ending with the turtle’s initial position, filled with the specified colour; see Colours. The pen size, whether the pen is up or down, and the pen colour are all ignored. The command arguments should be commands or lists of commands that move the turtle or draw curves. For example, the following code draws the same filled blue triangle and filled green circle as in the previous example:

  clearscreen; penup;
  filled(blue, setxy(0, 20), setxy(20, 0));
  setxy(50, 50);
  filled(green, circle(20));
  draw;

Note that the sequence of commands used by FILLED cannot be generated directly using a loop construct such as FOR, whereas with FILL it can. However, the command arguments to FILLED can be calls of procedures that can contain arbitrary code, e.g.

  procedure shape;
     for i := 1 : 4 do << forward 80; arc2(-90, 40) >>;

  clearscreen; penup;
  setxy(40, 80); setheading(-90);
  filled(false, shape());
  draw;

Label command
     LABEL text

takes a printable item or list of printable items as input and prints it on the graphics window with the top left-hand corner of the label at the turtle’s position. The items in a list are concatenated with no additional spacing. Beware that long labels will just fall off the edge of the graphics window. Multi-line labels can be produced by including newline characters encoded as \n within the text, e.g. "This is a\nmulti-line label". (The newline is recognised by Gnuplot, not by REDUCE.)

Setlabelfont command
     SETLABELFONT face
     SETLABELFONT size
     SETLABELFONT(face, size)
     SETLABELFONT {face, size}
     SETLABELFONT false

sets the face and/or size of the label font. If the face is specified then it should be the only or first input and must be an identifier or string, e.g. "Arial". If the size is specified then it should be the only or second input and must be a positive integer. If only one of the face and size is set then the other reverts to the default, not the previous value set. Alternatively, the single input can be a list of the form {face, size}, or false to revert to the default. The inputs must specify a font in a way that is accepted by Gnuplot but the details of font setting depend on the Gnuplot terminal in use. The defaults for the wxt terminal are face Sans and size 10. For the canvas terminal (and hence on Web REDUCE) setting the label font face is ignored.

Setlabelcolor command
     SETLABELCOLOR colour

sets the label foreground colour; see Colours.

18.3.11 Turtle and Window Queries

Shownp query
     SHOWNP

returns TRUE if the turtle is shown (visible), FALSE if the turtle is hidden. See SHOWTURTLE and HIDETURTLE.

Note that generally in LogoTurtle TRUE/FALSE values returned by query commands can be used to facilitate programming LogoTurtle by writing code such as the following:

     if shownp = true then ...

Windowsize query
     WINDOWSIZE

returns the current size of the graphics window as a list of the form \(\{x_{max},y_{max}\}\).

Turtlemode query
     TURTLEMODE

returns the word WRAP, FENCE, WINDOW or FALSE depending on the current turtle mode.

Labelfont query
     LABELFONT

returns a list of the current label font face and size if both are set, or whichever of the face or size is set, or false indicating that no label font information is set. Unset font information reverts to the Gnuplot default.

Labelcolor query
     LABELCOLOR

returns the current label foreground colour; see Colours.

18.3.12 Pen and Background Control

The turtle carries a pen that can draw pictures. At any time the pen can be UP (in which case moving the turtle does not change what’s on the graphics screen) or DOWN (in which case the turtle leaves a trace). Initially, the pen is UP.

Pendown command
     PENDOWN

sets the pen’s position to DOWN, i.e. lowers it so that the turtle draws when it moves.

Penup command
     PENUP

sets the pen’s position to UP, i.e. raises it so that the turtle moves without drawing.

Setpencolor command
     SETPENCOLOR colour

sets the pen colour; see Colours.

Setpalette command
     SETPALETTE(colournumber, colour)

sets the actual colour corresponding to a given colour number. The first argument must be an integer \(n\) such that \(8 \le n \le 15\). (LogoTurtle keeps the first 8 colours constant.) The second argument may be either an RGB list of three nonnegative numbers not greater than 100 specifying the percent saturation of red, green, and blue in the desired colour, or an identifier or string representing a colour in any way that is acceptable to Gnuplot, such as a colour name or hexadecimal number, e.g. red, "red" or "#FF0000". See Colours for further details.

Setpensize command
     SETPENSIZE size

sets the thickness of the pen. The input is a positive integer representing a multiple of the default thickness, or FALSE, meaning unspecified, which is equivalent to 1 but slightly more efficient.

Setbackground command
     SETBACKGROUND colour

sets the screen background colour; see Colours. Currently, however, this command requires the GNUTERM environment variable to be set to the Gnuplot terminal type. This is because in Gnuplot the background is a property of the terminal, so the terminal type is required as part of the command to set the background. Unless you already specify the appropriate Gnuplot terminal type, you can find it by running Gnuplot interactively, when it will report something like

     Terminal type set to ’wxt’

In this case, the correct value to assign to the GNUTERM environment variable would be wxt (without any quotes).

18.3.13 Pen and Background Queries

Pendownp query
     PENDOWNP

returns the identifier TRUE if the pen is down, FALSE if it’s up.

Pencolor query
     PENCOLOR

returns the pen colour; see Colours.

Palette query
     PALETTE colournumber

returns the colour associated with the given number; see Colours. Colournumber must be a nonnegative integer not greater than 15.

Pensize query
     PENSIZE

returns a positive integer specifying the thickness of the pen as a multiple of the default thickness, or false, meaning unspecified, which is equivalent to 1 but slightly more efficient.

Background query
     BACKGROUND

returns the graphics background colour; see Colours.

18.3.14 Saving and Loading Pictures

Savepict command
     SAVEPICT identifier

saves the current plot and labels to internal storage under the specified identifier without changing them. The saved data can be restored as the current plot and labels using LOADPICT.

Loadpict command
     LOADPICT(identifiers)

retrieves the plots and labels saved under the specified identifiers, which must have been saved by SAVEPICT commands, merges them in the order specified, and makes the result current. (The order is only significant in that it determines the colour of each plot if it is set automatically by Gnuplot, and if plots or labels overlap then later plots and labels overlay earlier ones and so hide them.) The previous current plot and labels are lost if not saved using SAVEPICT.


Hosted by Download REDUCE Powered by MathJax