예제 #1
0
        /**************************************************************************
         *
         ***************************************************************************/
        private void Zoom(Rectangle window)
        {
            // don't bother zooming if the size is too small.
            if (window.Height < 10 || window.Width < 10)
            {
                return;
            }

            // stretch zoom
            using (Bitmap bitmap = new Bitmap(myPictureBox.Width, myPictureBox.Height, PixelFormat.Format32bppPArgb))
                using (Graphics g = Graphics.FromImage((Image)bitmap))
                {
                    g.DrawImage(_canvas, myPictureBox.ClientRectangle, window, GraphicsUnit.Pixel);
                }
            myPictureBox.Invalidate(true);

            // HORRIBLE !!
            // Need to use async/await
            Application.DoEvents();

            // calculate new window and render
            aComplexNumber tlPoint = new aComplexNumber();
            aComplexNumber brPoint = new aComplexNumber();

            TransformCoord(window.X, window.Y, ref tlPoint);
            TransformCoord(window.Right, window.Bottom, ref brPoint);

            _complexWindow.MinX = tlPoint.Real;
            _complexWindow.MaxX = brPoint.Real;
            _complexWindow.MinY = brPoint.Imaginary;
            _complexWindow.MaxY = tlPoint.Imaginary;

            Render();
        }
예제 #2
0
        /**************************************************************************
         *  Test the given coordinate to see if it is inside the Mandelbrot set
         *
         *  Returns 0 if it is part of the set.
         *  If not, returns the number of tries reached.
         *
         ***************************************************************************/
        private int TestForMandelbrotSetAsync(int x, int y)
        {
            int            iterationsTaken = 0;
            aComplexNumber Z = new aComplexNumber();
            aComplexNumber C = new aComplexNumber();

            // Set initial value of Zn to 0+0i
            Z.Real      = 0;
            Z.Imaginary = 0;

            // get the imaginary coordinate that is represented by our current position
            TransformCoord(x, y, ref C);

            // To test for divergence, we perform an iterative loop of the form:
            // Zn+1 = Zn^2 + C
            //
            // If the magnitude of Z goes above 2, then it is within the Mandelbrot set.
            double ZrSq = Z.Real * Z.Real;
            double ZiSq = Z.Imaginary * Z.Imaginary;

            for (iterationsTaken = 0; iterationsTaken < _complexWindow.MaxThreshold; iterationsTaken++)
            {
                /***********************************
                *  aComplexNumber Zn = Z.Squared() + C;
                *  if (Zn.IsDivergent())
                *   break;
                *  Z = Zn;
                ***********************************/

                // optimisation of above code
                // Test for divergence
                // No need to do the square root for a little perf. increase.
                if (ZrSq + ZiSq > 4.0)
                {
                    break;
                }

                Z.Imaginary  = Z.Real * Z.Imaginary;
                Z.Imaginary += Z.Imaginary;
                Z.Imaginary += C.Imaginary;

                Z.Real = ZrSq - ZiSq + C.Real;

                ZrSq = Z.Real * Z.Real;
                ZiSq = Z.Imaginary * Z.Imaginary;
            }

            if (iterationsTaken >= _complexWindow.MaxThreshold)
            {
                return(0);
            }

            // Not inside the Mandelbrot set
            return(iterationsTaken);
        }
