첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
------------------------------------------------------------------------------------------------------------------------------------------------------
728x90
728x170

■ 소용돌이 프랙탈(Vortex Fractal)을 그리는 방법을 보여준다.

TestProject.zip
다운로드

▶ Complex.cs

using System;

namespace TestProject
{
    /// <summary>
    /// 복소수
    /// </summary>
    public class Complex
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region Field

        /// <summary>
        /// 실수부
        /// </summary>
        public double Real = 0d;

        /// <summary>
        /// 허수부
        /// </summary>
        public double Imaginary = 0d;

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Property
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 크기 - Magnitude

        /// <summary>
        /// 크기
        /// </summary>
        public double Magnitude
        {
            get
            {
                return (Math.Sqrt(Real * Real + Imaginary * Imaginary));
            }
        }

        #endregion
        #region 제곱 크기 - MagnitudeSquared

        /// <summary>
        /// 제곱 크기
        /// </summary>
        public double MagnitudeSquared
        {
            get
            {
                return (Real * Real + Imaginary * Imaginary);
            }
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - Complex(real, imaginary)

        /// <summary>
        /// 생성자
        /// </summary>
        /// <param name="real">실수부</param>
        /// <param name="imaginary">허수부</param>
        public Complex(double real, double imaginary)
        {
            Real      = real;
            Imaginary = imaginary;
        }

        #endregion
        #region 생성자 - Complex(real)

        /// <summary>
        /// 생성자
        /// </summary>
        /// <param name="real">실수부</param>
        public Complex(double real)
        {
            Real      = real;
            Imaginary = 0d;
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 파싱하기 - Parse(source)

        /// <summary>
        /// 파싱하기
        /// </summary>
        /// <param name="source">소스 문자열</param>
        /// <returns>복소수</returns>
        public static Complex Parse(string source)
        {
            source = source.Replace(" ", "");
            source = source.ToLower().Replace("i", "");

            char[] characterArray = { '+', '-' };

            int position = source.IndexOfAny(characterArray);

            if(position == 0)
            {
                position = source.IndexOfAny(characterArray, 1);
            }

            double real      = double.Parse(source.Substring(0, position));
            double imaginary = double.Parse(source.Substring(position));

            return new Complex(real, imaginary);
        }

        #endregion

        #region + 연산자 재정의하기 - +(c)

        /// <summary>
        /// + 연산자 재정의하기
        /// </summary>
        /// <param name="c">복소수</param>
        /// <returns>복소수</returns>
        public static Complex operator +(Complex c)
        {
            return new Complex(c.Real, c.Imaginary);
        }

        #endregion
        #region - 연산자 재정의하기 - -(c)

        /// <summary>
        /// - 연산자 재정의하기
        /// </summary>
        /// <param name="c">복소수</param>
        /// <returns>복소수</returns>
        public static Complex operator -(Complex c)
        {
            return new Complex(-c.Real, -c.Imaginary);
        }

        #endregion

        #region + 연산자 재정의하기 - +(c1, c2)

        /// <summary>
        /// + 연산자 재정의하기
        /// </summary>
        /// <param name="c1">복소수 1</param>
        /// <param name="c2">복소수 2</param>
        /// <returns>복소수</returns>
        public static Complex operator +(Complex c1, Complex c2)
        {
            return new Complex(c1.Real + c2.Real, c1.Imaginary + c2.Imaginary);
        }

        #endregion
        #region - 연산자 재정의하기 - -(c1, c2)

        /// <summary>
        /// - 연산자 재정의하기
        /// </summary>
        /// <param name="c1">복소수 1</param>
        /// <param name="c2">복소수 2</param>
        /// <returns>복소수</returns>
        public static Complex operator -(Complex c1, Complex c2)
        {
            return new Complex(c1.Real - c2.Real, c1.Imaginary - c2.Imaginary);
        }

        #endregion
        #region * 연산자 재정의하기 - *(c1, c2)

        /// <summary>
        /// * 연산자 재정의하기
        /// </summary>
        /// <param name="c1">복소수 1</param>
        /// <param name="c2">복소수 2</param>
        /// <returns>복소수</returns>
        public static Complex operator *(Complex c1, Complex c2)
        {
            return new Complex
            (
                c1.Real * c2.Real - c1.Imaginary * c2.Imaginary,
                c1.Real * c2.Imaginary + c1.Imaginary * c2.Real
            );
        }

        #endregion
        #region / 연산자 재정의하기 - /(c1, c2)

        /// <summary>
        /// / 연산자 재정의하기
        /// </summary>
        /// <param name="c1">복소수 1</param>
        /// <param name="c2">복소수 2</param>
        /// <returns>복소수</returns>
        public static Complex operator /(Complex c1, Complex c2)
        {
            double denominator = c2.Real * c2.Real + c2.Imaginary * c2.Imaginary;

            double real      = (c1.Real * c2.Real + c1.Imaginary * c2.Imaginary) / denominator;
            double imaginary = (c1.Imaginary * c2.Real - c1.Real * c2.Imaginary) / denominator;

            return new Complex(real, imaginary);
        }

        #endregion

        #region < 연산자 재정의하기 - <(c1, c2)

        /// <summary>
        /// < 연산자 재정의하기
        /// </summary>
        /// <param name="c1">복소수 1</param>
        /// <param name="c2">복소수 2</param>
        /// <returns>처리 결과</returns>
        public static bool operator <(Complex c1, Complex c2)
        {
            return (c1.Magnitude < c2.Magnitude);
        }

        #endregion
        #region > 연산자 재정의하기 - >(c1, c2)

        /// <summary>
        /// > 연산자 재정의하기
        /// </summary>
        /// <param name="c1">복소수 1</param>
        /// <param name="c2">복소수 2</param>
        /// <returns>처리 결과</returns>
        public static bool operator >(Complex c1, Complex c2)
        {
            return (c1.Magnitude > c2.Magnitude);
        }

        #endregion
        #region <= 연산자 재정의하기 - <=(c1, c2)

        /// <summary>
        /// <= 연산자 재정의하기
        /// </summary>
        /// <param name="c1">복소수 1</param>
        /// <param name="c2">복소수 2</param>
        /// <returns>처리 결과</returns>
        public static bool operator <=(Complex c1, Complex c2)
        {
            return (c1.Magnitude <= c2.Magnitude);
        }

        #endregion
        #region >= 연산자 재정의하기 - >=(c1, c2)

        /// <summary>
        /// >= 연산자 재정의하기
        /// </summary>
        /// <param name="c1">복소수 1</param>
        /// <param name="c2">복소수 2</param>
        /// <returns>처리 결과</returns>
        public static bool operator >=(Complex c1, Complex c2)
        {
            return (c1.Magnitude >= c2.Magnitude);
        }

        #endregion
        #region == 연산자 재정의하기 - ==(c1, c2)

        /// <summary>
        /// == 연산자 재정의하기
        /// </summary>
        /// <param name="c1">복소수 1</param>
        /// <param name="c2">복소수 2</param>
        /// <returns>처리 결과</returns>
        public static bool operator ==(Complex c1, Complex c2)
        {
            return (c1.Real == c2.Real && c1.Imaginary == c2.Imaginary);
        }

        #endregion
        #region != 연산자 재정의하기 - !=(c1, c2)

        /// <summary>
        /// != 연산자 재정의하기
        /// </summary>
        /// <param name="c1">복소수 1</param>
        /// <param name="c2">복소수 2</param>
        /// <returns>처리 결과</returns>
        public static bool operator !=(Complex c1, Complex c2)
        {
            return !(c1 == c2);
        }

        #endregion

        #region 암시적 형변환 하기 - Complex(real)

        /// <summary>
        /// 암시적 형변환 하기
        /// </summary>
        /// <param name="real"></param>
        public static implicit operator Complex(double real)
        {
            return new Complex(real, 0);
        }

        #endregion
        #region 명시적 형변환 하기 - double(c)

        /// <summary>
        /// 명시적 형변환 하기
        /// </summary>
        /// <param name="c">복소수</param>
        public static explicit operator double(Complex c)
        {
            return c.Magnitude;
        }

        #endregion

        #region 동일 여부 구하기 - Equals(instance)

        /// <summary>
        /// 동일 여부 구하기
        /// </summary>
        /// <param name="instance">인스턴스</param>
        /// <returns>동일 여부</returns>
        public override bool Equals(object instance)
        {
            Complex c = instance as Complex;

            return this == c;
        }

        #endregion
        #region 해시 코드 구하기 - GetHashCode()

        /// <summary>
        /// 해시 코드 구하기
        /// </summary>
        /// <returns>해시 코드</returns>
        public override int GetHashCode()
        {
            return Real.GetHashCode() | Imaginary.GetHashCode();
        }

        #endregion

        #region 문자열 구하기 - ToString()

        /// <summary>
        /// 문자열 구하기
        /// </summary>
        /// <returns>문자열</returns>
        public override string ToString()
        {
            if(Imaginary == 0)
            {
                return string.Format("{0}", Real);
            }

            if(Real == 0)
            {
                return string.Format("{0}i", Imaginary);
            }

            if(Imaginary < 0)
            {
                return string.Format("{0} - {1}i", Real, Math.Abs(Imaginary));
            }

            return string.Format("{0} + {1}i", Real, Imaginary);
        }

        #endregion
        #region 문자열 구하기 - ToString(format)

        /// <summary>
        /// 문자열 구하기
        /// </summary>
        /// <param name="format">포맷</param>
        /// <returns>문자열</returns>
        public string ToString(string format)
        {
            if(Imaginary == 0)
            {
                return string.Format("{0:" + format + "}", Real);
            }

            if(Real == 0)
            {
                return string.Format("{0:" + format + "}i", Imaginary);
            }

            if(Imaginary < 0)
            {
                return string.Format("{0:" + format + "} - {1:" + format + "}i", Real, Math.Abs(Imaginary));
            }

            return string.Format("{0:" + format + "} + {1:" + format + "}i", Real, Imaginary);
        }

        #endregion
    }
}

 

▶ MainForm.cs

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms;

namespace TestProject
{
    /// <summary>
    /// 메인 폼
    /// </summary>
    public partial class MainForm : Form
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region Field

