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

TestProject.zip
다운로드

▶ Octagon.cs

using System;
using System.Collections.Generic;
using System.Drawing;

namespace TestProject
{
    /// <summary>
    /// 8각형
    /// </summary>
    public class Octagon
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// 난수기
        /// </summary>
        private static Random _random = new Random();

        /// <summary>
        /// 색상 배열
        /// </summary>
        private static Color[] _colorArray =
        {
            Color.Aquamarine,
            Color.Red,
            Color.Orange,
            Color.Yellow,
            Color.SeaShell,
            Color.RosyBrown,
            Color.Cyan,
            Color.Blue,
            Color.LightBlue,
            Color.Fuchsia,
            Color.Beige,
            Color.BlueViolet,
            Color.Orange
        };

        #endregion

        ////////////////////////////////////////////////////////////////////////////////////////// Instance
        //////////////////////////////////////////////////////////////////////////////// Public

        #region Field

        /// <summary>
        /// 포인트 배열
        /// </summary>
        public PointF[] PointArray = null;

        /// <summary>
        /// 채우기 색상
        /// </summary>
        public Color FillColor = Color.Black;

        /// <summary>
        /// 자식 리스트
        /// </summary>
        public List<Octagon> ChildList = new List<Octagon>();

        #endregion

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

        #region 생성자 - Octagon(pointArray)

        /// <summary>
        /// 생성자
        /// </summary>
        /// <param name="pointArray">포인트 배열</param>
        public Octagon(PointF[] pointArray)
        {
            PointArray = pointArray;

            FillColor = _colorArray[_random.Next(0, _colorArray.Length)];

            FillColor = Color.FromArgb(80, FillColor);
        }

        #endregion

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

        #region 그리기 - Draw(graphics)

        /// <summary>
        /// 그리기
        /// </summary>
        /// <param name="graphics">그래픽스</param>
        public void Draw(Graphics graphics)
        {
            using(Brush brush = new SolidBrush(FillColor))
            {
                graphics.FillPolygon(brush, PointArray);
            }

            graphics.DrawPolygon(Pens.Black, PointArray);

            foreach(Octagon child in ChildList)
            {
                child.Draw(graphics);
            }
        }

        #endregion
    }
}

 

728x90

 

▶ 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 Octagon root = null;

        /// <summary>
        /// 크기 스케일
        /// </summary>
        private float sizeScale = (float)(1.0 / (2.0 * (1 + Math.Cos(Math.PI / 180 * 45))));

        #endregion

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

        #region 생성자 - MainForm()

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

            #region 이벤트를 설정한다.

            Load                                 += Form_Load;
            this.depthNumericUpDown.ValueChanged += depthNumericUpDown_ValueChanged;
            this.drawButton.Click                += drawButton_Click;
            this.canvasPictureBox.Paint          += canvasPictureBox_Paint;

            #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)
        {
            DrawSierpinskiOctagon();
        }

        #endregion
        #region 깊이 숫자 UP/DOWN 값 변경시 처리하기 - depthNumericUpDown_ValueChanged(sender, e)

        /// <summary>
        /// 깊이 숫자 UP/DOWN 값 변경시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void depthNumericUpDown_ValueChanged(object sender, EventArgs e)
        {
            DrawSierpinskiOctagon();
        }

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

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

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

        /// <summary>
        /// 캔버스 픽처 박스 페인트시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void canvasPictureBox_Paint(object sender, PaintEventArgs e)
        {
            e.Graphics.Clear(this.canvasPictureBox.BackColor);

            e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;

            if(this.root == null)
            {
                return;
            }

            this.root.Draw(e.Graphics);
        }

        #endregion

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

        #region 8각형 포인트 배열 구하기 - GetOctagonPointArray(centerPoint, radius)

        /// <summary>
        /// 8각형 포인트 배열 구하기
        /// </summary>
        /// <param name="centerPoint">중심 포인트</param>
        /// <param name="radius">반지름</param>
        /// <returns>8각형 포인트 배열</returns>
        private PointF[] GetOctagonPointArray(PointF centerPoint, float radius)
        {
            PointF[] pointArray = new PointF[8];
            double   theta      = -Math.PI / 2.0;
            double   deltaTheta = 2.0 * Math.PI / 8.0;

            for(int i = 0; i < 8; i++)
            {
                pointArray[i] = new PointF
                (
                    centerPoint.X + (float)(radius * Math.Cos(theta)),
                    centerPoint.Y + (float)(radius * Math.Sin(theta))
                );

                theta += deltaTheta;
            }

            return pointArray;
        }

        #endregion
        #region 8각형 구하기 - GetOctagon(depth, centerPoint, radius)

        /// <summary>
        /// 8각형 구하기
        /// </summary>
        /// <param name="depth">깊이</param>
        /// <param name="centerPoint">중심 포인트</param>
        /// <param name="radius">반지름</param>
        /// <returns>8각형</returns>
        private Octagon GetOctagon(int depth, PointF centerPoint, float radius)
        {
            Octagon parent = new Octagon(GetOctagonPointArray(centerPoint, radius));

            if(depth > 0)
            {
                float d = radius - radius * this.sizeScale;

                PointF[] pointArray = GetOctagonPointArray(centerPoint, d);

                foreach(PointF point in pointArray)
                {
                    parent.ChildList.Add
                    (
                        GetOctagon
                        (
                            depth - 1,
                            point,
                            radius * this.sizeScale
                        )
                    );
                }
            }

            return parent;
        }

        #endregion
        #region 시어핀스키 8각형 그리기 - DrawSierpinskiOctagon()

        /// <summary>
        /// 시어핀스키 8각형 그리기
        /// </summary>
        private void DrawSierpinskiOctagon()
        {
            int depth = (int)this.depthNumericUpDown.Value;

            PointF centerPoint = new PointF
            (
                this.canvasPictureBox.ClientSize.Width  / 2,
                this.canvasPictureBox.ClientSize.Height / 2
            );

            float radius = (float)Math.Min(centerPoint.X, centerPoint.Y);

            radius -= 5;

            this.root = GetOctagon(depth, centerPoint, radius);

            this.canvasPictureBox.Refresh();
        }

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

댓글을 달아 주세요