728x90
반응형
728x170
▶ MainForm.cs
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>
/// 포인트 리스트
/// </summary>
private List<PointF> pointList = new List<PointF>();
/// <summary>
/// 근접점 1
/// </summary>
private PointF closePoint1;
/// <summary>
/// 근접점 2
/// </summary>
private PointF closePoint2;
/// <summary>
/// 교차점
/// </summary>
private PointF intersectPoint;
/// <summary>
/// 직선 교차 여부
/// </summary>
private bool lineIntersect = false;
/// <summary>
/// 세그먼트 교차 여부
/// </summary>
private bool segmentIntersect = false;
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - MainForm()
/// <summary>
/// 생성자
/// </summary>
public MainForm()
{
InitializeComponent();
#region 이벤트를 설정한다.
MouseClick += Form_MouseClick;
Paint += Form_Paint;
#endregion
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Private
//////////////////////////////////////////////////////////////////////////////// Event
#region 폼 마우스 클릭시 처리하기 - Form_MouseClick(sender, e)
/// <summary>
/// 폼 마우스 클릭시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void Form_MouseClick(object sender, MouseEventArgs e)
{
if(this.pointList.Count == 4)
{
this.pointList = new List<PointF>();
this.lineIntersect = false;
}
this.pointList.Add(new PointF(e.X, e.Y));
if(this.pointList.Count == 4)
{
FindIntersection
(
this.pointList[0],
this.pointList[1],
this.pointList[2],
this.pointList[3],
out this.lineIntersect,
out this.segmentIntersect,
out this.intersectPoint,
out this.closePoint1,
out this.closePoint2
);
}
Invalidate();
}
#endregion
#region 폼 페인트시 처리하기 - Form_Paint(sender, e)
/// <summary>
/// 폼 페인트시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void Form_Paint(object sender, PaintEventArgs e)
{
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
if(this.pointList.Count == 4)
{
e.Graphics.DrawLine(Pens.Green, this.pointList[2], this.pointList[3]);
}
if(this.pointList.Count >= 2)
{
e.Graphics.DrawLine(Pens.Blue, this.pointList[0], this.pointList[1]);
}
if(this.lineIntersect)
{
using(Pen dashPen = new Pen(Color.Red))
{
dashPen.DashStyle = DashStyle.Custom;
dashPen.DashPattern = new float[] { 4, 4 };
e.Graphics.DrawLine(dashPen, this.closePoint1, this.closePoint2);
}
}
foreach(PointF point in this.pointList)
{
DrawPoint(e.Graphics, point, Brushes.White, Pens.Black);
}
if(this.lineIntersect)
{
DrawPoint(e.Graphics, this.closePoint1 , Brushes.LightBlue, Pens.Blue);
DrawPoint(e.Graphics, this.closePoint2 , Brushes.LightBlue, Pens.Blue);
DrawPoint(e.Graphics, this.intersectPoint, Brushes.HotPink , Pens.Red );
}
}
#endregion
//////////////////////////////////////////////////////////////////////////////// Function
#region 포인트 그리기 - DrawPoint(graphics, point, brush, pen)
/// <summary>
/// 포인트 그리기
/// </summary>
/// <param name="graphics">그래픽스</param>
/// <param name="point">포인트</param>
/// <param name="brush">브러시</param>
/// <param name="pen">펜</param>
private void DrawPoint(Graphics graphics, PointF point, Brush brush, Pen pen)
{
const int RADIUS = 3;
graphics.FillEllipse(brush, point.X - RADIUS, point.Y - RADIUS, 2 * RADIUS, 2 * RADIUS);
graphics.DrawEllipse(pen, point.X - RADIUS, point.Y - RADIUS, 2 * RADIUS, 2 * RADIUS);
}
#endregion
#region 교차점 찾기 - FindIntersection(p1, p2, p3, p4, lineIntersect, segmentIntersect, intersectPoint, closePoint1, closePoint2)
/// <summary>
/// 교차점 찾기
/// </summary>
/// <param name="p1">직선 1 포인트 1</param>
/// <param name="p2">직선 1 포인트 2</param>
/// <param name="p3">직선 2 포인트 1</param>
/// <param name="p4">직선 2 포인트 2</param>
/// <param name="lineIntersect">선 교차 여부</param>
/// <param name="segmentIntersect">세그먼트 교차 여부</param>
/// <param name="intersectPoint">교차점</param>
/// <param name="closePoint1">근접점 1</param>
/// <param name="closePoint2">근접점 2</param>
private void FindIntersection
(
PointF p1,
PointF p2,
PointF p3,
PointF p4,
out bool lineIntersect,
out bool segmentIntersect,
out PointF intersectPoint,
out PointF closePoint1,
out PointF closePoint2)
{
float dx21 = p2.X - p1.X;
float dy21 = p2.Y - p1.Y;
float dx43 = p4.X - p3.X;
float dy43 = p4.Y - p3.Y;
float denominator = (dy21 * dx43 - dx21 * dy43);
float t1 = ((p1.X - p3.X) * dy43 + (p3.Y - p1.Y) * dx43) / denominator;
if(float.IsInfinity(t1))
{
lineIntersect = false;
segmentIntersect = false;
intersectPoint = new PointF(float.NaN, float.NaN);
closePoint1 = new PointF(float.NaN, float.NaN);
closePoint2 = new PointF(float.NaN, float.NaN);
return;
}
lineIntersect = true;
float t2 = ((p3.X - p1.X) * dy21 + (p1.Y - p3.Y) * dx21) / -denominator;
intersectPoint = new PointF(p1.X + dx21 * t1, p1.Y + dy21 * t1);
segmentIntersect = ((t1 >= 0) && (t1 <= 1) && (t2 >= 0) && (t2 <= 1));
if(t1 < 0)
{
t1 = 0;
}
else if(t1 > 1)
{
t1 = 1;
}
if(t2 < 0)
{
t2 = 0;
}
else if(t2 > 1)
{
t2 = 1;
}
closePoint1 = new PointF(p1.X + dx21 * t1, p1.Y + dy21 * t1);
closePoint2 = new PointF(p3.X + dx43 * t2, p3.Y + dy43 * t2);
}
#endregion
}
}
728x90
반응형
그리드형(광고전용)
'C# > WinForm' 카테고리의 다른 글
[C#/WINFORM] 폰트 메트릭(Font Metrics) 구하기 (0) | 2018.12.08 |
---|---|
[C#/WINFORM] 문자 크기 측정하기 (0) | 2018.12.08 |
[C#/WINFORM] 마우스 드래그시 고무밴드 상자(Rubber Band Box) 표시하기 (0) | 2018.12.08 |
[C#/WINFORM] 포인트 리스트를 둘러싸는 원 구하기 (0) | 2018.12.05 |
[C#/WINFORM] 2개 직선 사이 최단거리 구하기 (0) | 2018.12.05 |
[C#/WINFORM] 2개 직선의 교차 여부 구하기 (0) | 2018.12.05 |
[C#/WINFORM] 하이포트로코이드(Hypotrochoid) 그리기 (0) | 2018.12.05 |
[C#/WINFORM] Button 클래스 : 버튼 모양 설정하기 (0) | 2018.12.03 |
[C#/WINFORM] 다각형 처리하기 (0) | 2018.12.03 |
[C#/WINFORM] 시어핀스키 곡선(Sierpinski Curve) 그리기 (0) | 2018.12.03 |
[C#/WINFORM] 별난 끌개 프랙탈(Strange Attractor Fractal) 그리기 (0) | 2018.12.02 |
댓글을 달아 주세요