        /// <summary>
        /// 최대 반복 카운트
        /// </summary>
        public int MaximumIterationCount;

        /// <summary>
        /// 복소수
        /// </summary>
        public Complex Complex;

        /// <summary>
        /// 색상 리스트
        /// </summary>
        public List<Color> ColorList = new List<Color>();

        #endregion

        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// 최소 X
        /// </summary>
        private const double MINIMUM_X = -2;

        /// <summary>
        /// 최대 X
        /// </summary>
        private const double MAXIMUM_X = 2;

        /// <summary>
        /// 최소 Y
        /// </summary>
        private const double MINIMUM_Y = -2;

        /// <summary>
        /// 최소 Y
        /// </summary>
        private const double MAXIMUM_Y = 2;

        /// <summary>
        /// 상자 그리기 여부
        /// </summary>
        private bool isDrawingBox;

        /// <summary>
        /// 시작 X
        /// </summary>
        private double startX;

        /// <summary>
        /// 시작 Y
        /// </summary>
        private double startY;

        /// <summary>
        /// 현재 X
        /// </summary>
        private double currentX;

        /// <summary>
        /// 현재 Y
        /// </summary>
        private double currentY;

        /// <summary>
        /// 최소 X
        /// </summary>
        private double minimumX;

        /// <summary>
        /// 최대 X
        /// </summary>
        private double maximumX;

