Example #1
0
        protected override void OnKeyDown(KeyEventArgs e)
        {
            base.OnKeyDown(e);
            if (e.KeyCode == Keys.R)
            {
                _mandelbrotWindow = MandelbrotPosition.Default;

                using (MainForm tempForm = new MainForm())
                {
                    double xFactor = Size.Width / (double)tempForm.Width, yFactor = Size.Height / (double)tempForm.Height;
                    _mandelbrotWindow.Width  *= xFactor;
                    _mandelbrotWindow.Height *= yFactor;
                }

                UpdateImageAsync();
            }
            else if (e.KeyCode == Keys.S)
            {
                _parallelRendering = false;
                UpdateImageAsync();
            }
            else if (e.KeyCode == Keys.P)
            {
                _parallelRendering = true;
                UpdateImageAsync();
            }
        }
Example #2
0
        protected override void OnKeyDown(KeyEventArgs e)
        {
            base.OnKeyDown(e);
            if (e.KeyCode == Keys.R)
            {
                _mandelbrotWindow = MandelbrotPosition.Default;

                using (MainForm tempForm = new MainForm())
                {
                    double xFactor = Size.Width / (double)tempForm.Width, yFactor = Size.Height / (double)tempForm.Height;
                    _mandelbrotWindow.Width *= xFactor;
                    _mandelbrotWindow.Height *= yFactor;
                }

                UpdateImageAsync();
            }
            else if (e.KeyCode == Keys.S)
            {
                _parallelRendering = false;
                UpdateImageAsync();
            }
            else if (e.KeyCode == Keys.P)
            {
                _parallelRendering = true;
                UpdateImageAsync();
            }
        }
        /// <summary>Renders a mandelbrot fractal.</summary>
        /// <param name="position">The MandelbrotPosition representing the fractal boundaries to be rendered.</param>
        /// <param name="imageWidth">The width in pixels of the image to create.</param>
        /// <param name="imageHeight">The height in pixels of the image to create.</param>
        /// <param name="parallelRendering">Whether to render the image in parallel.</param>
        /// <returns>The rendered Bitmap.</returns>
        public unsafe static Bitmap Create(MandelbrotPosition position, int imageWidth, int imageHeight, CancellationToken cancellationToken, bool parallelRendering)
        {
            // The maximum number of iterations to perform for each pixel.  Higher number means better
            // quality but also slower.
            const int maxIterations = 256;

            // In order to use the Bitmap ctor that accepts a stride, the stride must be divisible by four.
            // We're using imageWidth as the stride, so shift it to be divisible by 4 as necessary.
            if (imageWidth % 4 != 0)
            {
                imageWidth = (imageWidth / 4) * 4;
            }

            // Based on the fractal bounds, determine its upper left coordinate
            double left = position.CenterX - (position.Width / 2);
            double top  = position.CenterY - (position.Height / 2);

            // Get the factors that can be multiplied by row and col to arrive at specific x and y values
            double colToXTranslation = position.Width / (double)imageWidth;
            double rowToYTranslation = position.Height / (double)imageHeight;

            // Create the byte array that will store the rendered color indices
            int pixels = imageWidth * imageHeight;

            byte[] data = new byte[pixels];             // initialized to all 0s, which equates to all black based on the default palette

            // Generate the fractal using the mandelbrot formula : z = z^2 + c

            // Parallel implementation
            if (parallelRendering)
            {
                var options = new ParallelOptions {
                    CancellationToken = cancellationToken
                };
                Parallel.For(0, imageHeight, options, row =>
                {
                    double initialY = row * rowToYTranslation + top;
                    fixed(byte *ptr = data)
                    {
                        byte *currentPixel = &ptr[row * imageWidth];
                        for (int col = 0; col < imageWidth; col++, currentPixel++)
                        {
                            Complex c = new Complex(col * colToXTranslation + left, initialY);
                            Complex z = c;
                            for (int iteration = 0; iteration < maxIterations; iteration++)
                            {
                                if (z.Magnitude > 4)
                                {
                                    *currentPixel = (byte)iteration;
                                    break;
                                }
                                z = (z * z) + c;
                            }
                        }
                    }
                });
            }
            // Sequential implementation
            else
            {
                for (int row = 0; row < imageHeight; row++)
                {
                    //cancellationToken.ThrowIfCancellationRequested();
                    double initialY = row * rowToYTranslation + top;
                    fixed(byte *ptr = data)
                    {
                        byte *currentPixel = &ptr[row * imageWidth];

                        for (int col = 0; col < imageWidth; col++, currentPixel++)
                        {
                            Complex c = new Complex(col * colToXTranslation + left, initialY);
                            Complex z = c;
                            for (int iteration = 0; iteration < maxIterations; iteration++)
                            {
                                if (z.Magnitude > 4)
                                {
                                    *currentPixel = (byte)iteration;
                                    break;
                                }
                                z = (z * z) + c;
                            }
                        }
                    }
                }
                ;
            }

            // Produce a Bitmap from the byte array of color indices and return it
            fixed(byte *ptr = data)
            {
                using (Bitmap tempBitmap = new Bitmap(imageWidth, imageHeight, imageWidth, PixelFormat.Format8bppIndexed, (IntPtr)ptr)) {
                    Bitmap bitmap = tempBitmap.Clone(new Rectangle(0, 0, tempBitmap.Width, tempBitmap.Height), PixelFormat.Format8bppIndexed);
                    UpdatePalette(bitmap);
                    return(bitmap);
                }
            }
        }
