첨부 소스 코드는 나눔고딕코딩 폰트를 사용합니다.
728x90
반응형
728x170

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 Bitmap bitmap;

        /// <summary>
        /// 이미지 너비
        /// </summary>
        private double imageWidth;
        
        /// <summary>
        /// 이미지 높이
        /// </summary>
        private double imageHeight;

        /// <summary>
        /// 계수 배열
        /// </summary>
        private double[] coefficientArray = new double[12];

        /// <summary>
        /// X
        /// </summary>
        private double x;
        
        /// <summary>
        /// Y
        /// </summary>
        private double y;
        
        /// <summary>
        /// X 최소값
        /// </summary>
        private double xMinimum;
        
        /// <summary>
        /// X 최대값
        /// </summary>
        private double xMaximuma;
        
        /// <summary>
        /// Y 최소값
        /// </summary>
        private double yMinimum;
        
        /// <summary>
        /// Y 최대값
        /// </summary>
        private double yMaximum;
        
        /// <summary>
        /// 너비
        /// </summary>
        private double width;
        
        /// <summary>
        /// 높이
        /// </summary>
        private double height;

        #endregion

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

        #region 생성자 - MainForm()

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

            #region 이벤트를 설정한다.

            Load                                          += Form_Load;
            this.coefficientComboBox.SelectedIndexChanged += coefficientComboBox_SelectedIndexChanged;
            this.showAxesCheckBox.CheckedChanged          += showAxesCheckBox_CheckedChanged;
            this.drawButton.Click                         += drawButton_Click;
            this.canvasPictureBox.Resize                  += canvasPictureBox_Resize;
            this.timer.Tick                               += timer_Tick;

            #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.coefficientComboBox.SelectedIndex = 0;

            DrawNewImage();
        }

        #endregion
        #region 계수 콤보 박스 선택 인덱스 변경시 처리하기 - coefficientComboBox_SelectedIndexChanged(sender, e)

        /// <summary>
        /// 계수 콤보 박스 선택 인덱스 변경시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void coefficientComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            DrawNewImage();
        }

        #endregion
        #region 축 표시 체크 박스 체크 변경시 처리하기 - showAxesCheckBox_CheckedChanged(sender, e)

        /// <summary>
        /// 축 표시 체크 박스 체크 변경시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void showAxesCheckBox_CheckedChanged(object sender, EventArgs e)
        {
            DrawNewImage();
        }

        #endregion
        #region 그리기 버튼 클릭시 처리하기 - drawButton_Click(sender, e)

        /// <summary>
        /// 그리기 버튼 클릭시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void drawButton_Click(object sender, EventArgs e)
        {
            this.timer.Enabled = !this.timer.Enabled;

            if(this.timer.Enabled)
            {
                this.drawButton.Text = "중단";
            }
            else
            {
                this.drawButton.Text = "그리기";
            }
        }

        #endregion
        #region 캔버스 픽처 박스 크기 조정시 처리하기 - canvasPictureBox_Resize(sender, e)

        /// <summary>
        /// 캔버스 픽처 박스 크기 조정시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void canvasPictureBox_Resize(object sender, EventArgs e)
        {
            DrawNewImage();
        }

        #endregion
        #region 타이머 틱 처리하기 - timer_Tick(sender, e)

        /// <summary>
        /// 타이머 틱 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void timer_Tick(object sender, EventArgs e)
        {
            for(int i = 1; i <= 1000; i++)
            {
                double newX = this.coefficientArray[0] + this.coefficientArray[1] * this.x + this.coefficientArray[2] * this.x * this.x +
                    this.coefficientArray[3] * this.x * this.y + this.coefficientArray[4 ] * this.y + this.coefficientArray[5 ] * this.y * this.y;
                double newY = this.coefficientArray[6] + this.coefficientArray[7] * this.x + this.coefficientArray[8] * this.x * this.x +
                    this.coefficientArray[9] * this.x * this.y + this.coefficientArray[10] * this.y + this.coefficientArray[11] * this.y * this.y;

                this.x = newX;
                this.y = newY;

                int xPixel = (int)Math.Round((this.x - this.xMinimum) / this.width * this.imageWidth);
                int yPixel = (int)Math.Round(this.imageHeight - (this.y - this.yMinimum) / this.height * this.imageHeight - 1);

                if((xPixel >= 0) && (xPixel < this.imageWidth) && (yPixel >= 0) && (yPixel < this.imageHeight))
                {
                    this.bitmap.SetPixel(xPixel, yPixel, Color.Blue);
                }
            }

            this.canvasPictureBox.Refresh();
        }

        #endregion

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

        #region 계수 설정하기 - SetCoefficient(coefficientString)

        /// <summary>
        /// 계수 설정하기
        /// </summary>
        /// <param name="coefficientString">계수 문자열</param>
        private void SetCoefficient(string coefficientString)
        {
            if(coefficientString.Length == 0)
            {
                return;
            }

            const int aASCII = (int)'A';

            string[] itemArray = coefficientString.Split(' ');

            char[] coefficientCharacterArray = itemArray[0].ToUpper().ToCharArray();

            for(int i = 0; i < 12; i++)
            {
                coefficientArray[i] = -1.2 + ((int)coefficientCharacterArray[i] - aASCII) * 0.1;
            }

            this.xMinimum  = double.Parse(itemArray[1]);
            this.xMaximuma = double.Parse(itemArray[2]);
            this.yMinimum  = double.Parse(itemArray[3]);
            this.yMaximum  = double.Parse(itemArray[4]);

            this.width  = this.xMaximuma - this.xMinimum;
            this.height = this.yMaximum  - this.yMinimum;
        }

        #endregion
        #region 새 이미지 그리기 - DrawNewImage()

        /// <summary>
        /// 새 이미지 그리기
        /// </summary>
        private void DrawNewImage()
        {
            if(this.canvasPictureBox.ClientSize.Width <= 0 || this.canvasPictureBox.ClientSize.Height <= 0)
            {
                return;
            }

            this.imageWidth  = this.canvasPictureBox.ClientSize.Width;
            this.imageHeight = this.canvasPictureBox.ClientSize.Height;

            SetCoefficient(this.coefficientComboBox.Text);

            this.x = 0;
            this.y = 0;

            this.bitmap = new Bitmap((int)this.imageWidth, (int)this.imageHeight);

            this.canvasPictureBox.BackgroundImage = this.bitmap;

            using(Graphics graphics = Graphics.FromImage(bitmap))
            {
                graphics.Clear(Color.Black);

                if(this.showAxesCheckBox.Checked)
                {
                    int xPixel = (int)Math.Round((0 - this.xMinimum) / this.width * this.imageWidth);
                    int yPixel = (int)Math.Round(this.imageHeight - (0 - this.yMinimum) / this.height * this.imageHeight - 1);

                    graphics.DrawLine(Pens.Red, xPixel, 0     , xPixel                                , this.canvasPictureBox.ClientSize.Height);
                    graphics.DrawLine(Pens.Red, 0     , yPixel, this.canvasPictureBox.ClientSize.Width, yPixel                                 );

                    for(float i = -5; i <= 5; i += 0.1f)
                    {
                        xPixel = (int)Math.Round((i - this.xMinimum) / this.width * this.imageWidth);

                        graphics.DrawLine(Pens.Orange, xPixel, yPixel - 3, xPixel, yPixel + 3);
                    }

                    for(float i = -5; i <= 5; i += 1)
                    {
                        xPixel = (int)Math.Round((i - this.xMinimum) / this.width * this.imageWidth);

                        graphics.DrawLine(Pens.Yellow, xPixel, yPixel - 5, xPixel, yPixel + 5);
                    }

                    xPixel = (int)Math.Round((0 - this.xMinimum) / this.width * this.imageWidth);

                    for(float i = -5; i <= 5; i += 0.1f)
                    {
                        yPixel = (int)Math.Round(this.imageHeight - (i - this.yMinimum) / this.height * this.imageHeight - 1);

                        graphics.DrawLine(Pens.Orange, xPixel - 3, yPixel, xPixel + 3, yPixel);
                    }

                    for(float i = -5; i <= 5; i += 1)
                    {
                        yPixel = (int)Math.Round(this.imageHeight - (i - this.yMinimum) / this.height * this.imageHeight - 1);

                        graphics.DrawLine(Pens.Yellow, xPixel - 5, yPixel, xPixel + 5, yPixel);
                    }
                }
            }

            this.canvasPictureBox.Invalidate();
        }

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

댓글을 달아 주세요