XAML Playground
about XAML and other Amenities

Draw your Paths with Logo Turtle Graphics

2012-02-20T22:58:55+01:00 by codeblock

Working on a presentation I'm preparing about Silverlight 5.0, I wrote a funny example to demonstrate the new "Vector Printing" feature. My purpose was to put together a bunch of lines to send to the printer, but I was unsatisfied by any result I created by hand.

So, all of a sudden, I remembered the beauty of some figures, I drawed long time ago (perhaps I was 15), using the Logo Turtle Graphics principles and decided to write some code to draw them again. The result is funny. Try yourself to move the sliders in the following application to see the figures.

The code behind the example is really simple. I wrote a basic Turtle class that is able to manage the position of the turtle. It exposes a basic set of methods that emulates the movements that are tipical of a Logo procedure. Forward, Backward, Left and Right and so on.

   1: public class Turtle
   2: {
   3:     // Collection of geometries to draw the figure
   4:     private GeometryGroup Geometries { get; set; }
   5:     // current angle of the turtle
   6:     public double Angle { get; private set; }
   7:     // current position of the turtle
   8:     public Point Position { get; private set; }
   9:     // position of the pen
  10:     public bool IsPenDown { get; private set; }
  11:  
  12:     /// <summary>
  13:     /// Inizializza una nuova istanza della classe <see cref="Turtle"/>.
  14:     /// </summary>
  15:     public Turtle(Path path)
  16:     {
  17:         this.Geometries = new GeometryGroup();
  18:         path.Data = this.Geometries;
  19:         this.Angle = 0.0;
  20:         this.Position = new Point(0, 0);
  21:         this.IsPenDown = true;
  22:     }
  23:  
  24:     // lift up the pen
  25:     public void PenUp()
  26:     {
  27:         this.IsPenDown = false;
  28:     }
  29:  
  30:     // lower the pen
  31:     public void PenDown()
  32:     {
  33:         this.IsPenDown = true;
  34:     }
  35:  
  36:     // move forward
  37:     public void Forward(double size)
  38:     {
  39:         this.Move(size);
  40:     }
  41:  
  42:     //  move backward
  43:     public void Backward(double size)
  44:     {
  45:         this.Move(-size);
  46:     }
  47:  
  48:     // rotate to the left
  49:     public void Left(double angle)
  50:     {
  51:         this.Angle += ToRadians(angle);
  52:     }
  53:  
  54:     // rotate to the right
  55:     public void Right(double angle)
  56:     {
  57:         this.Angle -= ToRadians(angle);
  58:     }
  59:  
  60:     // move the pen of the specified size
  61:     private void Move(double size)
  62:     {
  63:         Point past = this.Position;
  64:  
  65:         this.Position =
  66:             new Point(
  67:                 past.X + Math.Sin(this.Angle) * size,
  68:                 past.Y + Math.Cos(this.Angle) * size);
  69:  
  70:         if (IsPenDown)
  71:         {
  72:             this.Geometries.Children.Add(
  73:                 new LineGeometry
  74:                 {
  75:                     StartPoint = past,
  76:                     EndPoint = this.Position,
  77:                 });
  78:         }
  79:     }
  80:  
  81:     // convert degrees to radians
  82:     public double ToRadians(double angle)
  83:     {
  84:         return angle * Math.PI / 180.0;
  85:     }
  86: }

Then a short C# function does the rest and draws the figure on the basis of a simple mathematical algorithm. It simply repeat a poligon a number of times, rotating the origin point of a short amount of degrees. The sliders change the number of sides of the poligon and the amount of the rotation expressed in fraction of 360°.

   1: private void Draw(Path pathToDraw)
   2: {
   3:     int sides = (int)this.SidesSlider.Value;
   4:     double corner = 360 / (double)sides;
   5:     int repeat = (int)this.RepeatSlider.Value;
   6:     double angle = 360 / (double)repeat;
   7:  
   8:     Turtle turtle = new Turtle(pathToDraw);
   9:  
  10:     for (int j = 0; j < repeat; j++)
  11:     {
  12:         for (int i = 0; i < sides; i++)
  13:         {
  14:             turtle.Forward(50);
  15:             turtle.Left(corner);
  16:         }
  17:  
  18:         turtle.Right(angle);
  19:     }
  20: }

I'm always impressed by the beauty of the simple mathematical drawing. The prints I got from this example have been forwarded to my daughter and some hours after they are completely coloured and becomed a beautiful picture for the door of our refrigerator. I hope you like this funny Vector Printing example.

Categories:   TIPS
Actions:   E-mail | del.icio.us | Permalink | Comments (0) | Comment RSSRSS comment feed