        /// <summary>
        /// 최소 Y
        /// </summary>
        private double minimumY;

        /// <summary>
        /// 최대 Y
        /// </summary>
        private double maximumY;

        /// <summary>
        /// 비트맵
        /// </summary>
        private Bitmap bitmap;

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - MainForm()

        /// <summary>
        /// 생성자
        /// </summary>
        public MainForm()
        {
            InitializeComponent();

            #region 이벤트를 설정한다.

            Load                            += Form_Load;
            this.saveAsMenuItem.Click       += saveAsMenuItem_Click;
            this.scaleX2MenuItem.Click      += scaleMenuItem_Click;
            this.scaleX4MenuItem.Click      += scaleMenuItem_Click;
            this.scaleX8MenuItem.Click      += scaleMenuItem_Click;
            this.fullScaleMenuItem.Click    += fullScaleMenuItem_Click;
            this.refreshMenuItem.Click      += refreshMenuItem_Click;
            this.setOptionMenuItem.Click    += setOptionMenuItem_Click;
            this.canvasPictureBox.MouseDown += canvasPictureBox_MouseDown;
            this.canvasPictureBox.MouseMove += canvasPictureBox_MouseMove;
            this.canvasPictureBox.MouseUp   += canvasPictureBox_MouseUp;

            #endregion
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Event
        //////////////////////////////////////////////////////////////////////////////// Private

        #region 폼 로드시 처리하기 - Form_Load(sender, e)

        /// <summary>
        /// 폼 로드시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void Form_Load(object sender, EventArgs e)
        {
            Show();

            Application.DoEvents();

            MaximumIterationCount = 64;

            Complex = new Complex(0.62, -0.55);

            ResetColorList();

            SettingForm form = new SettingForm();

            ColorList.Add(form.color40PictureBox.BackColor);
            ColorList.Add(form.color17PictureBox.BackColor);
            ColorList.Add(form.color18PictureBox.BackColor);
            ColorList.Add(form.color19PictureBox.BackColor);
            ColorList.Add(form.color20PictureBox.BackColor);
            ColorList.Add(form.color21PictureBox.BackColor);
            ColorList.Add(form.color22PictureBox.BackColor);
            ColorList.Add(form.color23PictureBox.BackColor);

            form.Close();

            this.fullScaleMenuItem.PerformClick();
        }

        #endregion
        #region 다른 이름으로 저장하기 메뉴 항목 클릭시 처리하기 - saveAsMenuItem_Click(sender, e)

        /// <summary>
        /// 다른 이름으로 저장하기 메뉴 항목 클릭시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void saveAsMenuItem_Click(object sender, EventArgs e)
        {
            if(this.saveFileDialog.ShowDialog() == DialogResult.OK)
            {
                this.bitmap.Save(this.saveFileDialog.FileName);

                string fileName      = this.saveFileDialog.FileName;
                string fileExtension = fileName.Substring(fileName.LastIndexOf("."));

                switch(fileExtension)
                {
                    case ".bmp"  : this.bitmap.Save(fileName, ImageFormat.Bmp ); break;
                    case ".jpg"  :
                    case ".jpeg" : this.bitmap.Save(fileName, ImageFormat.Jpeg); break;
                    case ".gif"  : this.bitmap.Save(fileName, ImageFormat.Gif ); break;
                    case ".png"  : this.bitmap.Save(fileName, ImageFormat.Png ); break;
                    case ".tif"  :
                    case ".tiff" : this.bitmap.Save(fileName, ImageFormat.Tiff); break;
                }
            }
        }

        #endregion
        #region 스케일 메뉴 항목 클릭시 처리하기 - scaleMenuItem_Click(sender, e)

        /// <summary>
        /// 스케일 메뉴 항목 클릭시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void scaleMenuItem_Click(object sender, EventArgs e)
        {
            MenuItem menuItem = sender as MenuItem;

            ScaleArea(int.Parse(menuItem.Tag.ToString()));
        }

        #endregion
        #region 전체 스케일 메뉴 항목 클릭시 처리하기 - fullScaleMenuItem_Click(sender, e)

        /// <summary>
        /// 전체 스케일 메뉴 항목 클릭시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void fullScaleMenuItem_Click(object sender, EventArgs e)
        {
            this.minimumX = MINIMUM_X;
            this.maximumX = MAXIMUM_X;
            this.minimumY = MINIMUM_Y;
            this.maximumY = MAXIMUM_Y;

            Cursor = Cursors.WaitCursor;

            Application.DoEvents();

            DrawVortexFractal();

            Cursor = Cursors.Default;

            this.canvasPictureBox.Cursor = Cursors.Cross;
        }

        #endregion
        #region 새로 고침 메뉴 항목 클릭시 처리하기 - refreshMenuItem_Click(sender, e)

        /// <summary>
        /// 새로 고침 메뉴 항목 클릭시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void refreshMenuItem_Click(object sender, EventArgs e)
        {
            ScaleArea(1);
        }

        #endregion
        #region 옵션 설정하기 메뉴 항목 클릭시 처리하기 - setOptionMenuItem_Click(sender, e)

        /// <summary>
        /// 옵션 설정하기 메뉴 항목 클릭시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void setOptionMenuItem_Click(object sender, EventArgs e)
        {
            SettingForm form = new SettingForm();

            form.StartPosition = FormStartPosition.CenterParent;

            form.Initialize(this);

            form.ShowDialog(this);
        }

        #endregion
        #region 캔버스 픽처 박스 마우스 DOWN 처리하기 - canvasPictureBox_MouseDown(sender, e)

        /// <summary>
        /// 캔버스 픽처 박스 마우스 DOWN 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void canvasPictureBox_MouseDown(object sender, MouseEventArgs e)
        {
            this.isDrawingBox = true;

            this.startX = e.X;
            this.startY = e.Y;

            this.currentX = e.X;
            this.currentY = e.Y;
        }

        #endregion
        #region 캔버스 픽처 박스 마우스 이동시 처리하기 - canvasPictureBox_MouseMove(sender, e)

        /// <summary>
        /// 캔버스 픽처 박스 마우스 이동시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void canvasPictureBox_MouseMove(object sender, MouseEventArgs e)
        {
            if(!this.isDrawingBox)
            {
                return;
            }

            this.currentX = e.X;
            this.currentY = e.Y;

            Bitmap   newBitmap         = new Bitmap(this.bitmap);
            Graphics newBitmapGraphics = Graphics.FromImage(newBitmap);

            newBitmapGraphics.DrawRectangle
            (
                Pens.Yellow,
                (int)(Math.Min(this.startX, this.currentX)),
                (int)(Math.Min(this.startY, this.currentY)),
                (int)(Math.Abs(this.startX - this.currentX)),
                (int)(Math.Abs(this.startY - this.currentY))
            );

            this.canvasPictureBox.Image = newBitmap;
        }

        #endregion
        #region 캔버스 픽처 박스 마우스 UP 처리하기 - canvasPictureBox_MouseUp(sender, e)

        /// <summary>
        /// 캔버스 픽처 박스 마우스 UP 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void canvasPictureBox_MouseUp(object sender, MouseEventArgs e)
        {
            if(!this.isDrawingBox)
            {
                return;
            }

            this.isDrawingBox = false;

            this.canvasPictureBox.Image = this.bitmap;

            this.currentX = e.X;
            this.currentY = e.Y;

            double x1 = Math.Min(this.startX, this.currentX);
            double x2 = Math.Max(this.startX, this.currentX);

            if(x1 == x2)
            {
                x2 = x1 + 1;
            }

            double y1 = Math.Min(this.startY, this.currentY);
            double y2 = Math.Max(this.startY, this.currentY);

            if(y1 == y2)
            {
                y2 = y1 + 1;
            }

            double factor = (this.maximumX - this.minimumX) / this.canvasPictureBox.ClientSize.Width;

            this.maximumX = this.minimumX + x2 * factor;
            this.minimumX = this.minimumX + x1 * factor;

            factor = (this.maximumY - this.minimumY) / this.canvasPictureBox.ClientSize.Height;

            this.maximumY = this.minimumY + y2 * factor;
            this.minimumY = this.minimumY + y1 * factor;

            Cursor = Cursors.WaitCursor;

            Application.DoEvents();

            DrawVortexFractal();

            Cursor = Cursors.Default;

            this.canvasPictureBox.Cursor = Cursors.Cross;
        }

        #endregion

        ////////////////////////////////////////////////////////////////////////////////////////// Function
        //////////////////////////////////////////////////////////////////////////////// Public

        #region 색상 리스트 리셋하기 - ResetColorList()

        /// <summary>
        /// 색상 리스트 리셋하기
        /// </summary>
        public void ResetColorList()
        {
            ColorList = new List<Color>();
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////// Private

        #region 화면비 조정하기 - AdjustAspect()

        /// <summary>
        /// 화면비 조정하기
        /// </summary>
        private void AdjustAspect()
        {
            double height;
            double width;
            double middle;

            double aspectDesired = (this.maximumY - this.minimumY) / (this.maximumX - this.minimumX);
            double canvasAspect  = this.canvasPictureBox.ClientSize.Height / (double)this.canvasPictureBox.ClientSize.Width;

            if(aspectDesired > canvasAspect)
            {
                width  = (this.maximumY - this.minimumY) / canvasAspect;
                middle = (this.minimumX + this.maximumX) / 2;

                this.minimumX = middle - width / 2;
                this.maximumX = middle + width / 2;
            }
            else
            {
                height = (this.maximumX - this.minimumX) * canvasAspect;
                middle = (this.minimumY + this.maximumY) / 2;

                this.minimumY = middle - height / 2;
                this.maximumY = middle + height / 2;
            }
        }

        #endregion
        #region 소용돌이 프랙탈 그리기 - DrawVortexFractal()

        /// <summary>
        /// 소용돌이 프랙탈 그리기
        /// </summary>
        private void DrawVortexFractal()
        {
            const int MAXIMUM_MAGNITUDE_SQUARED = 8;

            this.bitmap = new Bitmap
            (
                this.canvasPictureBox.ClientSize.Width,
                this.canvasPictureBox.ClientSize.Height
            );

            Graphics graphics = Graphics.FromImage(this.bitmap);

            graphics.Clear(this.canvasPictureBox.BackColor);

            this.canvasPictureBox.Image = this.bitmap;

            Application.DoEvents();

            AdjustAspect();

            int width  = this.canvasPictureBox.ClientRectangle.Width;
            int height = this.canvasPictureBox.ClientRectangle.Height;

            double real      = (this.maximumX - this.minimumX) / (width  - 1);
            double imaginary = (this.maximumY - this.minimumY) / (height - 1);

            int colorCount = ColorList.Count;

            double zReal = this.minimumX;

            for(int x = 0; x < width; x++)
            {
                double zImaginary = this.minimumY;

                for(int y = 0; y < height; y++)
                {
                    Complex z       = new Complex(zReal, zImaginary);
                    Complex zMinus1 = new Complex(zReal, zImaginary);

                    int colorValue = 1;

                    while((colorValue < MaximumIterationCount) && (z.MagnitudeSquared < MAXIMUM_MAGNITUDE_SQUARED))
                    {
                        Complex zPlus1 = z * z + Complex.Real + Complex.Imaginary * zMinus1;

                        zMinus1 = z;

                        z = zPlus1;

                        colorValue++;
                    }

                    this.bitmap.SetPixel(x, y, ColorList[colorValue % colorCount]);

                    zImaginary += imaginary;
                }

                zReal += real;

                if(x % 10 == 0)
                {
                    this.canvasPictureBox.Refresh();
                }
            }

            Text = string.Format
            (
                "소용돌이 프랙탈(Vortex Fractal) 그리기 : Vortex ({0}, {1}) - ({2}, {3})",
                this.minimumX.ToString("0.000000"),
                this.minimumY.ToString("0.000000"),
                this.maximumX.ToString("0.000000"),
                this.maximumY.ToString("0.000000")
            );
        }

        #endregion
        #region 영역 스케일 처리하기 - ScaleArea(scaleFactor)

        /// <summary>
        /// 영역 스케일 처리하기
        /// </summary>
        /// <param name="scaleFactor">스케일 팩터</param>
        private void ScaleArea(int scaleFactor)
        {
            double size = scaleFactor * (this.maximumX - this.minimumX);

            if(size > 3.2)
            {
                this.fullScaleMenuItem.PerformClick();

                return;
            }

            double middle = (this.minimumX + this.maximumX) / 2;

            this.minimumX = middle - size / 2;
            this.maximumX = middle + size / 2;

            size = scaleFactor * (this.maximumY - this.minimumY);

            if(size > 2.4)
            {
                this.fullScaleMenuItem.PerformClick();

                return;
            }

            middle = (this.minimumY + this.maximumY) / 2;

            this.minimumY = middle - size / 2;
            this.maximumY = middle + size / 2;

            Cursor = Cursors.WaitCursor;

            Application.DoEvents();

            DrawVortexFractal();

            Cursor = Cursors.Default;

            this.canvasPictureBox.Cursor = Cursors.Cross;
        }

        #endregion
    }
}
728x90
그리드형(광고전용)
Posted by icodebroker
,