정보

자연스러운 펜툴 만들기 – 1

보통 GDI 등의 라이브러리를 사용하여 그림판 같은 프로그램을 만들면 그린 점을 모두 이어 화면에 출력합니다. 예를 들면 Mouse Move 이벤트로 점을 받을 때마다 이전 점과 현재 점을 DrawLine과 같은 함수로 이어 그리는 것이지요. 가장 좋은 방법은 베지어(Bezier) 곡선을 그리는 방법입니다만, 중간 단계 점이 더 있어야 완성할 수 있는데다, 펜의 두께가 점마다 다르게 하는 것을 구현하려면 직접 구현해야 하므로 이 방법보다 다른 방법을 이용하는 편이 좋을 것이라고 생각했지요.

GDI나 GDI+에는 Polygon을 그리는 방법이 있습니다. 각 점에 일단 원을 그려놓고, 두 원을 이 Polygon으로 이어주면 되지요.

513bfea183a4f09262d9d063e982f1d4

Polygon의 좌표는 첫 번째 원과 두 번째 원을 잇는 두 점의 시작점과 끝점들입니다. 총 네 개의 점이 있지요. 그렇다면, 이 위치를 어떻게 하면 잡을 수 있을까요?

한 원에 두 개의 점이 있는데, 중심점으로부터의 거리는 같습니다. 위치만이 중심점으로부터 얼마나 각도가 틀어졌느냐의 문제인데, sin 함수와 cos 함수를 이용하면 쉽게 구할 수 있습니다. 아래는 예제의 소스 코드의 일부입니다.

PointF [] poly = new PointF [ 4 ]; 
double angle = Math.Atan2 ( lastp.y - p.y, lastp.x - p.x ); 
poly [ 0 ] = new PointF ( lastp.x - ( float ) Math.Sin ( angle ) * lastp.size, lastp.y + ( float ) Math.Cos ( angle ) * lastp.size ); 
poly [ 1 ] = new PointF ( lastp.x + ( float ) Math.Sin ( angle ) * lastp.size, lastp.y - ( float ) Math.Cos ( angle ) * lastp.size ); 
poly [ 2 ] = new PointF ( p.x + ( float ) Math.Sin ( angle ) * p.size, p.y - ( float ) Math.Cos ( angle ) * p.size ); 
poly [ 3 ] = new PointF ( p.x - ( float ) Math.Sin ( angle ) * p.size, p.y + ( float ) Math.Cos ( angle ) * p.size ); 
e.Graphics.FillPolygon ( blackBrush, poly );

폴리곤 정점의 순서는 크게 상관은 없습니다만, 삼각형 두개가 연결된 것을 보고 싶지 않으시다면 순서를 연결되게 하는 것이 좋습니다.

광고

답글 남기기

아래 항목을 채우거나 오른쪽 아이콘 중 하나를 클릭하여 로그 인 하세요:

WordPress.com 로고

WordPress.com의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Google photo

Google의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Twitter 사진

Twitter의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Facebook 사진

Facebook의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

%s에 연결하는 중

This site uses Akismet to reduce spam. Learn how your comment data is processed.