Esempio n. 1
0
 public MainForm()
 {
     InitializeComponent();
     mandelProps = new MandelProps(this, _mandelbrotWindow);
     dials = new Dials(10);
     dials.Show();
     props = new PropsDialog(this);
     props.loadFields(mandelProps);
     props.Show();
     juliaForm = new JuliaForm();
     //juliaForm.Size = new System.Drawing.Size(512, 512);
     juliaForm.pictureBox1.Size = new System.Drawing.Size(512, 512);
     juliaForm.Show();
 }
        public void loadFields(MandelProps mandelProps)
        {
            this.mandelProps = mandelProps;
            textBox1.Text = "" + mandelProps.max_iter;
            planeBox.Text = "" + mandelProps.plane;
            depthBox.Text = "" + mandelProps.depth;
            tolerance.Text = "" + mandelProps.tol;
            scaleCmapBox.Checked = mandelProps.scaleCmap;
            juliaTextBoxX.Text = "" + mandelProps.juliax;
            juliaTextBoxY.Text = "" + mandelProps.juliay;

            int index = comboBox1.FindString(mandelProps.algorithm);
            comboBox1.SelectedIndex = index;
            index = comboBox2.FindString(mandelProps.cmap);
            comboBox2.SelectedIndex = index;
            windowLabel.Text = "w/h/center: " + mandelProps.mandelbrotWindow.Width + " " + mandelProps.mandelbrotWindow.Height
                + mandelProps.mandelbrotWindow.CenterX + " " + mandelProps.mandelbrotWindow.CenterY;
        }
        /// <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 static unsafe Bitmap Create(MandelProps mandelProps, 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.
            int maxIterations = mandelProps.max_iter;
            _paletteColors = Palettes.CreatePaletteColors(mandelProps.cmap);

            // 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 right coordinate
            double right = 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
            try
            {
                // Parallel implementation
                Evaluator evaluator = Evaluators.evaluatorFactory(mandelProps);
                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++)
                            {
                                double initialX = col * colToXTranslation + right;
                                byte iteration = (byte) evaluator.eval(initialX, initialY);
                                *currentPixel =  iteration;
                            }
                        }
                    });
                }
                // Sequential implementation
                else
                {
                    for (int row = 0; row < imageHeight; row++)
                    {
                        // if (cancellationToken.IsCancellationRequested) break;
                        cancellationToken.ThrowIfCancellationRequested();

                        double initialY = row * rowToYTranslation + top;
                        fixed (byte* ptr = data)
                        {
                            byte* currentPixel = &ptr[row * imageWidth];
                            for (int col = 0; col < imageWidth; col++, currentPixel++)
                            {
                                double initialX = col * colToXTranslation + right;
                                byte iteration = (byte) evaluator.eval(initialX, initialY);
                                *currentPixel = iteration;
                            }
                        }
                    };
                }
            }
            catch (Exception)
            {
            }

            // 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;
                }
            }
        }
 public Frac375MultiEvaluator(MandelProps props)
 {
     this.max = props.max_iter;
     this.bound = props.tol > 1 ? props.tol : 4;
     this.julia = props.julia;
     this.juliax = props.juliax;
     this.juliay = props.juliay;
 }
 public Frac25PlanesEvaluator(MandelProps mandelProps)
 {
     this.max = mandelProps.max_iter;
     this.planeProp = mandelProps.plane;
 }
 public Frac25Planes2Evaluator(MandelProps mandelProps)
 {
     this.max = mandelProps.max_iter;
     this.planeProp = mandelProps.plane;
     this.planeCount = mandelProps.depth;
 }
 public Frac25Evaluator(MandelProps props, int flag)
 {
     this.max = props.max_iter;
     this.flag = flag;
 }
 public Frac25DEvaluator(MandelProps props)
 {
     this.max = props.max_iter;
 }
 public Frac15MultiEvaluator(MandelProps props)
 {
     this.max = props.max_iter;
 }
 public Escape25Evaluator(MandelProps props)
 {
     this.max = props.max_iter;
     this.tol = props.tol;
     this.julia = props.julia;
     this.juliax = props.juliax;
     this.juliay = props.juliay;
 }
 public CyclesEvaluator(MandelProps props)
 {
     this.max = props.max_iter;
     this.tol = props.tol;
 }
 public static Evaluator evaluatorFactory(MandelProps mandelProps)
 {
     if (mandelProps.algorithm.Equals("Mandel"))
     {
         return new MandelEvaluator(mandelProps);
     }
     else if (mandelProps.algorithm.Equals("Frac25"))
     {
         return new Frac25Evaluator(mandelProps, 0);
     }
     else if (mandelProps.algorithm.Equals("Frac25a"))
     {
         return new Frac25Evaluator(mandelProps, 1);
     }
     else if (mandelProps.algorithm.Equals("Frac25c"))
     {
         return new Frac25CEvaluator(mandelProps);
     }
     else if (mandelProps.algorithm.Equals("Frac25d"))
     {
         return new Frac25DEvaluator(mandelProps);
     }
     else if (mandelProps.algorithm.Equals("Frac25Multi"))
     {
         return new Frac25MultiEvaluator(mandelProps);
     }
     else if (mandelProps.algorithm.Equals("Frac25Planes"))
     {
         return new Frac25PlanesEvaluator(mandelProps);
     }
     else if (mandelProps.algorithm.Equals("Cycles"))
     {
         return new CyclesEvaluator(mandelProps);
     }
      else if (mandelProps.algorithm.Equals("Cycles1"))
     {
         return new Cycles1Evaluator(mandelProps);
     }
     else if (mandelProps.algorithm.Equals("Cycles2"))
     {
         return new Cycles2Evaluator(mandelProps);
     }
     else if (mandelProps.algorithm.Equals("Zeros"))
     {
         return new ZerosEvaluator(mandelProps);
     }
     else if (mandelProps.algorithm.Equals("MandelZeros"))
     {
         return new MandelZerosEvaluator(mandelProps);
     }
     else if (mandelProps.algorithm.Equals("Frac15Multi"))
     {
         return new Frac15MultiEvaluator(mandelProps);
     }
     else if (mandelProps.algorithm.Equals("Frac25Planes2"))
     {
         return new Frac25Planes2Evaluator(mandelProps);
     }
     else if (mandelProps.algorithm.Equals("Escape25"))
     {
         return new Escape25Evaluator(mandelProps);
     }
     else if (mandelProps.algorithm.Equals("Frac375Multi"))
     {
         return new Frac375MultiEvaluator(mandelProps);
     }
     else
     {
         return new MandelEvaluator(mandelProps);
     }
 }
 public MandelZerosEvaluator(MandelProps props)
 {
     this.max = props.max_iter;
     this.tol = props.tol;
 }
 public MandelEvaluator(MandelProps props)
 {
     this.max = props.max_iter;
     this.julia = props.julia;
     this.juliax = props.juliax;
     this.juliay = props.juliay;
 }