Click here to Skip to main content
15,900,511 members
Articles / Desktop Programming / WPF
Tip/Trick

Generative Art I

Rate me:
Please Sign up or sign in to vote.
4.88/5 (6 votes)
29 Dec 2014CPOL2 min read 18.1K   349   16  
Turtle graphics: fundamental C# classes and methods for the artwork production in the area of generative art.

Introduction

Generative art refers to art that in whole or in part has been created with the use of an autonomous system (Wikipedia). This tip focuses on the technical part of that challenge and provides first basic C# classes and methods for developers/digital artists who want to produce these kind of artworks. Concerning the artistic aspect, you can find lots of material, e.g., here.

This tip shows how incredibly easy the technical part of the production of generative artworks can be.

Image 1

Basic Approach

For producing your first generative artwork, you have to accomplish the following tasks:

  • Create a canvas
  • Generate something on it
  • Sign the result
  • Save the artwork
C#
var canvas = new GenArtCanvas(width * zoom, height * zoom, backgroundColor);

canvas.Generate(zoom);
canvas.Sign(signature, margin);
canvas.Save(outputDirectory + title + format);

Create Canvas

The class GenArtCanvas inherits everything from Canvas:

C#
public class GenArtCanvas : Canvas
{
    public GenArtCanvas(double Width, double Height, Brush BackgroundColor)
        : base()
    {
        this.Width = Width;
        this.Height = Height;
        this.Background = BackgroundColor;
    }
}

The canvas is not displayed on the screen. It only uses the memory. You cannot observe the process of painting, but in the end, you will see the result in the stored file.

Generate Artwork

Now you choose an algorithm. In this case, it is a so-called turtle graphics. But this is the part where you should bring in your own creativity. You may adapt well-known algorithms (like this one) or create your own ones.

C#
public void Generate(int Zoom)
{
    this.Children.Add(Generator.TurtleWalk(2000, new Point(Width / 2, Height / 2), 
    new Vector(1, 0), Brushes.Black, 1 * Zoom, 20 * Zoom));
}

This generator works with a Polyline which is generated as random turtle walk and then simply added to the canvas.

C#
public class Generator
{
    private static Random RandomNumbers = new Random();

    public static Polyline TurtleWalk(int NumberOfSteps, Point Point, 
        Vector Vector, Brush Color, double Thickness, int Length)
    {
        var points = new PointCollection();
        var result = new Polyline()
        {
            Stroke = Color,
            StrokeThickness = Thickness,
            StrokeStartLineCap = PenLineCap.Round,
            StrokeEndLineCap = PenLineCap.Round,
            StrokeLineJoin = PenLineJoin.Round,
            Points = points
        };

        points.Add(Point);
        for (var i = 0; i < NumberOfSteps; i++)
        {
            Vector = Vector / Vector.Length * Length;
            Vector = RotatedVector(Vector, RandomNumbers.Next(0, 361));
            Point += Vector;
            points.Add(Point);
        }
        return result;
    }
    private static Vector RotatedVector(Vector OldVector, double Angle)
    {
        var matrix = Matrix.Identity;

        matrix.Rotate(Angle);
        return matrix.Transform(OldVector);
    }
}

It is up to you which algorithm you use and how much random action you implement here in your personal generator.

Sign Artwork

Of course, your artwork needs a signature:

C#
public void Sign(string Signature, double Margin)
{
    var signature = new Label()
        {
            Content = Signature,
            FontSize = (int)(Height * 1 / 100)
        };

    signature.Measure(new Size(Double.MaxValue, Double.MaxValue));
    this.Children.Add(signature);
    Canvas.SetLeft(signature, Width - Margin - signature.DesiredSize.Width);
    Canvas.SetTop(signature, Height - Margin - signature.DesiredSize.Height);
}

In this case, the size of the signature is set to 1 percent of the height of the canvas.

Save Artwork

Now the artwork is saved as an imagefile. The format depends on the extension of the OutputFileName.

C#
public void Save(string OutputFileName)
{
    BitmapEncoder encoder = null;
    RenderTargetBitmap renderBitmap;
    var size = new Size(Width, Height);

    Measure(size);
    Arrange(new Rect(size));
    renderBitmap = new RenderTargetBitmap((int)size.Width, 
        (int)size.Height, 96d, 96d, PixelFormats.Pbgra32);
    renderBitmap.Render(this);
    using (FileStream outStream = new FileStream(OutputFileName, FileMode.Create))
    {
        if (OutputFileName.ToUpper().EndsWith(".PNG"))
            encoder = new PngBitmapEncoder();
        if (OutputFileName.ToUpper().EndsWith(".JPG") || 
            OutputFileName.ToUpper().EndsWith(".JPEG"))
            encoder = new JpegBitmapEncoder();
        if (OutputFileName.ToUpper().EndsWith(".TIFF"))
            encoder = new TiffBitmapEncoder();
        if (encoder == null)
            encoder = new BmpBitmapEncoder();
        encoder.Frames.Add(BitmapFrame.Create(renderBitmap));
        encoder.Save(outStream);
    }
}

Finally, look at the produced file and enjoy the result!

Points of Interest

This code works with a zoom-factor. This is helpful for the fast trial of new algorithms (when set to a lower value) and the high-quality generation of the file for the print shop (when set to a higher value).

History

  • 29th December, 2014 - Published
  • 31st December, 2014 - Different output file formats added
  • 11th January, 2015 - Links to other articles in the series added

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
schoder.uk
United Kingdom United Kingdom
generative artist: schoder.uk

Comments and Discussions

 
-- There are no messages in this forum --