Example #4
0
        /// <summary>Renders a mandelbrot fractal.</summary>
        /// <param name="position">The MandelbrotPosition representing the fractal boundaries to be rendered.</param>
        /// <param name="imageWidth">The width in pixels of the image to create.</param>
        /// <param name="imageHeight">The height in pixels of the image to create.</param>
        /// <param name="parallelRendering">Whether to render the image in parallel.</param>
        /// <returns>The rendered Bitmap.</returns>
        public unsafe static Bitmap Create(MandelbrotPosition position, int imageWidth, int imageHeight, CancellationToken cancellationToken, bool parallelRendering)
        {
            // The maximum number of iterations to perform for each pixel.  Higher number means better
            // quality but also slower.
            const int maxIterations = 256;

            // In order to use the Bitmap ctor that accepts a stride, the stride must be divisible by four.
            // We're using imageWidth as the stride, so shift it to be divisible by 4 as necessary.
            if (imageWidth % 4 != 0) imageWidth = (imageWidth / 4) * 4;

            // Based on the fractal bounds, determine its upper left coordinate
            double left = position.CenterX - (position.Width / 2);
            double top = position.CenterY - (position.Height / 2);

            // Get the factors that can be multiplied by row and col to arrive at specific x and y values
            double colToXTranslation = position.Width / (double)imageWidth;
            double rowToYTranslation = position.Height / (double)imageHeight;

            // Create the byte array that will store the rendered color indices
            int pixels = imageWidth * imageHeight;
            byte[] data = new byte[pixels]; // initialized to all 0s, which equates to all black based on the default palette

            // Generate the fractal using the mandelbrot formula : z = z^2 + c

            // Parallel implementation
            if (parallelRendering)
            {
                var options = new ParallelOptions { CancellationToken = cancellationToken };
                Parallel.For(0, imageHeight, options, row =>
                {
                    double initialY = row * rowToYTranslation + top;
                    fixed (byte* ptr = data)
                    {
                        byte* currentPixel = &ptr[row * imageWidth];
                        for (int col = 0; col < imageWidth; col++, currentPixel++)
                        {
                            Complex c = new Complex(col * colToXTranslation + left, initialY);
                            Complex z = c;
                            for (int iteration = 0; iteration < maxIterations; iteration++)
                            {
                                if (z.Magnitude > 4)
                                {
                                    *currentPixel = (byte)iteration;
                                    break;
                                }
                                z = (z * z) + c;
                            }
                        }
                    }
                });
            }
                // Sequential implementation
            else
            {
                for (int row = 0; row < imageHeight; row++)
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    double initialY = row * rowToYTranslation + top;
                    fixed (byte* ptr = data)
                    {
                        byte* currentPixel = &ptr[row * imageWidth];
                        for (int col = 0; col < imageWidth; col++, currentPixel++)
                        {
                            Complex c = new Complex(col * colToXTranslation + left, initialY);
                            Complex z = c;
                            for (int iteration = 0; iteration < maxIterations; iteration++)
                            {
                                if (z.Magnitude > 4)
                                {
                                    *currentPixel = (byte)iteration;
                                    break;
                                }
                                z = (z * z) + c;
                            }
                        }
                    }
                };
            }

            // Produce a Bitmap from the byte array of color indices and return it
            fixed (byte* ptr = data)
            {
                using (Bitmap tempBitmap = new Bitmap(imageWidth, imageHeight, imageWidth, PixelFormat.Format8bppIndexed, (IntPtr)ptr))
                {
                    Bitmap bitmap = tempBitmap.Clone(new Rectangle(0, 0, tempBitmap.Width, tempBitmap.Height), PixelFormat.Format8bppIndexed);
                    UpdatePalette(bitmap);
                    return bitmap;
                }
            }
        }