퇴근5분전

 전에 그래프 그리고 할때는 임의 점에서 각으로 특점 점을 찍어서 그렸던게 대부분이었는데... 

요즘 프로그램 업데이트를 위해 필요한걸 만들려다보니.. 이런 화살표가 필요한데... 

기본 pen에 있는 화살표는... 너무 작게 보인다. 그래서 선을 직접 그리는 걸로 만들려고... 간단히 

테스트 겸해서 만들어봤다. 

 

 몇년만에 다시 삼각함수를 ... 

1. pt1 찍고 -----------> pt2 까지 마우스로 움직였을때의 각( angle )을 구하고

2. 이 각에서 -25도, + 25도 되는 80의 거리를 가진 지점 위치를 구한다. 

3. 각각 구해진 자리를 pt1과 이어지도록 그린다. 

 

# 구성 

  - 판넬 하나 놓고. 

  - 판넬에 이벤트 paint, mouse_down, mouse_move, mouse_up 을 걸어준다. 

 

 public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        } 

        Pen linePen = new Pen(Brushes.Black, 2f) { 
            StartCap = System.Drawing.Drawing2D.LineCap.NoAnchor,
            EndCap = System.Drawing.Drawing2D.LineCap.NoAnchor,
        };

        private void panel1_Paint(object sender, PaintEventArgs e)
        {
            if (pt1 == pt2) return;

            e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
            e.Graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
            e.Graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;

            e.Graphics.DrawLine(linePen, pt1, pt2);

            float angle = -CalcAngleDegree(pt1, pt2);
            Point arowPt1 = CalcAngleRotate(angle - 25f, new Point(80, 0));
            Point arowPt2 = CalcAngleRotate(angle + 25f, new Point(80, 0));

            e.Graphics.DrawLine(linePen, pt1.X, pt1.Y, pt1.X + arowPt1.X, pt1.Y + arowPt1.Y);
            e.Graphics.DrawLine(linePen, pt1.X, pt1.Y, pt1.X + arowPt2.X, pt1.Y + arowPt2.Y);
        }


        bool isMDn = false;
        Point pt1;
        Point pt2;
        private void panel1_MouseDown(object sender, MouseEventArgs e)
        {
            isMDn = e.Button == MouseButtons.Left;
            pt1 = pt2 = e.Location;
        }

        private void panel1_MouseMove(object sender, MouseEventArgs e)
        {
            if (isMDn)
            {
                pt2 = e.Location;
                panel1.Invalidate();            
            }
        }

        private void panel1_MouseUp(object sender, MouseEventArgs e)
        {
            if (isMDn) panel1.Invalidate();

            isMDn = false;
          //  pt1 = pt2 = Point.Empty;
        }
         

        public float CalcAngleDegree(Point p1, Point p2)
        {
            double theta = 0d;
            int a = p2.X - p1.X;
            int b = p2.Y - p1.Y;


            if (b < 0)
            {
                theta = - (180 / Math.PI * Math.Atan2(b, a));
            }
            else
            {
                theta = 180 + (180 - (180 / Math.PI * Math.Atan2(b, a)));
            }
            return (float)theta;
        }

        public Point CalcAngleRotate(float anlge, Point p1)
        {
            Point p2 = p1;
            double rad = Math.PI / 180 * anlge;
            double x2 = Math.Cos(rad) * p1.X - Math.Sin(rad) * p1.Y;
            double y2 = Math.Sin(rad) * p1.X + Math.Cos(rad) * p1.Y;
            return new Point((int)x2, (int)y2);
        }
    }

 

############# 간만에 삼각함수를 하려니... 또 헷갈리네.. 

변환 : 라디안 <----> 각

 

라디안 = PI / 180 * 각도;   

각 = 180 / PI * 라디안; 

 

라디안을 구하고 싶으면 PI로 시작하면 편함. 

각을 구하고 싶으면 180으로 시작하면 편함. 

 

------------------------------------------- 구글링하면 많이 나오니까.. 

두 지점의 pt1, pt2의 각을 구할때는 atan2를 쓴다. 

tan@ = 높이(b)/ 밑변(a);

@ = aTan2( b / a);

 

CalcAngleDegree : 두 지점간에 각도 구하기

CalcAngleRotate : 회전시켜 다른 지점 구하기( 화살표 머리 양쪽지점 )

 

소스도 간단하니 딱히 더 주석달게 없네...