첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
유용한 소스 코드가 있으면 icodebroker@naver.com으로 보내주시면 감사합니다.
블로그 자료는 자유롭게 사용하세요.

728x90
반응형

■ 피코버 별난 끌개 프랙탈(Pickover Strange Attractor Fractal) 그리기

------------------------------------------------------------------------------------------------------------------------


TestProject.zip


MainForm.cs

 

 

using System;

using System.Drawing;

using System.Windows.Forms;

 

namespace TestProject

{

    /// <summary>

    /// 메인 폼

    /// </summary>

    public partial class MainForm : Form

    {

        //////////////////////////////////////////////////////////////////////////////////////////////////// Field

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

 

        #region Field

 

        /// <summary>

        /// 플레인

        /// </summary>

        private Plane plane;

 

        /// <summary>

        /// 비트맵

        /// </summary>

        private Bitmap bitmap;

 

        /// <summary>

        /// 그래픽스

        /// </summary>

        private Graphics graphics;

 

        /// <summary>

        /// 너비

        /// </summary>

        private int width;

        

        /// <summary>

        /// 높이

        /// </summary>

        private int height;

 

        /// <summary>

        /// X 오프셋

        /// </summary>

        private double xOffset;

        

        /// <summary>

        /// Y 오프셋

        /// </summary>

        private double yOffset;

        

        /// <summary>

        /// Z 오프셋

        /// </summary>

        private double zOffset;

        

        /// <summary>

        /// X 스케일

        /// </summary>

        private double xScale;

        

        /// <summary>

        /// Y 스케일

        /// </summary>

        private double yScale;

        

        /// <summary>

        /// Z 스케일

        /// </summary>

        private double zScale;

 

 

        /// <summary>

        /// A

        /// </summary>

        private double a;

        

        /// <summary>

        /// B

        /// </summary>

        private double b;

        

        /// <summary>

        /// C

        /// </summary>

        private double c;

        

        /// <summary>

        /// D

        /// </summary>

        private double d;

        

        /// <summary>

        /// E

        /// </summary>

        private double e;

        

        /// <summary>

        /// X0

        /// </summary>

        private double x0;

        

        /// <summary>

        /// Y0

        /// </summary>

        private double y0;

        

        /// <summary>

        /// Z0

        /// </summary>

        private double z0;

 

        /// <summary>

        /// 배경색

        /// </summary>

        private Color backgroundColor;

        

        /// <summary>

        /// 전경색

        /// </summary>

        private Color foregroundColor;

 

        /// <summary>

        /// 실행 여부

        /// </summary>

        private bool isRunning = false;

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor

        ////////////////////////////////////////////////////////////////////////////////////////// Public

 

        #region 생성자 - MainForm()

 

        /// <summary>

        /// 생성자

        /// </summary>

        public MainForm()

        {

            InitializeComponent();

 

            #region 이벤트를 설정한다.

 

            Load                                   += Form_Load;

            this.foregroundColorDisplayLabel.Click += colorDisplayLabel_Click;

            this.backgroundColorDisplayLabel.Click += colorDisplayLabel_Click;

            this.startButton.Click                 += startButton_Click;

 

            #endregion

        }

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method

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

        //////////////////////////////////////////////////////////////////////////////// Event

 

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

 

        /// <summary>

        /// 폼 로드시 처리하기

        /// </summary>

        /// <param name="sender">이벤트 발생자</param>

        /// <param name="e">이벤트 인자</param>

        private void Form_Load(object sender, EventArgs e)

        {

            this.planeComboBox.SelectedIndex = 0;

 

            this.plane = Plane.XY;

        }

 

        #endregion

        #region 색상 표시 레이블 클릭시 처리하기 - colorDisplayLabel_Click(sender, e)

 

        /// <summary>

        /// 색상 표시 레이블 클릭시 처리하기

        /// </summary>

        /// <param name="sender">이벤트 발생자</param>

        /// <param name="e">이벤트 인자</param>

        private void colorDisplayLabel_Click(object sender, EventArgs e)

        {

            Label label = sender as Label;

 

            this.colorDialog.Color = label.BackColor;

 

            if(this.colorDialog.ShowDialog() == DialogResult.OK)

            {

                label.BackColor = this.colorDialog.Color;

            }

        }

 

        #endregion

        #region 시작 버튼 클릭시 처리하기 - startButton_Click(sender, e)

 

        /// <summary>

        /// 시작 버튼 클릭시 처리하기

        /// </summary>

        /// <param name="sender">이벤트 발생자</param>

        /// <param name="e">이벤트 인자</param>

        private void startButton_Click(object sender, EventArgs e)

        {

            if(this.isRunning)

            {

                this.isRunning = false;

 

                this.startButton.Text = "Stopped";

            }

            else

            {

                this.isRunning = true;

 

                this.startButton.Text = "Stop";

 

                DrawPickoverStrangeAttractorFractal();

 

                this.startButton.Text = "Start";

            }

        }

 

