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

728x90
반응형
728x170

TestProject.zip
0.01MB

▶ MainForm.cs

using System;
using System.Collections.Generic;
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>
        /// 포인트 1
        /// </summary>
        private PointF point1;
        
        /// <summary>
        /// 포인트 2
        /// </summary>
        private PointF point2;

        /// <summary>
        /// 포인트 리스트
        /// </summary>
        private List<PointF[]> pointList = new List<PointF[]>();

        private Brush[] brushArray =
        {
            new SolidBrush(Color.FromArgb(128, Color.Red )),
            new SolidBrush(Color.FromArgb(128, Color.Red )),
            new SolidBrush(Color.FromArgb(128, Color.Blue)),
            new SolidBrush(Color.FromArgb(128, Color.Blue))
        };

        /// <summary>
        /// 펜 배열
        /// </summary>
        private Pen[] penArray =
        {
            Pens.Red,
            Pens.Red,
            Pens.Blue,
            Pens.Blue
        };

        /// <summary>
        /// 그리기 여부
        /// </summary>
        private bool isDrawing = false;

        #endregion

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

        #region 생성자 - MainForm()

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

            this.aspectRatioTextBox.TextChanged += aspectRatioTextBox_TextChanged;
            this.pictureBox.Paint               += pictureBox_Paint;
            this.pictureBox.MouseDown           += pictureBox_MouseDown;
            this.pictureBox.MouseMove           += pictureBox_MouseMove;
            this.pictureBox.MouseUp             += pictureBox_MouseUp;
        }

        #endregion

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

        #region 종횡비 텍스트 박스 텍스트 변경시 처리하기 - aspectRatioTextBox_TextChanged(sender, e)

        /// <summary>
        /// 종횡비 텍스트 박스 텍스트 변경시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void aspectRatioTextBox_TextChanged(object sender, EventArgs e)
        {
            this.point1 = new PointF();
            this.point2 = new PointF();

            this.pointList = new List<PointF[]>();

            this.pictureBox.Refresh();
        }

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

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

            this.pointList = new List<PointF[]>();

            this.pictureBox.Refresh();

            this.isDrawing = true;
        }

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

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

            this.point2 = e.Location;

            this.pictureBox.Refresh();
        }

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

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

            this.isDrawing = false;

            float aspectRatio = GetAspectRatio(this.aspectRatioTextBox.Text);

            this.pointList = FindRectangle(aspectRatio, this.point1, this.point2);

            this.pictureBox.Refresh();
        }

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

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

            e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;

            for(int i = 0; i < this.pointList.Count; i++)
            {
                e.Graphics.FillPolygon(this.brushArray[i], this.pointList[i]);

                e.Graphics.DrawPolygon(this.penArray[i], this.pointList[i]);
            }

            if(this.point1 != this.point2)
            {
                e.Graphics.DrawLine(Pens.Black, this.point1, this.point2);
            }
        }

        #endregion

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

        #region 종횡비 구하기 - GetAspectRatio(text)

        /// <summary>
        /// 종횡비 구하기
        /// </summary>
        /// <param name="text">텍스트</param>
        /// <returns>종횡비</returns>
        private float GetAspectRatio(string text)
        {
            try
            {
                if(text.Contains(":"))
                {
                    float width  = float.Parse(text.Split(':')[0]);
                    float height = float.Parse(text.Split(':')[1]);

                    return width / height;
                }
                else
                {
                    return float.Parse(text);
                }
            }
            catch
            {
                return 1;
            }
        }

        #endregion
        #region 사각형 찾기 - FindRectangle(aspectRatio, point1, point2)

        /// <summary>
        /// 사각형 찾기
        /// </summary>
        /// <param name="aspectRatio">종횡비</param>
        /// <param name="point1">포인트 1</param>
        /// <param name="point2">포인트 2</param>
        /// <returns>사각형</returns>
        private List<PointF[]> FindRectangle(float aspectRatio, PointF point1, PointF point2)
        {
            float vectorX = point2.X - point1.X;
            float vectorY = point2.Y - point1.Y;

            if(Math.Sqrt(vectorX * vectorX + vectorY * vectorY) < 0.1)
            {
                return null;
            }

            PointF point3;
            PointF point4;

            List<PointF[]> pointList = new List<PointF[]>();

            float perpendicularVectorX;
            float perpendicularVectorY;

            perpendicularVectorX =  vectorY * aspectRatio;
            perpendicularVectorY = -vectorX * aspectRatio;

            point3 = new PointF(point2.X + perpendicularVectorX, point2.Y + perpendicularVectorY);
            point4 = new PointF(point1.X + perpendicularVectorX, point1.Y + perpendicularVectorY);

            pointList.Add(new PointF[] { point1, point2, point3, point4 });

            point3 = new PointF(point2.X - perpendicularVectorX, point2.Y - perpendicularVectorY);
            point4 = new PointF(point1.X - perpendicularVectorX, point1.Y - perpendicularVectorY);

            pointList.Add(new PointF[] { point1, point2, point3, point4 });

            perpendicularVectorX =  vectorY / aspectRatio;
            perpendicularVectorY = -vectorX / aspectRatio;

            point3 = new PointF(point2.X + perpendicularVectorX, point2.Y + perpendicularVectorY);
            point4 = new PointF(point1.X + perpendicularVectorX, point1.Y + perpendicularVectorY);

            pointList.Add(new PointF[] { point1, point2, point3, point4 });

            point3 = new PointF(point2.X - perpendicularVectorX, point2.Y - perpendicularVectorY);
            point4 = new PointF(point1.X - perpendicularVectorX, point1.Y - perpendicularVectorY);

            pointList.Add(new PointF[] { point1, point2, point3, point4 });

            return pointList;
        }

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

댓글을 달아 주세요