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

■ 다각형 내부에서 별 그리기

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


TestProject.zip


MainForm.cs

 

 

using System;

using System.Drawing;

using System.Drawing.Drawing2D;

using System.Windows.Forms;

 

namespace TestProject

{

    /// <summary>

    /// 메인 폼

    /// </summary>

    public partial class MainForm : Form

    {

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

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

 

        #region Field

 

        /// <summary>

        /// 포인트 카운트

        /// </summary>

        private int pointCount = 0;

 

        #endregion

 

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

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

 

        #region 생성자 - MainForm()

 

        /// <summary>

        /// 생성자

        /// </summary>

        public MainForm()

        {

            InitializeComponent();

 

            #region 이벤트를 설정한다.

 

            this.drawButton.Click        += drawButton_Click;

            this.canvasPictureBox.Resize += canvasPictureBox_Resize;

            this.canvasPictureBox.Paint  += canvasPictureBox_Paint;

 

            #endregion

        }

 

        #endregion

 

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

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

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

 

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

 

        /// <summary>

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

        /// </summary>

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

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

        private void drawButton_Click(object sender, EventArgs e)

        {

            int pointCount;

 

            if(!int.TryParse(pointCountTextBox.Text, out pointCount))

            {

                MessageBox.Show("포인트 수는 정수로 입력해 주시기 바랍니다.");

            }

            else if (pointCount< 3)

            {

                MessageBox.Show("포인트 수는 반드시 3 이상이어야 합니다.");

            }

            else

            {

                this.pointCount = pointCount;

 

                this.canvasPictureBox.Refresh();

            }

        }

 

        #endregion

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

 

        /// <summary>

        /// 캔버스 픽처 박스 크기 조정시 처리하기

        /// </summary>

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

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

        private void canvasPictureBox_Resize(object sender, EventArgs e)

        {

            this.canvasPictureBox.Refresh();

        }

 

        #endregion

        #region 캔버스 픽처 박스 페인트시 처리하기 - canvasPictureBox_Paint(sender, e)

 

        /// <summary>

        /// 캔버스 픽처 박스 페인트시 처리하기

        /// </summary>

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

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

        private void canvasPictureBox_Paint(object sender, PaintEventArgs e)

        {

            if(this.pointCount < 3)

            {

                return;

            }

 

            e.Graphics.Clear(this.canvasPictureBox.BackColor);

 

            e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;

 

            int radius1;

            int radius2;

            int radius3;

 

            radius3 = Math.Min

            (

                this.canvasPictureBox.ClientSize.Width,

                this.canvasPictureBox.ClientSize.Height

            ) / 2;

 

            radius1 = radius3 / 2;

            radius2 = radius3 / 4;

            radius3 = radius1 + radius2;

 

            int centerX = this.canvasPictureBox.ClientSize.Width  / 2;

            int centerY = this.canvasPictureBox.ClientSize.Height / 2;

 

            PointF[] pointArray1 = new PointF[this.pointCount];

            PointF[] pointArray2 = new PointF[this.pointCount];

 

            double theta      = -Math.PI / 2;

            double deltaTheta = 2 * Math.PI / this.pointCount;

 

            for(int i = 0; i < this.pointCount; i++)

            {

                pointArray1[i].X = (float)(radius1 * Math.Cos(theta));

                pointArray1[i].Y = (float)(radius1 * Math.Sin(theta));

                pointArray2[i].X = (float)(radius2 * Math.Cos(theta));

                pointArray2[i].Y = (float)(radius2 * Math.Sin(theta));

 

                theta += deltaTheta;

            }

 

            int maximum = this.pointCount - 1;

 

            for(int skip = 1; skip <= maximum; skip++)

            {

                if(GetGreatestCommonDivisor(skip, this.pointCount) == 1)

                {

                    DrawStar(e.Graphics, centerX, centerY, pointArray1, skip);

 

                    theta = -Math.PI / 2 + skip * 2 * Math.PI / this.pointCount;

 

                    int x = (int)(centerX + radius3 * Math.Cos(theta));

                    int y = (int)(centerY + radius3 * Math.Sin(theta));

 

                    DrawStar(e.Graphics, x, y, pointArray2, skip);

                }

            }

        }

 

        #endregion

 

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

 

        #region 최대 공약수 구하기 - GetGreatestCommonDivisor(a, b)

 

        /// <summary>

        /// 최대 공약수 구하기

        /// </summary>

        /// <param name="a">A</param>

        /// <param name="b">B</param>

        /// <returns>최대 공약수</returns>

        private long GetGreatestCommonDivisor(long a, long b)

        {

            long remainder;

 

            for(;;)

            {

                remainder = a % b;

 

                if(remainder == 0)

                {

                    break;

                }

 

                a = b;

                b = remainder;

            }

 

            return b;

        }

 

        #endregion

        #region 별 그리기 - DrawStar(graphics, x, y, sourcePointArray, skip)

 

        /// <summary>

        /// 별 그리기

        /// </summary>

        /// <param name="graphics">그래픽스</param>

        /// <param name="x">X 좌표</param>

        /// <param name="y">Y 좌표</param>

        /// <param name="sourcePointArray">소스 포인트 배열</param>

        /// <param name="skip">건너띄기</param>

        private void DrawStar(Graphics graphics, int x, int y, PointF[] sourcePointArray, int skip)

        {

            PointF[] pointArray = new PointF[this.pointCount];

 

            for(int i = 0; i < this.pointCount; i++)

            {

                pointArray[i] = sourcePointArray[(i * skip) % this.pointCount];

            }

 

            graphics.TranslateTransform(x, y);

 

            graphics.DrawPolygon(Pens.Blue, pointArray);

 

            graphics.ResetTransform();

        }

 

        #endregion

    }

}

 

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

Posted by 사용자 icodebroker

댓글을 달아 주세요