예제 #3
0
        /**************************************************************************
         * Handler for the mouse button up event
         *
         * Use this event to update our image if we have been zooming or panning.
         ***************************************************************************/
        private void PictureBox_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                if (_isZooming)
                {
                    _isZooming = false;
                    Point endZoomPoint = new Point(e.X, e.Y);

                    // Call zoom function
                    Rectangle window = new Rectangle(
                        Math.Min(_startPoint.X, endZoomPoint.X),
                        Math.Min(_startPoint.Y, endZoomPoint.Y),
                        Math.Abs(_startPoint.X - endZoomPoint.X),
                        Math.Abs(_startPoint.Y - endZoomPoint.Y));

                    Zoom(window);
                }
                else if (_isPanning)
                {
                    _isPanning = false;
                    Point endPoint = new Point(e.X, e.Y);

                    _panninggrapics?.Dispose();
                    _panninggrapics = null;

                    // calculate distance moved on each axis.
                    aComplexNumber start = new aComplexNumber();
                    aComplexNumber end   = new aComplexNumber();

                    TransformCoord(_startPoint.X, _startPoint.Y, ref start);
                    TransformCoord(endPoint.X, endPoint.Y, ref end);

                    double deltaX = end.Real - start.Real;
                    double deltaY = end.Imaginary - start.Imaginary;

                    _complexWindow.MinX -= deltaX;
                    _complexWindow.MaxX -= deltaX;
                    _complexWindow.MinY -= deltaY;
                    _complexWindow.MaxY -= deltaY;

                    using (Bitmap tempbitmap = (Bitmap)_canvas.Clone())
                        using (Graphics g = Graphics.FromImage(_canvas))
                        {
                            GraphicsUnit gu = GraphicsUnit.Pixel;
                            g.FillRectangle(new SolidBrush(Color.SeaGreen), _canvas.GetBounds(ref gu));
                            g.DrawImage(tempbitmap, (endPoint.X - _startPoint.X), (endPoint.Y - _startPoint.Y));
                        }

                    Render();
                }
            }
        }
예제 #4
0
        /**************************************************************************
         * Handles the mouse movement event
         *
         * This handler has a few tasks.
         * . Handles image movement, if we are panning
         * . Updates zoom coordinates, if we are zooming in.
         *
         ***************************************************************************/
        private void PictureBox_MouseMove(object sender, MouseEventArgs e)
        {
            // If we are still rendering our image, then do no continue
            if (_isRendering)
            {
                return;
            }

            if (_isZooming)
            {
                Point endZoomPoint = new Point(e.X, e.Y);

                _ZoomWindow = new Rectangle(
                    Math.Min(_startPoint.X, endZoomPoint.X),
                    Math.Min(_startPoint.Y, endZoomPoint.Y),
                    Math.Abs(_startPoint.X - endZoomPoint.X),
                    Math.Abs(_startPoint.Y - endZoomPoint.Y));

                myPictureBox.Invalidate();
                return;
            }

            // we are panning our image, so move to the new position
            if (_isPanning)
            {
                Point endPoint = new Point(e.X, e.Y);

                _panninggrapics.FillRectangle(new SolidBrush(Color.DimGray), myPictureBox.ClientRectangle);
                _panninggrapics.DrawImage(_canvas, (endPoint.X - _startPoint.X), (endPoint.Y - _startPoint.Y));
                return;
            }

            aComplexNumber C = new aComplexNumber();

            TransformCoord(e.X, e.Y, ref C);

            // output the coordinates to the screen
            statusLabel.Text = $"x: {C.Real:0.####} y:{C.Imaginary:0.####}";
        }
 public aComplexNumber(aComplexNumber c)
 {
     _real      = c._real;
     _imaginary = c._imaginary;
 }
예제 #6
0
 /**************************************************************************
  * Maps the given screen position to the complex plane being rendered
  ***************************************************************************/
 private void TransformCoord(int x, int y, ref aComplexNumber complexPoint)
 {
     complexPoint.Real      = ((x * (_complexWindow.MaxX - _complexWindow.MinX)) / myPictureBox.Width) + _complexWindow.MinX;
     complexPoint.Imaginary = (((myPictureBox.Height - y) * (_complexWindow.MaxY - _complexWindow.MinY)) / myPictureBox.Height) + _complexWindow.MinY;
 }
예제 #7
0
 /**************************************************************************
  * Transform the given screen coordinate to the represented complex number
  ***************************************************************************/
 private void TransformCoord(Point screenPoint, ref aComplexNumber complexPoint)
 {
     TransformCoord(screenPoint.X, screenPoint.Y, ref complexPoint);
 }