Turtle Graphics using C#
In this example code, I show a minimal implementation of Turtle Graphics, using
C#.
Last changed: Feb 24, 2002
Download the sample code: TurtleGraphics.zip
As I started to read the book Fractal Horizons by Clifford A. Pickover, I thought it would
be a good idea to implement the code samples from the book. The first samples I
came across where written using Turtle Graphics commands. I remembered that the
book Turtle Geometry by Harold Abelson and Andrea diSessa, had
some code in the back to implement Turtle Graphics. This little bit of code was
written in Applesoft Basic. I was about to translate this to C#, but the Appendix
mentioned that more details could be found in the Chapter 3 - Vector Methods in Turtle
Geometry. In this chapter was some pseudo code written in the style of the
Logo programming language. I used the ideas in this code to create the Turtle class
presented below. The code which you
can download contains many of the algorithms form Turtle Geometry, which
I have implemented in C#.
The Turtle class is derived from System.Windows.Forms.UserControl.
Three variables are used to maintain the state of the turtle.
private Vector2D _P = new Vector2D( 0, 0 );
private Vector2D _H = new Vector2D( 0, 1 );
private bool _PenDown = true;
_P is the position vector, and _H is the heading vector. _PenDown,
keeps track of the state of the pen.
public PointF Position
{
get
{
return( new PointF( (float)_P.x, (float)_P.y ) );
}
set
{
_P.x = value.X; _P.y = value.Y;
}
}
The Position property returns or sets the Position vector using a PointF
structure.
public bool PenDown
{
get
{
return( _PenDown );
}
set
{
_PenDown = value;
}
}
Use the PenDown property to control or read the state of the pen.
public void Erase()
{
Graphics g = CreateGraphics();
Rectangle clientRect = this.ClientRectangle;
Brush bkgBrush = new SolidBrush( Color.White );
g.FillRectangle( bkgBrush, clientRect );
bkgBrush.Dispose();
g.Dispose();
_H.x = 0;
_H.y = 1;
_P.x = 0;
_P.y = 0;
}
The Erase function is used to wipe the canvas clean and initialize the Heading and
Position vectors. The heading vector is initialized to a unit vector pointing up,
and the position is moved to the canvas origin.
public void GoForward( double distance )
{
//Thread.Sleep( 100 );
Vector2D P = new Vector2D( _P + distance * _H );
if( _PenDown )
{
Graphics g = CreateGraphics();
Matrix myMatrix = new Matrix(1, 0, 0, -1, 0, 0);
g.Transform = myMatrix; g.TranslateTransform( 0, Height - 1, MatrixOrder.Append );
g.DrawLine( new Pen( new SolidBrush( Color.Blue ), 1 ),
new PointF( (float)_P.x, (float)_P.y ),
new PointF( (float)P.x, (float)P.y ) );
g.Dispose();
}
_P = P;
}
The GoForward function is used to update the position of the turtle. If the
pen is in the down state a line is drawn from the previous position to the current
position. A transformation matrix is use to mirror coordinates around the x-axis,
giving us up as the positive y direction. A Translate Transform is used to move
the origin to the bottom left corner.
There are a number of problems with this routine, put the purpose for this code
was to try out some Turtle Graphics routines. For example, the code is called for
every line which is drawn. A more efficient way, would be to store the lines in
a Path object and draw them all at once. Also there is no code here for saving the
drawing information, and performing a re-draw during an OnPaint. An example
of how this can be done, can be found in the code for the Drawing Canvas example.
public void GoBack( double distance )
{
GoForward( -1.0 * distance );
}
public void GoLeft( double angle )
{
_H = Rotate( _H, angle );
}
public void GoRight( double angle )
{
GoLeft( -1.0 * angle );
}
The GoForward, GoBack, GoLeft, & GoRight functions
are a minimal implementation of the Turtle Graphics language. This is all that is
needed, because everything else can easily be written in C#, as demonstrated in
the examples in the Art class.
private Vector2D Rotate( Vector2D V, double angle )
{
return( Math.Cos( angle * Math.PI / 180.0 )
* V + Math.Sin( angle * Math.PI / 180.0 )
* Perp( V ) );
}
private Vector2D Perp( Vector2D V )
{
return( new Vector2D( -1.0 * V.y, V.x ) );
}
The Rotate & Perp functions are use to translate turtle rotation
angles into changes in the Heading vector.
A Vector class was created to simplify working with 2D vectors.
public class Vector2D
{
public double x; public double y;
public Vector2D( double vx, double vy )
{
x = vx;
y = vy;
}
public Vector2D( Vector2D v )
{
x = v.x;
y = v.y;
}
public static Vector2D operator + ( Vector2D lhs, Vector2D rhs )
{
Vector2D result = new Vector2D( lhs );
result.x += rhs.x;
result.y += rhs.y;
return( result );
}
public static Vector2D operator * ( double lhs, Vector2D rhs )
{
Vector2D result = new Vector2D( rhs );
result.x *= lhs;
result.y *= lhs; return( result );
}
public static Vector2D operator * ( Vector2D lhs, double rhs )
{
Vector2D result = new Vector2D( lhs );
result.x *= rhs;
result.y *= rhs;
return( result );
}
}
To see the sample code in action, create a C# Windows application and add the downloaded
code to it. Click the entries in the list box to see the corresponding drawing on
the Turtle control on the right. Examine the code in the Art class to see the Turtle
graphics algorithms used to create the drawings.





wburris at telusplanet dot net |