        #endregion

 

        //////////////////////////////////////////////////////////////////////////////// Function

 

        #region 준비하기 - Prepare()

 

        /// <summary>

        /// 준비하기

        /// </summary>

        private void Prepare()

        {

            this.backgroundColor = this.backgroundColorDisplayLabel.BackColor;

            this.foregroundColor = this.foregroundColorDisplayLabel.BackColor;

 

            this.width  = this.canvasPictureBox.ClientSize.Width;

            this.height = this.canvasPictureBox.ClientSize.Height;

 

            this.bitmap   = new Bitmap(this.width, this.height);

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

 

            this.graphics.Clear(this.backgroundColor);

 

            this.canvasPictureBox.Image = this.bitmap;

 

            const double MINIMUM_X = -2.1;

            const double MAXIMUM_X =  2.1;

            const double MINIMUM_Y = -2.1;

            const double MAXIMUM_Y =  2.1;

            const double MINIMUM_Z = -1.2;

            const double MAXIMUM_Z =  1.2;

 

            this.plane = (Plane)this.planeComboBox.SelectedIndex;

 

            switch(this.plane)

            {

                case Plane.XY :

 

                    this.xOffset = this.width  / 2;

                    this.yOffset = this.height / 2;

                    this.xScale  = this.width  / (MAXIMUM_X - MINIMUM_X);

                    this.yScale  = this.height / (MAXIMUM_Y - MINIMUM_Y);

 

                    break;

 

                case Plane.YZ :

 

                    this.yOffset = this.width  / 2;

                    this.zOffset = this.height / 2;

                    this.yScale  = this.width  / (MAXIMUM_Y - MINIMUM_Y);

                    this.zScale  = this.height / (MAXIMUM_Z - MINIMUM_Z);

 

                    break;

 

                case Plane.XZ :

 

                    this.xOffset = this.width  / 2;

                    this.zOffset = this.height / 2;

                    this.xScale  = this.width  / (MAXIMUM_X - MINIMUM_X);

                    this.zScale  = this.height / (MAXIMUM_Z - MINIMUM_Z);

 

                    break;

            }

 

            if(double.TryParse(this.aTextBox.Text, out this.a))

            {

                this.a = 2.0;

            }

 

            if(double.TryParse(this.bTextBox.Text, out this.b))

            {

                this.b = 0.5;

            }

 

            if(double.TryParse(this.cTextBox.Text, out this.c))

            {

                this.c = -0.6;

            }

 

            if(double.TryParse(this.dTextBox.Text, out this.d))

            {

                this.d = -2.5;

            }

 

            if(double.TryParse(this.eTextBox.Text, out this.e))

            {

                this.e = 1.0;

            }

 

            if(double.TryParse(this.x0TextBox.Text, out this.x0))

            {

                this.x0 = 0.0;

            }

 

            if(double.TryParse(this.y0TextBox.Text, out this.y0))

            {

                this.y0 = 0.0;

            }

 

            if(double.TryParse(this.z0TextBox.Text, out this.z0))

            {

                this.z0 = 0.0;

            }

        }

 

        #endregion

        #region 피코버 별난 끌개 프랙탈 그리기 - DrawPickoverStrangeAttractorFractal()

 

        /// <summary>

        /// 피코버 별난 끌개 프랙탈 그리기

        /// </summary>

        private void DrawPickoverStrangeAttractorFractal()

        {

            Prepare();

 

            double x = this.x0;

            double y = this.y0;

            double z = this.z0;

 

            while(this.isRunning)

            {

                for(int i = 1; i <= 1000; i++)

                {

                    double x2 = Math.Sin(this.a * y) - z * Math.Cos(this.b * x);

                    double y2 = z * Math.Sin(this.c * x) - Math.Cos(this.d * y);

 

                    z = Math.Sin(x);

                    x = x2;

                    y = y2;

 

                    switch(this.plane)

                    {

                        case Plane.XY :

 

                            this.bitmap.SetPixel

                            (

                                (int)(x * this.xScale + this.xOffset),

                                (int)(y * this.yScale + this.yOffset),

                                this.foregroundColor

                            );

 

                            break;

 

                        case Plane.YZ :

 

                            this.bitmap.SetPixel

                            (

                                (int)(y * this.yScale + this.yOffset),

                                (int)(z * this.zScale + this.zOffset),

                                this.foregroundColor

                            );

 

                            break;

 

                        case Plane.XZ :

 

                            this.bitmap.SetPixel

                            (

                                (int)(x * this.xScale + this.xOffset),

                                (int)(z * this.zScale + this.zOffset),

                                this.foregroundColor

                            );

 

                            break;

                    }

                }

 

                this.canvasPictureBox.Refresh();

 

                Application.DoEvents();

            }

        }

 

        #endregion

    }

}

 

------------------------------------------------------------------------------------------------------------------------

728x90
반응형
Posted by 사용자 icodebroker

댓글을 달아 주세요