Wednesday, December 1, 2010

Prime Art Generators

Go here to see how to generate a set of Primes.


This is a simple method that traverses each row in the image and puts a black pixel at every point that is a Prime number.
private Bitmap CreateNormalPrimeArt(HashSet<int> primes, int width, int height)
{
    Bitmap bmp = new Bitmap(width, height);
    using (Graphics gfx = Graphics.FromImage(bmp))
    {
        using (Brush brush = new SolidBrush(Color.FromArgb(25, 25, 76)))
        {
            gfx.FillRectangle(brush, new Rectangle(0, 0, width, height));
        }
    }
    for (int y = 0; y < height; y++)
    {
        for (int x = 0; x < width; x++)
        {
            if (primes.Contains((y * height) + x))
                bmp.SetPixel(x, y, Color.White);
        }
    }
    using (Graphics gfx = Graphics.FromImage(bmp))
    {
        using (Brush brush = new SolidBrush(Color.White))
        {
            gfx.DrawString("Prime Rows", new System.Drawing.Font("Calibri", 10), brush, new PointF(20, height - 20));
        }
    }
    return bmp;
}



The second is based on the Ulam Spiral.
private Bitmap CreateUlamSpiralPrimeArt(HashSet<int> primes, int width, int height)
{
    if (width != height)
    {
        if (width > height)
            width = height;
        else
            height = width;
    }
    if (width % 2 == 0)
    {
        width--;
        height--;
    }
    int index = 1;
    int sideLength = 2;
    int thisSide = 2;
    int turns = 0;
    Bitmap bmp = new Bitmap(width, height);
    using (Graphics gfx = Graphics.FromImage(bmp))
    {
        using (Brush brush = new SolidBrush(Color.FromArgb(25, 25, 76)))
        {
            gfx.FillRectangle(brush, new Rectangle(0, 0, width, height));
        }
    }
    // set p to center
    Point p = new Point(width / 2, height / 2);
    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            if (p.Y <= 5 || p.Y >= height - 5 || p.X <= 5 || p.X >= width - 5)
                break;
            if (primes.Contains(index))
                bmp.SetPixel(p.X, p.Y, Color.White);
            index++;
            thisSide--;
            int dir = turns % 4;
            if (thisSide == 0)
            {
                thisSide = sideLength;
                turns++;
                if (dir == 1 || dir == 3)
                    sideLength += 1;
            }
            if (dir == 0)
            {
                p.X = p.X + 1;
            }
            else if (dir == 1)
            {
                p.Y = p.Y - 1;
            }
            else if (dir == 2)
            {
                p.X = p.X - 1;
            }
            else if (dir == 3)
            {
                p.Y = p.Y + 1;
            }
        }
    }
    using (Graphics gfx = Graphics.FromImage(bmp))
    {
        using (Brush brush = new SolidBrush(Color.White))
        {
            gfx.DrawString("Ulam Spiral", new System.Drawing.Font("Calibri", 10), brush, new PointF(20, height - 20));
        }
    }
    return bmp;
}



Third method creates nice spirals based on the Prime distribution. Enjoy.
private Bitmap CreateDSCPrimeArt(HashSet<int> primes, int width, int height)
{
    int index = 1;
    Bitmap bmp = new Bitmap(width, height);
    using (Graphics gfx = Graphics.FromImage(bmp))
    {
        using (Brush brush = new SolidBrush(Color.FromArgb(25, 25, 76)))
        {
            gfx.FillRectangle(brush, new Rectangle(0, 0, width, height));
        }
    }
    // set p to center
    int max = primes.Max();
    Point p = new Point(width / 2, height / 2);
    for (int i = 0; i < height; i++)
    {
        for (int j = 0; j < width; j++)
        {
            if (primes.Contains(index))
            {
                // calculate location of the next pixel from the center of the image
                // distance to the center of the image is based on the square root of the prime
                PointF pixel = new Point() { X = p.X, Y = p.Y };
                pixel.X += (float)(Math.Sin(index) * Math.Sqrt(index));
                pixel.Y += (float)(Math.Cos(index) * Math.Sqrt(index));

                if (!(pixel.Y <= 5 || pixel.Y >= height - 5 || pixel.X <= 5 || pixel.X >= width - 5))
                {
                    bmp.SetPixel((int)pixel.X, (int)pixel.Y, Color.White);
                }
            }
            index++;


            if (index > max)
                break;
        }
    }

    using (Graphics gfx = Graphics.FromImage(bmp))
    {
        using (Brush brush = new SolidBrush(Color.White))
        {
            gfx.DrawString("Prime Spiral", new System.Drawing.Font("Calibri", 10), brush, new PointF(20, height - 20));
        }
    }
    return bmp;
}

Update 2017-01-30
Fixed broken pictures, changed code to a cleaner format without line numbering.


No comments:

Post a Comment