■ 대칭 복합 선 그리기
------------------------------------------------------------------------------------------------------------------------
▶ MainWindow.xaml
<Window x:Class="TestProject.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="600" Height="450" Title="대칭 복합 선 그리기" Loaded="Window_Loaded"> <Grid Name="mainGrid"> </Grid> </Window>
|
▶ MainWindow.xaml.cs
using System; using System.Windows; using System.Windows.Media; using System.Windows.Shapes;
namespace TestProject { /// <summary> /// 메인 윈도우 /// </summary> public partial class MainWindow : Window { //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - MainWindow()
/// <summary> /// 생성자 /// </summary> public MainWindow() { InitializeComponent(); }
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Private //////////////////////////////////////////////////////////////////////////////// Event
#region 윈도우 로드시 처리하기 - Window_Loaded(sender, e)
/// <summary> /// 윈도우 로드시 처리하기 /// </summary> /// <param name="sender">이벤트 발생자</param> /// <param name="e">이벤트 인자</param> private void Window_Loaded(object sender, RoutedEventArgs e) { double width = Math.Min ( this.mainGrid.ActualWidth - 60, this.mainGrid.ActualHeight - 40 );
Rect rectangle = new Rect(30, 40, width, width);
Point[] pointArray = GetStarPointArray(-Math.PI / 2, 5, 2, rectangle);
double[] thicknessesArray = { 15, 10, 6 };
Brush[] brusheArray = { Brushes.Blue, Brushes.White, Brushes.Blue };
for(int i = 0; i < thicknessesArray.Length; i++) { Polygon polygon = new Polygon();
polygon.Points = new PointCollection(pointArray); polygon.StrokeThickness = thicknessesArray[i]; polygon.Stroke = brusheArray[i];
this.mainGrid.Children.Add(polygon); } }
#endregion
//////////////////////////////////////////////////////////////////////////////// Function
#region 교차 포인트 찾기 - FindIntersectionPoint(point1, point2, point3, point4, lineIntersect, segmentIntersect, intersectionPoint, closePoint1, closePoint2)
/// <summary> /// 교차 포인트 찾기 /// </summary> /// <param name="point1">포인트 1</param> /// <param name="point2">포인트 2</param> /// <param name="point3">포인트 3</param> /// <param name="point4">포인트 41</param> /// <param name="lineIntersect">직선 교차 여부</param> /// <param name="segmentIntersect">세그먼트 교차 여부</param> /// <param name="intersectionPoint">교차 포인트</param> /// <param name="closePoint1">근접 포인트 1</param> /// <param name="closePoint2">근접 포인트 2</param> private void FindIntersectionPoint(Point point1, Point point2, Point point3, Point point4, out bool lineIntersect, out bool segmentIntersect, out Point intersectionPoint, out Point closePoint1, out Point closePoint2) { double dx12 = point2.X - point1.X; double dy12 = point2.Y - point1.Y; double dx34 = point4.X - point3.X; double dy34 = point4.Y - point3.Y;
double denominator = (dy12 * dx34 - dx12 * dy34);
double t1 = ((point1.X - point3.X) * dy34 + (point3.Y - point1.Y) * dx34) / denominator;
if(double.IsInfinity(t1)) { lineIntersect = false; segmentIntersect = false;
intersectionPoint = new Point(double.NaN, double.NaN);
closePoint1 = new Point(double.NaN, double.NaN); closePoint2 = new Point(double.NaN, double.NaN);
return; }
lineIntersect = true;
double t2 = ((point3.X - point1.X) * dy12 + (point1.Y - point3.Y) * dx12) / -denominator;
intersectionPoint = new Point(point1.X + dx12 * t1, point1.Y + dy12 * 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 Point(point1.X + dx12 * t1, point1.Y + dy12 * t1); closePoint2 = new Point(point3.X + dx34 * t2, point3.Y + dy34 * t2); }
#endregion #region 오목 반지름 구하기 - GetConcaveRadius(pointCount, skip)
/// <summary> /// 오목 반지름 구하기 /// </summary> /// <param name="pointCount">포인트 카운트</param> /// <param name="skip">건너띄기</param> /// <returns>오목 반지름</returns> private double GetConcaveRadius(int pointCount, int skip) { if(pointCount < 5) { return 0.33f; }
double deltaTheta = 2 * Math.PI / pointCount; double theta00 = -Math.PI / 2; double theta01 = theta00 + deltaTheta * skip; double theta10 = theta00 + deltaTheta; double theta11 = theta10 - deltaTheta * skip;
Point pt00 = new Point ( (double)Math.Cos(theta00), (double)Math.Sin(theta00) );
Point pt01 = new Point ( (double)Math.Cos(theta01), (double)Math.Sin(theta01) );
Point pt10 = new Point ( (double)Math.Cos(theta10), (double)Math.Sin(theta10) );
Point pt11 = new Point ( (double)Math.Cos(theta11), (double)Math.Sin(theta11) );
bool lineIntersect; bool segmentIntersect;
Point intersectionPoint; Point closePoint1; Point closePoint2;
FindIntersectionPoint ( pt00, pt01, pt10, pt11, out lineIntersect, out segmentIntersect, out intersectionPoint, out closePoint1, out closePoint2 );
return Math.Sqrt(intersectionPoint.X * intersectionPoint.X + intersectionPoint.Y * intersectionPoint.Y); }
#endregion #region 별 포인트 배열 구하기 - GetStarPointArray(startTheta, pointCount, skip, rectangle)
/// <summary> /// 별 포인트 배열 구하기 /// </summary> /// <param name="startTheta">시작 세타</param> /// <param name="pointCount">포인트 카운트</param> /// <param name="skip">건너띄기</param> /// <param name="rectangle">사각형</param> /// <returns>별 포인트 배열</returns> private Point[] GetStarPointArray(double startTheta, int pointCount, int skip, Rect rectangle) { double theta; double deltaTheta; Point[] pointArray;
double halfWidth = rectangle.Width / 2f; double halfHeight = rectangle.Height / 2f; double centerX = rectangle.X + halfWidth; double centerY = rectangle.Y + halfHeight;
if(skip == 1) { pointArray = new Point[pointCount];
theta = startTheta;
deltaTheta = 2 * Math.PI / pointCount;
for(int i = 0; i < pointCount; i++) { pointArray[i] = new Point ( (double)(centerX + halfWidth * Math.Cos(theta)), (double)(centerY + halfHeight * Math.Sin(theta)) );
theta += deltaTheta; }
return pointArray; }
double concaveRadius = GetConcaveRadius(pointCount, skip);
pointArray = new Point[2 * pointCount]; theta = startTheta; deltaTheta = Math.PI / pointCount;
for(int i = 0; i < pointCount; i++) { pointArray[2 * i] = new Point ( (double)(centerX + halfWidth * Math.Cos(theta)), (double)(centerY + halfHeight * Math.Sin(theta)) );
theta += deltaTheta;
pointArray[2 * i + 1] = new Point ( (double)(centerX + halfWidth * Math.Cos(theta) * concaveRadius), (double)(centerY + halfHeight * Math.Sin(theta) * concaveRadius) );
theta += deltaTheta; }
return pointArray; }
#endregion } }
|
------------------------------------------------------------------------------------------------------------------------
'C# > WPF' 카테고리의 다른 글
[C#/WPF] 사면체(Tetrahedron) 사용하기 (0) | 2018.12.31 |
---|---|
[C#/WPF] 설치 폰트 샘플 표시하기 (0) | 2018.12.30 |
[C#/WPF] 색상 리스트 표시하기 (0) | 2018.12.30 |
[C#/WPF] FrameworkElement 클래스 : 이미지 저장하기 (0) | 2018.12.30 |
[C#/WPF] 외곽선 경로 구하기 (0) | 2018.12.30 |
[C#/WPF] 대칭 복합 선 그리기 (0) | 2018.12.30 |
[C#/WPF] WriteableBitmap 클래스 : 비트맵 픽셀 설정하기 (0) | 2018.12.29 |
[C#/WPF] RenderTargetBitmap 클래스 : 텍스트 그리기 (0) | 2018.12.27 |
[C#/WPF] 회전 텍스트 그리기 (0) | 2018.12.27 |
[C#/WPF] 이미지 텍스트 그리기 (0) | 2018.12.26 |
[C#/WPF] 외곽선 텍스트 그리기 (0) | 2018.12.26 |
댓글을 달아 주세요