728x90
반응형
728x170
▶ ICONINFORMATION.cs
using System;
using System.Runtime.InteropServices;
namespace TestProject
{
/// <summary>
/// 아이콘 정보
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct ICONINFORMATION
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Public
////////////////////////////////////////////////////////////////////////////////////////// Field
#region Field
/// <summary>
/// 아이콘 여부
/// </summary>
public bool IsIcon;
/// <summary>
/// 핫스팟 X
/// </summary>
public int hotSpotX;
/// <summary>
/// 핫스팟 Y
/// </summary>
public int hotSpotY;
/// <summary>
/// 마스크 비트맵 핸들
/// </summary>
public IntPtr maskBitmapHandle;
/// <summary>
/// 색상 비트맵 핸들
/// </summary>
public IntPtr colorBitmapHandle;
#endregion
}
}
728x90
▶ ArcPart.cs
namespace TestProject
{
/// <summary>
/// 호 파트
/// </summary>
public enum ArcPart
{
/// <summary>
/// 해당 무
/// </summary>
None,
/// <summary>
/// 시작 포인트
/// </summary>
StartPoint,
/// <summary>
/// 종료 포인트
/// </summary>
EndPoint,
/// <summary>
/// 몸체
/// </summary>
Body,
}
}
300x250
▶ Arc.cs
using System;
using System.Collections.Generic;
using System.Drawing;
namespace TestProject
{
/// <summary>
/// 호
/// </summary>
public class Arc
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Field
////////////////////////////////////////////////////////////////////////////////////////// Public
#region Field
/// <summary>
/// 종단 포인트 배열
/// </summary>
public PointF[] EndPointArray = null;
#endregion
////////////////////////////////////////////////////////////////////////////////////////// Private
#region Field
/// <summary>
/// 경계 사각형
/// </summary>
private RectangleF boundRectangle;
/// <summary>
/// 시작 각도
/// </summary>
private float startAngle;
/// <summary>
/// 스윕 각도
/// </summary>
private float sweepAngle;
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Property
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 경계 사각형 - BoundRectangle
/// <summary>
/// 경계 사각형
/// </summary>
public RectangleF BoundRectangle
{
get
{
return this.boundRectangle;
}
set
{
this.boundRectangle = value;
SetArcEndPoint();
}
}
#endregion
#region 시작 각도 - StartAngle
/// <summary>
/// 시작 각도
/// </summary>
public float StartAngle
{
get
{
return this.startAngle;
}
set
{
this.startAngle = value;
SetArcEndPoint();
}
}
#endregion
#region 스윕 각도 - SweepAngle
/// <summary>
/// 스윕 각도
/// </summary>
public float SweepAngle
{
get
{
return this.sweepAngle;
}
set
{
this.sweepAngle = value;
SetArcEndPoint();
}
}
#endregion
#region 종료 각도 - EndAngle
/// <summary>
/// 종료 각도
/// </summary>
public float EndAngle
{
get
{
return this.startAngle + this.sweepAngle;
}
}
#endregion
#region 중심 포인트 - CenterPoint
/// <summary>
/// 중심 포인트
/// </summary>
public PointF CenterPoint
{
get
{
return new PointF
(
BoundRectangle.X + BoundRectangle.Width / 2,
BoundRectangle.Y + BoundRectangle.Height / 2
);
}
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - Arc(boundRectangle, startAngle, sweepAngle)
/// <summary>
/// 생성자
/// </summary>
/// <param name="boundRectangle">경계 사각형</param>
/// <param name="startAngle">시작 각도</param>
/// <param name="sweepAngle">스윕 각도</param>
public Arc(RectangleF boundRectangle, float startAngle, float sweepAngle)
{
this.boundRectangle = boundRectangle;
this.startAngle = startAngle;
this.sweepAngle = sweepAngle;
if(this.sweepAngle < 0)
{
this.startAngle += this.sweepAngle;
this.sweepAngle = -this.sweepAngle;
}
while(this.startAngle < 0)
{
this.startAngle += 360;
}
while(this.startAngle > 360)
{
this.startAngle -= 360;
}
SetArcEndPoint();
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 그리기 - Draw(graphics, brush, pen)
/// <summary>
/// 그리기
/// </summary>
/// <param name="graphics">그래픽스</param>
/// <param name="brush">브러시</param>
/// <param name="pen">펜</param>
public void Draw(Graphics graphics, Brush brush, Pen pen)
{
if((BoundRectangle.Width == 0) || (BoundRectangle.Height == 0))
{
return;
}
if(brush != null)
{
graphics.FillPie
(
brush,
BoundRectangle.X,
BoundRectangle.Y,
BoundRectangle.Width,
BoundRectangle.Height,
StartAngle,
SweepAngle
);
}
if(pen != null)
{
graphics.DrawArc
(
pen,
BoundRectangle.X,
BoundRectangle.Y,
BoundRectangle.Width,
BoundRectangle.Height,
StartAngle,
SweepAngle
);
}
}
#endregion
#region 종단 포인트 그리기 - DrawEndPoint(graphics, brush, pen, radius)
/// <summary>
/// 종단 포인트 그리기
/// </summary>
/// <param name="graphics">그래픽스</param>
/// <param name="brush">브러시</param>
/// <param name="pen">펜</param>
/// <param name="radius">반경</param>
public void DrawEndPoint(Graphics graphics, Brush brush, Pen pen, float radius)
{
for(int i = 0; i < 2; i++)
{
RectangleF rectangle = new RectangleF
(
EndPointArray[i].X - radius,
EndPointArray[i].Y - radius,
2 * radius,
2 * radius
);
if(brush != null)
{
graphics.FillRectangle(brush, rectangle);
}
if(pen != null)
{
graphics.DrawRectangle(pen, rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height);
}
}
}
#endregion
#region 호 파트 구하기 - GetArcPart(target, radius)
/// <summary>
/// 호 파트 구하기
/// </summary>
/// <param name="targetPoint">타겟 포인트</param>
/// <param name="radius">반경</param>
/// <returns>호 파트</returns>
public ArcPart GetArcPart(Point targetPoint, float radius)
{
if(GetDistance(targetPoint, EndPointArray[0]) < radius)
{
return ArcPart.StartPoint;
}
if(GetDistance(targetPoint, EndPointArray[1]) < radius)
{
return ArcPart.EndPoint;
}
PointF centerPoint = CenterPoint;
float deltaX = targetPoint.X - centerPoint.X;
float deltaY = targetPoint.Y - centerPoint.Y;
float radian = (float)Math.Atan2(deltaY, deltaX);
float degree = (float)(radian * 180 / Math.PI);
while(degree < 0)
{
degree += 360;
}
if((degree < StartAngle) || (degree > StartAngle + SweepAngle))
{
return ArcPart.None;
}
PointF[] intersectionPointArray = FindEllipseSegmentIntersectionPointArray
(
BoundRectangle,
centerPoint,
targetPoint,
false
);
for(int i = 0; i < intersectionPointArray.Length; i++)
{
if(GetDistance(targetPoint, intersectionPointArray[i]) < radius)
{
return ArcPart.Body;
}
}
return ArcPart.None;
}
#endregion
#region 이동하기 - Move(deltaX, deltaY)
/// <summary>
/// 이동하기
/// </summary>
/// <param name="deltaX">델타 X</param>
/// <param name="deltaY">델타 Y</param>
public void Move(int deltaX, int deltaY)
{
BoundRectangle = new RectangleF
(
BoundRectangle.X + deltaX,
BoundRectangle.Y + deltaY,
BoundRectangle.Width,
BoundRectangle.Height
);
}
#endregion
#region 시작 포인트 이동하기 - MoveStartPoint(point)
/// <summary>
/// 시작 포인트 이동하기
/// </summary>
/// <param name="point">포인트</param>
public void MoveStartPoint(PointF point)
{
PointF centerPoint = CenterPoint;
float deltaX = point.X - centerPoint.X;
float deltaY = point.Y - centerPoint.Y;
if((deltaX == 0) && (deltaY == 0))
{
return;
}
float startAngle = (float)(Math.Atan2(deltaY, deltaX) * 180 / Math.PI);
if(startAngle < 0)
{
startAngle += 360;
}
float endAngle = StartAngle + SweepAngle;
while(endAngle < startAngle)
{
endAngle += 360;
}
while(endAngle > startAngle + 360)
{
endAngle -= 360;
}
float sweepAngle = endAngle - startAngle;
StartAngle = startAngle;
SweepAngle = sweepAngle;
}
#endregion
#region 종료 포인트 이동하기 - MoveEndPoint(point)
/// <summary>
/// 종료 포인트 이동하기
/// </summary>
/// <param name="point">포인트</param>
public void MoveEndPoint(PointF point)
{
PointF centerPoint = CenterPoint;
float deltaX = point.X - centerPoint.X;
float deltaY = point.Y - centerPoint.Y;
if((deltaX == 0) && (deltaY == 0))
{
return;
}
float endAngle = (float)(Math.Atan2(deltaY, deltaX) * 180 / Math.PI);
while(endAngle < StartAngle)
{
endAngle += 360;
}
while(endAngle > StartAngle + 360)
{
endAngle -= 360;
}
SweepAngle = endAngle - StartAngle;
}
#endregion
////////////////////////////////////////////////////////////////////////////////////////// Private
#region 거리 구하기 - GetDistance(point1, point2)
/// <summary>
/// 거리 구하기
/// </summary>
/// <param name="point1">포인트 1</param>
/// <param name="point2">포인트 2</param>
/// <returns>거리 구하기</returns>
private float GetDistance(PointF point1, PointF point2)
{
float deltaX = point1.X - point2.X;
float deltaY = point1.Y - point2.Y;
return (float)Math.Sqrt(deltaX * deltaX + deltaY * deltaY);
}
#endregion
#region 타원 세그먼트 교차 포인트 배열 구하기 - FindEllipseSegmentIntersectionPointArray(rectangle, point1, point2, segmentonly)
/// <summary>
/// 타원 세그먼트 교차 포인트 배열 구하기
/// </summary>
/// <param name="rectangle">사각형</param>
/// <param name="point1">포인트 1</param>
/// <param name="point2">포인트 2</param>
/// <param name="segmentonly">세그먼트 전용 여부</param>
/// <returns>타원 세그먼트 교차 포인트 배열</returns>
private static PointF[] FindEllipseSegmentIntersectionPointArray
(
RectangleF rectangle,
PointF point1,
PointF point2,
bool segmentonly
)
{
if((rectangle.Width == 0) || (rectangle.Height == 0) || ((point1.X == point2.X) && (point1.Y == point2.Y)))
{
return new PointF[] { };
}
if(rectangle.Width < 0)
{
rectangle.X = rectangle.Right;
rectangle.Width = -rectangle.Width;
}
if(rectangle.Height < 0)
{
rectangle.Y = rectangle.Bottom;
rectangle.Height = -rectangle.Height;
}
float centerX = rectangle.Left + rectangle.Width / 2f;
float centerY = rectangle.Top + rectangle.Height / 2f;
rectangle.X -= centerX;
rectangle.Y -= centerY;
point1.X -= centerX;
point1.Y -= centerY;
point2.X -= centerX;
point2.Y -= centerY;
float a = rectangle.Width / 2;
float b = rectangle.Height / 2;
float A = (point2.X - point1.X) * (point2.X - point1.X) / a / a + (point2.Y - point1.Y) * (point2.Y - point1.Y) / b / b;
float B = 2 * point1.X * (point2.X - point1.X) / a / a + 2 * point1.Y * (point2.Y - point1.Y) / b / b;
float C = point1.X * point1.X / a / a + point1.Y * point1.Y / b / b - 1;
List<float> valueList = new List<float>();
float discriminant = B * B - 4 * A * C;
if(discriminant == 0)
{
valueList.Add(-B / 2 / A);
}
else if(discriminant > 0)
{
valueList.Add((float)((-B + Math.Sqrt(discriminant)) / 2 / A));
valueList.Add((float)((-B - Math.Sqrt(discriminant)) / 2 / A));
}
List<PointF> pointList = new List<PointF>();
foreach(float value in valueList)
{
if(!segmentonly || ((value >= 0f) && (value <= 1f)))
{
float x = point1.X + (point2.X - point1.X) * value + centerX;
float y = point1.Y + (point2.Y - point1.Y) * value + centerY;
pointList.Add(new PointF(x, y));
}
}
return pointList.ToArray();
}
#endregion
#region 호 종단 포인트 설정하기 - SetArcEndPoint()
/// <summary>
/// 호 종단 포인트 설정하기
/// </summary>
private void SetArcEndPoint()
{
PointF centerPoint = new PointF
(
BoundRectangle.X + BoundRectangle.Width / 2f,
BoundRectangle.Y + BoundRectangle.Height / 2f
);
if((BoundRectangle.Width == 0) || (BoundRectangle.Height == 0))
{
EndPointArray = new PointF[] { centerPoint, centerPoint };
return;
}
double startRadian = StartAngle * Math.PI / 180;
double endRadian = EndAngle * Math.PI / 180;
float distance = BoundRectangle.Width + BoundRectangle.Height;
PointF point1 = new PointF
(
(float)(centerPoint.X + distance * Math.Cos(startRadian)),
(float)(centerPoint.Y + distance * Math.Sin(startRadian))
);
PointF point2 = new PointF
(
(float)(centerPoint.X + distance * Math.Cos(endRadian)),
(float)(centerPoint.Y + distance * Math.Sin(endRadian))
);
PointF[] intersectionPointArray1 = FindEllipseSegmentIntersectionPointArray
(
BoundRectangle,
centerPoint,
point1,
true
);
PointF[] intersectionPointArray2 = FindEllipseSegmentIntersectionPointArray
(
BoundRectangle,
centerPoint,
point2,
true
);
EndPointArray = new PointF[]
{
intersectionPointArray1[0],
intersectionPointArray2[0]
};
}
#endregion
}
}
▶ MainForm.cs
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace TestProject
{
/// <summary>
/// 메인 폼
/// </summary>
public partial class MainForm : Form
{
//////////////////////////////////////////////////////////////////////////////////////////////////// Field
////////////////////////////////////////////////////////////////////////////////////////// Private
#region 아이콘 정보 구하기 - GetIconInfo(iconHandle, iconInformation)
/// <summary>
/// 아이콘 정보 구하기
/// </summary>
/// <param name="iconHandle">아이콘 핸들</param>
/// <param name="iconInformation">아이콘 정보</param>
/// <returns>처리 결과</returns>
[DllImport("user32.dll")]
private static extern bool GetIconInfo(IntPtr iconHandle, out ICONINFORMATION iconInformation);
#endregion
#region 아이콘 간접 생성하기 - CreateIconIndirect(iconInformation)
/// <summary>
/// 아이콘 간접 생성하기
/// </summary>
/// <param name="iconInformation">아이콘 정보</param>
/// <returns>아이콘 핸들</returns>
[DllImport("user32.dll")]
private static extern IntPtr CreateIconIndirect([In] ref ICONINFORMATION iconInformation);
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Field
////////////////////////////////////////////////////////////////////////////////////////// Private
#region Field
/// <summary>
/// 반경
/// </summary>
private const int RADIUS = 3;
/// <summary>
/// 신규 호
/// </summary>
private Arc newArc = null;
/// <summary>
/// 시작 포인트
/// </summary>
private Point startPoint;
/// <summary>
/// 호 리스트
/// </summary>
private List<Arc> arcList = new List<Arc>();
/// <summary>
/// 마우스 아래 호
/// </summary>
private Arc arcUnderMouse = null;
/// <summary>
/// 마우스 아래 호 파트
/// </summary>
private ArcPart arcPartUnderMouse = ArcPart.None;
/// <summary>
/// 아크 커서
/// </summary>
private Cursor arcCursor;
/// <summary>
/// 마우스 DOWN 여부
/// </summary>
private bool isMouseDown = false;
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
////////////////////////////////////////////////////////////////////////////////////////// Public
#region 생성자 - MainForm()
/// <summary>
/// 생성자
/// </summary>
public MainForm()
{
InitializeComponent();
Load += Form_Load;
this.canvas.MouseMove += canvas_MouseMove;
this.canvas.MouseDown += canvas_MouseDown;
this.canvas.MouseUp += canvas_MouseUp;
this.canvas.Paint += canvas_Paint;
}
#endregion
//////////////////////////////////////////////////////////////////////////////////////////////////// Method
////////////////////////////////////////////////////////////////////////////////////////// Private
//////////////////////////////////////////////////////////////////////////////// Event
#region 폼 로드시 처리하기 - Form_Load(sender, e)
/// <summary>
/// 폼 로드시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void Form_Load(object sender, EventArgs e)
{
Bitmap bitmap = new Bitmap("IMAGE\\arc_cursor.png");
bitmap.MakeTransparent(Color.White);
this.arcCursor = GetCursor(bitmap, 7, 6);
}
#endregion
#region 캔버스 페인트시 처리하기 - canvas_Paint(sender, e)
/// <summary>
/// 캔버스 페인트시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void canvas_Paint(object sender, PaintEventArgs e)
{
e.Graphics.Clear(this.canvas.BackColor);
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
Color color = Color.FromArgb
(
Color.LightBlue.R,
Color.LightBlue.G,
Color.LightBlue.B,
128
);
using(Pen pen = new Pen(color, 5))
{
foreach(Arc arc in this.arcList)
{
arc.Draw(e.Graphics, null, Pens.Black);
}
}
foreach(Arc arc in this.arcList)
{
arc.DrawEndPoint(e.Graphics, Brushes.White, Pens.Black, RADIUS);
}
if(this.newArc != null)
{
using(Pen pen = new Pen(Color.Blue))
{
pen.DashPattern = new float[] { 5, 5 };
this.newArc.Draw(e.Graphics, null, pen);
pen.Color = Color.Green;
e.Graphics.DrawRectangle
(
pen,
this.newArc.BoundRectangle.X,
this.newArc.BoundRectangle.Y,
this.newArc.BoundRectangle.Width,
this.newArc.BoundRectangle.Height
);
}
}
}
#endregion
#region 캔버스 마우스 DOWN 처리하기 - canvas_MouseDown(sender, e)
/// <summary>
/// 캔버스 마우스 DOWN 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void canvas_MouseDown(object sender, MouseEventArgs e)
{
if(this.arcPartUnderMouse == ArcPart.Body)
{
this.startPoint = e.Location;
}
else if(this.arcPartUnderMouse == ArcPart.None)
{
this.startPoint = e.Location;
Rectangle rectangle = new Rectangle(startPoint, new Size(0, 0));
this.newArc = new Arc(rectangle, 270, 90);
}
this.isMouseDown = true;
}
#endregion
#region 캔버스 마우스 이동시 처리하기 - canvas_MouseMove(sender, e)
/// <summary>
/// 캔버스 마우스 이동시 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void canvas_MouseMove(object sender, MouseEventArgs e)
{
if(this.isMouseDown)
{
switch(this.arcPartUnderMouse)
{
case ArcPart.Body :
int deltaX = e.Location.X - this.startPoint.X;
int deltaY = e.Location.Y - this.startPoint.Y;
this.arcUnderMouse.Move(deltaX, deltaY);
this.startPoint = e.Location;
this.canvas.Refresh();
break;
case ArcPart.StartPoint :
this.arcUnderMouse.MoveStartPoint(e.Location);
this.canvas.Refresh();
break;
case ArcPart.EndPoint :
this.arcUnderMouse.MoveEndPoint(e.Location);
this.canvas.Refresh();
break;
case ArcPart.None :
default :
this.newArc.BoundRectangle = GetRectangle(this.startPoint, e.Location);
this.canvas.Refresh();
break;
}
}
else
{
foreach(Arc arc in this.arcList)
{
ArcPart arcPart = arc.GetArcPart(e.Location, RADIUS);
if(arcPart != ArcPart.None)
{
this.arcUnderMouse = arc;
this.arcPartUnderMouse = arcPart;
switch(arcPart)
{
case ArcPart.StartPoint : this.canvas.Cursor = Cursors.Cross; break;
case ArcPart.EndPoint : this.canvas.Cursor = Cursors.Cross; break;
case ArcPart.Body : this.canvas.Cursor = Cursors.SizeAll; break;
}
return;
}
}
this.arcUnderMouse = null;
this.arcPartUnderMouse = ArcPart.None;
this.canvas.Cursor = this.arcCursor;
}
}
#endregion
#region 캔버스 마우스 UP 처리하기 - canvas_MouseUp(sender, e)
/// <summary>
/// 캔버스 마우스 UP 처리하기
/// </summary>
/// <param name="sender">이벤트 발생자</param>
/// <param name="e">이벤트 인자</param>
private void canvas_MouseUp(object sender, MouseEventArgs e)
{
if(this.isMouseDown)
{
if(this.arcPartUnderMouse == ArcPart.None)
{
if((this.newArc.BoundRectangle.Width > 0) && (this.newArc.BoundRectangle.Height > 0))
{
this.arcList.Add(this.newArc);
}
this.newArc = null;
this.canvas.Refresh();
}
this.isMouseDown = false;
}
}
#endregion
//////////////////////////////////////////////////////////////////////////////// Function
#region 커서 구하기 - GetCursor(bitmap, hotSpotX, hotSpotY)
/// <summary>
/// 커서 구하기
/// </summary>
/// <param name="bitmap">비트맵</param>
/// <param name="hotSpotX">핫 스팟 X</param>
/// <param name="hotSpotY">핫 스팟 Y</param>
/// <returns>커서</returns>
private Cursor GetCursor(Bitmap bitmap, int hotSpotX, int hotSpotY)
{
ICONINFORMATION information = new ICONINFORMATION();
IntPtr iconHandle = bitmap.GetHicon();
GetIconInfo(iconHandle, out information);
information.IsIcon = false;
information.hotSpotX = hotSpotX;
information.hotSpotY = hotSpotY;
IntPtr cursorHandle = CreateIconIndirect(ref information);
return new Cursor(cursorHandle);
}
#endregion
#region 사각형 구하기 - GetRectangle(startPoint, endPoint)
/// <summary>
/// 사각형 구하기
/// </summary>
/// <param name="startPoint">시작 포인트</param>
/// <param name="endPoint">종료 포인트</param>
/// <returns>사각형</returns>
private RectangleF GetRectangle(Point startPoint, Point endPoint)
{
return new RectangleF
(
Math.Min(startPoint.X, endPoint.X),
Math.Min(startPoint.Y, endPoint.Y),
Math.Abs(startPoint.X - endPoint.X),
Math.Abs(startPoint.Y - endPoint.Y)
);
}
#endregion
}
}
728x90
반응형
그리드형(광고전용)
'C# > WinForm' 카테고리의 다른 글
[C#/WINFORM] 둥근 모서리 이미지 구하기 (0) | 2020.07.20 |
---|---|
[C#/WINFORM] 워터마크 추가하기 (0) | 2020.07.19 |
[C#/WINFORM] 직선 방향의 가운데 정렬 텍스트 그리기 (0) | 2020.07.19 |
[C#/WINFORM] Bitmap 클래스 : 비트맵 크기 변경하기 (0) | 2020.07.16 |
[C#/WINFORM] ColorMatrix 클래스 : 이미지 불투명도 조정하기 (0) | 2020.07.13 |
[C#/WINFORM] 호(arc) 그리기/이동하기/수정하기 (0) | 2020.07.12 |
[C#/WINFORM] 호(arc) 위의 마우스 위치 여부 구하기 (0) | 2020.07.12 |
[C#/WINFORM] 안티-알리아싱으로 그리는 경우 투명도 사용하기 (0) | 2020.07.11 |
[C#/WINFORM] 이미지 나선 그리기 (0) | 2020.07.10 |
[C#/WINFORM] Graphics 클래스 : DrawCurve 메소드를 사용해 곡선 그리기 (0) | 2020.07.09 |
[C#/WINFORM] 사인(Sine)과 코사인(Cosine)을 사용해 원과 타원 그리기 (0) | 2020.07.09 |
댓글을 달아 주세요