C# -- GraphicsPath HitTest & PathTypes
C# -- GraphicsPath HitTest & PathTypes
참고 : http://csharphelper.com/blog/2016/03/see-mouse-curve-c/ ---> 코드 출처
http://devlabo.blogspot.com/2016/04/graphicspoints.html
https://docs.microsoft.com/ko-kr/dotnet/framework/winforms/advanced/graphics-paths-in-gdi
https://stackoverflow.com/questions/34503334/graphics-path-types-not-in-the-document
** HitTest
-- GraphicsPath 이용하여, line 이나 곡선의 Hit test 시에는, IsOutlineVisible() 을 사용하면 됨.
* IsVisible( ) 사용시에는, closed figure 에서는 의도와 다른 결과 발생함.
** 주의: pen 두께를 넓게하면, 중앙선을 제외한 나머지 부분에서는 IsOutlineVisible( ) 에서 인식못함.
--> 오직, point 끼리 연결한, 중앙선만 인식한다.
--> 따라서, IsOutlineVisible( ) 에서 사용하는 pen 의 width 를 조절하여, hit test 하자!
< 실행 결과 >
-- hittest 성공시에는, 마우스 모양 바뀌게함.
---> 노란선 그은 point 만, 프로그램시 지정한 point 이다.
< 소스 >
---
using System; | |
using System.Collections.Generic; | |
using System.ComponentModel; | |
using System.Data; | |
using System.Drawing; | |
using System.Drawing.Drawing2D; | |
using System.Linq; | |
using System.Text; | |
using System.Threading.Tasks; | |
using System.Windows.Forms; | |
namespace hittest_curve | |
{ | |
public partial class Form1 : Form | |
{ | |
GraphicsPath gp = new GraphicsPath(); | |
private Point[] points = | |
{ | |
new Point(213, 204), | |
new Point(63, 143), | |
new Point(227, 60), | |
new Point(123, 222), | |
new Point(72, 64), | |
}; | |
private Point pt_line = new Point(300, 300); | |
public Form1() | |
{ | |
InitializeComponent(); | |
} | |
private void Form1_Load(object sender, EventArgs e) | |
{ | |
//gp.StartFigure(); | |
gp.AddLine(pt_line, points[0]); | |
gp.AddCurve(points); | |
//gp.CloseFigure(); | |
} | |
private void Form1_Paint(object sender, PaintEventArgs e) | |
{ | |
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias; | |
using(Pen pen = new Pen(Color.Red, 15)) | |
{ | |
e.Graphics.DrawPath(pen, gp); | |
e.Graphics.DrawCurve(new Pen(Color.Yellow, 1), points); // 곡선 중심선만 긋기 | |
} | |
} | |
private void Form1_MouseMove(object sender, MouseEventArgs e) | |
{ | |
PointF[] pts = gp.PathData.Points; | |
byte[] types = gp.PathData.Types; | |
// Hit Test | |
if (MyHitTest(e.Location)) | |
{ | |
Cursor = Cursors.Cross; // 마우스 커서 모양 마꾸기 | |
for(int i=0; i < gp.PathData.Points.Length; i++) | |
{ | |
Console.WriteLine($"point={pts[i]}, type= {types[i]}"); | |
} | |
Console.WriteLine("------------------"); | |
Console.WriteLine($"gp.PathData.Points.Length={gp.PathData.Points.Length}"); | |
Console.WriteLine($"gp.Pointcount={gp.PointCount}"); | |
MyDrawPoints(pts); // paint event 시에는 그린것 사라짐. | |
} else | |
{ | |
Cursor = Cursors.Default; | |
} | |
} | |
private bool MyHitTest(Point pt) | |
{ | |
using (Pen pen = new Pen(Color.Blue, 3)) | |
{ | |
return gp.IsOutlineVisible(pt, pen); | |
//return gp.IsVisible(pt); | |
} | |
} | |
// point 마다, 사각형 그리기 | |
private void MyDrawPoints(PointF[] pts) | |
{ | |
using (Graphics g = this.CreateGraphics()) | |
using (Brush brush = new SolidBrush(Color.Blue)) | |
{ | |
foreach( var pt in pts) | |
{ | |
g.FillRectangle(brush, pt.X-2, pt.Y-2, 5, 5); | |
} | |
} | |
} | |
} | |
} |