첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
------------------------------------------------------------------------------------------------------------------------------------------------------
728x90
728x170

■ 디지털 시계를 표시하는 방법을 보여준다.

TestProject.zip
다운로드

▶ LEDText.cs

using System;
using System.Collections.Generic;
using System.Drawing;

namespace TestProject
{
    /// <summary>
    /// LED 텍스트
    /// </summary>
    public class LEDText
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Delegate
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region LED 대리자 - LEDDelegate(point)

        /// <summary>
        /// LED 대리자
        /// </summary>
        /// <param name="point">포인트</param>
        /// <returns>포인트 배열</returns>
        private delegate PointF[] LEDDelegate(PointF point);

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region Field

        /// <summary>
        /// 셀 너비
        /// </summary>
        public float CellWidth;

        /// <summary>
        /// 셀 높이
        /// </summary>
        public float CellHeight;

        /// <summary>
        /// LED 두께
        /// </summary>
        public float LEDThickness;

        /// <summary>
        /// 갭
        /// </summary>
        public float Gap;

        /// <summary>
        /// 문자 딕셔너리
        /// </summary>
        public Dictionary<char, bool[]> LetterDictionary = null;

        /// <summary>
        /// LED 대리자 배열
        /// </summary>
        private LEDDelegate[] ledDelegateArray = null;

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - LEDText(cellWidth, cellHeight, ledThickness, gap)

        /// <summary>
        /// 생성자
        /// </summary>
        /// <param name="cellWidth">셀 너비</param>
        /// <param name="cellHeight">셀 높이</param>
        /// <param name="ledThickness">LED 두께</param>
        /// <param name="gap">갭</param>
        public LEDText(float cellWidth, float cellHeight, float ledThickness, float gap)
        {
            CellWidth    = cellWidth;
            CellHeight   = cellHeight;
            LEDThickness = ledThickness;
            Gap          = gap;

            SetLEDDelegateArray();

            SetLetterDictionary();
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 수평 LED 포인트 배열 구하기 - GetHorizontalLEDPointArray(point1, point2)

        /// <summary>
        /// 수평 LED 포인트 배열 구하기
        /// </summary>
        /// <param name="point1">포인트 1</param>
        /// <param name="point2">포인트 2</param>
        /// <returns>수평 LED 포인트 배열</returns>
        public PointF[] GetHorizontalLEDPointArray(PointF point1, PointF point2)
        {
            PointF[] pointArray =
            {
                new PointF(point1.X                    , point1.Y                    ),
                new PointF(point1.X + LEDThickness / 2f, point1.Y + LEDThickness / 2f),
                new PointF(point2.X - LEDThickness / 2f, point2.Y + LEDThickness / 2f),
                new PointF(point2.X                    , point2.Y                    ),
                new PointF(point2.X - LEDThickness / 2f, point2.Y - LEDThickness / 2f),
                new PointF(point1.X + LEDThickness / 2f, point1.Y - LEDThickness / 2f),
            };

            return pointArray;
        }

        #endregion
        #region 수직 LED 포인트 배열 구하기 - GetVerticalLEDPointArray(point1, point2)

        /// <summary>
        /// 수직 LED 포인트 배열 구하기
        /// </summary>
        /// <param name="point1">포인트 1</param>
        /// <param name="point2">포인트 2</param>
        /// <returns>수직 LED 포인트 배열</returns>
        public PointF[] GetVerticalLEDPointArray(PointF point1, PointF point2)
        {
            PointF[] pointArray =
            {
                new PointF(point1.X                    , point1.Y                    ),
                new PointF(point1.X + LEDThickness / 2f, point1.Y + LEDThickness / 2f),
                new PointF(point2.X + LEDThickness / 2f, point2.Y - LEDThickness / 2f),
                new PointF(point2.X                    , point2.Y                    ),
                new PointF(point2.X - LEDThickness / 2f, point2.Y - LEDThickness / 2f),
                new PointF(point1.X - LEDThickness / 2f, point1.Y + LEDThickness / 2f)
            };

            return pointArray;
        }

        #endregion
        #region 수직 상단 중앙 LED 포인트 배열 구하기 - GetVerticalTopCenterLEDPointArray(point1, point2)

        /// <summary>
        /// 수직 상단 중앙 LED 포인트 배열 구하기
        /// </summary>
        /// <param name="point1">포인트 1</param>
        /// <param name="point2">포인트 2</param>
        /// <returns>수직 상단 중앙 LED 포인트 배열</returns>
        public PointF[] GetVerticalTopCenterLEDPointArray(PointF point1, PointF point2)
        {
            PointF[] pointArray =
            {
                new PointF(point1.X - LEDThickness / 2f, point1.Y                    ),
                new PointF(point1.X + LEDThickness / 2f, point1.Y                    ),
                new PointF(point2.X + LEDThickness / 2f, point2.Y - LEDThickness / 2f),
                new PointF(point2.X                    , point2.Y                    ),
                new PointF(point1.X - LEDThickness / 2f, point2.Y - LEDThickness / 2f),
            };

            return pointArray;
        }

        #endregion
        #region 수직 하단 중앙 LED 포인트 배열 구하기 - GetVerticalBottomCenterLEDPointArray(point1, point2)

        /// <summary>
        /// 수직 하단 중앙 LED 포인트 배열 구하기
        /// </summary>
        /// <param name="point1">포인트 1</param>
        /// <param name="point2">포인트 2</param>
        /// <returns>수직 하단 중앙 LED 포인트 배열</returns>
        public PointF[] GetVerticalBottomCenterLEDPointArray(PointF point1, PointF point2)
        {
            PointF[] pointArray =
            {
                new PointF(point1.X                    , point1.Y                    ),
                new PointF(point1.X + LEDThickness / 2f, point1.Y + LEDThickness / 2f),
                new PointF(point2.X + LEDThickness / 2f, point2.Y                    ),
                new PointF(point2.X - LEDThickness / 2f, point2.Y                    ),
                new PointF(point1.X - LEDThickness / 2f, point1.Y + LEDThickness / 2f)
            };

            return pointArray;
        }

        #endregion
        #region 교차 LED 포인트 배열 구하기 - GetIntersectionLEDPointArray(point1, point2)

        /// <summary>
        /// 교차 LED 포인트 배열 구하기
        /// </summary>
        /// <param name="point1">포인트 1</param>
        /// <param name="point2">포인트 2</param>
        /// <returns>교차 LED 포인트 배열</returns>
        public PointF[] GetIntersectionLEDPointArray(PointF[][] segmentArray)
        {
            List<PointF> pointList = new List<PointF>();

            foreach(PointF[] segment in segmentArray)
            {
                PointF point1 = segment[0];
                PointF point2 = segment[1];
                PointF point3 = segment[2];
                PointF point4 = segment[3];

                bool   lineIntersect;
                bool   segmentIntersect;
                PointF intersectionPoint;
                PointF closePoint1;
                PointF closePoint2;

                FindIntersection
                (
                    point1,
                    point2,
                    point3,
                    point4,
                    out lineIntersect,
                    out segmentIntersect,
                    out intersectionPoint,
                    out closePoint1,
                    out closePoint2
                );

                pointList.Add(intersectionPoint);
            }

            return pointList.ToArray();
        }

        #endregion

        #region LED 00 포인트 배열 구하기 - GetLED00PointArray(position)

        /// <summary>
        /// LED 00 포인트 배열 구하기
        /// </summary>
        /// <param name="position">위치</param>
        /// <returns>LED 00 포인트 배열</returns>
        public PointF[] GetLED00PointArray(PointF position)
        {
            PointF point1 = new PointF
            (
                position.X + LEDThickness / 2f + Gap,
                position.Y + LEDThickness / 2f
            );

            PointF point2 = new PointF
            (
                position.X + CellWidth - LEDThickness / 2f - Gap,
                point1.Y
            );

            return GetHorizontalLEDPointArray(point1, point2);
        }

        #endregion
        #region LED 01 포인트 배열 구하기 - GetLED01PointArray(position)

        /// <summary>
        /// LED 01 포인트 배열 구하기
        /// </summary>
        /// <param name="position">위치</param>
        /// <returns>LED 01 포인트 배열</returns>
        public PointF[] GetLED01PointArray(PointF position)
        {
            PointF point1 = new PointF
            (
                position.X + LEDThickness / 2f,
                position.Y + LEDThickness / 2f + Gap
            );

            PointF point2 = new PointF
            (
                point1.X,
                position.Y + CellHeight / 2f - Gap
            );

            return GetVerticalLEDPointArray(point1, point2);
        }

        #endregion
        #region LED 02 포인트 배열 구하기 - GetLED02PointArray(position)

        /// <summary>
        /// LED 02 포인트 배열 구하기
        /// </summary>
        /// <param name="position">위치</param>
        /// <returns>LED 02 포인트 배열</returns>
        public PointF[] GetLED02PointArray(PointF position)
        {
            float squareRoot2 = (float)Math.Sqrt(2.0);
            float deltaX      = LEDThickness / squareRoot2;
            float deltaY      = deltaX;

            PointF point01 = new PointF
            (
                position.X + deltaX,
                position.Y
            );

            PointF point02 = new PointF
            (
                position.X + CellWidth,
                position.Y + CellHeight - deltaY
            );

            PointF point03 = new PointF
            (
                position.X,
                position.Y + deltaY
            );

            PointF point04 = new PointF
            (
                position.X + CellWidth - deltaX,
                position.Y + CellHeight
            );

            PointF point05 = new PointF
            (
                position.X,
                position.Y + LEDThickness + Gap
            );

            PointF point06 = new PointF
            (
                position.X + CellWidth,
                position.Y + LEDThickness + Gap
            );

            PointF point07 = new PointF
            (
                position.X,
                position.Y + CellHeight / 2f - LEDThickness / 2f - Gap
            );

            PointF point08 = new PointF
            (
                position.X + CellWidth,
                position.Y + CellHeight / 2f - LEDThickness / 2f - Gap
            );

            PointF point09 = new PointF
            (
                position.X + LEDThickness + Gap,
                position.Y
            );

            PointF point10 = new PointF
            (
                position.X + LEDThickness + Gap,
                position.Y + CellHeight
            );

            PointF point11 = new PointF
            (
                position.X + CellWidth / 2f - LEDThickness / 2f - Gap,
                position.Y
            );

            PointF point12 = new PointF
            (
                position.X + CellWidth / 2f - LEDThickness / 2f - Gap,
                position.Y + CellHeight
            );

            PointF[][] segmentArray =
            {
                new PointF[] { point09, point10, point05, point06 },
                new PointF[] { point05, point06, point01, point02 },
                new PointF[] { point01, point02, point11, point12 },
                new PointF[] { point11, point12, point07, point08 },
                new PointF[] { point07, point08, point03, point04 },
                new PointF[] { point03, point04, point09, point10 }
            };

            return GetIntersectionLEDPointArray(segmentArray);
        }

        #endregion
        #region LED 03 포인트 배열 구하기 - GetLED03PointArray(position)

        /// <summary>
        /// LED 03 포인트 배열 구하기
        /// </summary>
        /// <param name="position">위치</param>
        /// <returns>LED 03 포인트 배열</returns>
        public PointF[] GetLED03PointArray(PointF position)
        {
            PointF point1 = new PointF
            (
                position.X + CellWidth / 2f,
                position.Y + LEDThickness + Gap
            );

            PointF point2 = new PointF
            (
                point1.X,
                position.Y + CellHeight / 2f - Gap
            );

            return GetVerticalTopCenterLEDPointArray(point1, point2);
        }

        #endregion
        #region LED 04 포인트 배열 구하기 - GetLED04PointArray(position)

        /// <summary>
        /// LED 04 포인트 배열 구하기
        /// </summary>
        /// <param name="position">위치</param>
        /// <returns>LED 04 포인트 배열</returns>
        public PointF[] GetLED04PointArray(PointF position)
        {
            float squareRoot2 = (float)Math.Sqrt(2.0);
            float deltaX      = LEDThickness / squareRoot2;
            float deltaY      = deltaX;

            PointF point01 = new PointF
            (
                position.X + CellWidth - deltaX,
                position.Y
            );

            PointF point02 = new PointF
            (
                position.X,
                position.Y + CellHeight - deltaY
            );

            PointF point03 = new PointF
            (
                position.X + CellWidth,
                position.Y + deltaY
            );

            PointF point04 = new PointF
            (
                position.X + deltaX,
                position.Y + CellHeight
            );

            PointF point05 = new PointF
            (
                position.X,
                position.Y + LEDThickness + Gap
            );

            PointF point06 = new PointF
            (
                position.X + CellWidth,
                position.Y + LEDThickness + Gap
            );

            PointF point07 = new PointF
            (
                position.X,
                position.Y + CellHeight / 2f - LEDThickness / 2f - Gap
            );

            PointF point08 = new PointF
            (
                position.X + CellWidth,
                position.Y + CellHeight / 2f - LEDThickness / 2f - Gap
            );

            PointF point09 = new PointF
            (
                position.X + CellWidth / 2f + LEDThickness / 2f + Gap,
                position.Y
            );

            PointF point10 = new PointF
            (
                position.X + CellWidth / 2f + LEDThickness / 2f + Gap,
                position.Y + CellHeight
            );

            PointF point11 = new PointF
            (
                position.X + CellWidth - LEDThickness - Gap,
                position.Y
            );

            PointF point12 = new PointF
            (
                position.X + CellWidth - LEDThickness - Gap,
                position.Y + CellHeight
            );

            PointF[][] segmentArray =
            {
                new PointF[] { point05, point06, point11, point12 },
                new PointF[] { point11, point12, point03, point04 },
                new PointF[] { point03, point04, point07, point08 },
                new PointF[] { point07, point08, point09, point10 },
                new PointF[] { point09, point10, point01, point02 },
                new PointF[] { point01, point02, point05, point06 }
            };

            return GetIntersectionLEDPointArray(segmentArray);
        }

        #endregion
        #region LED 05 포인트 배열 구하기 - GetLED05PointArray(position)

        /// <summary>
        /// LED 05 포인트 배열 구하기
        /// </summary>
        /// <param name="position">위치</param>
        /// <returns>LED 05 포인트 배열</returns>
        public PointF[] GetLED05PointArray(PointF position)
        {
            PointF point1 = new PointF
            (
                position.X + CellWidth - LEDThickness / 2f,
                position.Y + LEDThickness / 2f + Gap
            );

            PointF point2 = new PointF
            (
                point1.X,
                position.Y + CellHeight / 2f - Gap
            );

            return GetVerticalLEDPointArray(point1, point2);
        }

        #endregion
        #region LED 06 포인트 배열 구하기 - GetLED06PointArray(position)

        /// <summary>
        /// LED 06 포인트 배열 구하기
        /// </summary>
        /// <param name="position">위치</param>
        /// <returns>LED 06 포인트 배열</returns>
        public PointF[] GetLED06PointArray(PointF position)
        {
            PointF point1 = new PointF
            (
                position.X + LEDThickness / 2f + Gap,
                position.Y + CellHeight / 2f
            );

            PointF point2 = new PointF
            (
                position.X + CellWidth / 2f - Gap,
                point1.Y
            );

            return GetHorizontalLEDPointArray(point1, point2);
        }

        #endregion
        #region LED 07 포인트 배열 구하기 - GetLED07PointArray(position)

        /// <summary>
        /// LED 07 포인트 배열 구하기
        /// </summary>
        /// <param name="position">위치</param>
        /// <returns>LED 07 포인트 배열</returns>
        public PointF[] GetLED07PointArray(PointF position)
        {
            PointF point1 = new PointF
            (
                position.X + CellWidth / 2f + Gap,
                position.Y + CellHeight / 2f
            );

            PointF p2 = new PointF
            (
                position.X + CellWidth - LEDThickness / 2f - Gap,
                point1.Y
            );

            return GetHorizontalLEDPointArray(point1, p2);
        }

        #endregion
        #region LED 08 포인트 배열 구하기 - GetLED08PointArray(position)

        /// <summary>
        /// LED 08 포인트 배열 구하기
        /// </summary>
        /// <param name="position">위치</param>
        /// <returns>LED 08 포인트 배열</returns>
        public PointF[] GetLED08PointArray(PointF position)
        {
            PointF point1 = new PointF
            (
                position.X + LEDThickness / 2f,
                position.Y + CellHeight / 2f + Gap
            );

            PointF point2 = new PointF
            (
                point1.X,
                position.Y + CellHeight - LEDThickness / 2f - Gap
            );

            return GetVerticalLEDPointArray(point1, point2);
        }

        #endregion
        #region LED 09 포인트 배열 구하기 - GetLED09PointArray(position)

        /// <summary>
        /// LED 09 포인트 배열 구하기
        /// </summary>
        /// <param name="position">위치</param>
        /// <returns>LED 09 포인트 배열</returns>
        public PointF[] GetLED09PointArray(PointF position)
        {
            float squareRoot2 = (float)Math.Sqrt(2.0);
            float deltaX      = LEDThickness / squareRoot2;
            float deltaY      = deltaX;

            PointF point01 = new PointF
            (
                position.X,
                position.Y + CellHeight - deltaY
            );

            PointF point02 = new PointF
            (
                position.X + CellWidth - deltaX,
                position.Y
            );

            PointF point03 = new PointF
            (
                position.X + deltaX,
                position.Y + CellHeight
            );

            PointF point04 = new PointF
            (
                position.X + CellWidth,
                position.Y + deltaY
            );

            PointF point05 = new PointF
            (
                position.X,
                position.Y + CellHeight / 2f + LEDThickness / 2f + Gap
            );

            PointF point06 = new PointF
            (
                position.X + CellWidth,
                position.Y + CellHeight / 2f + LEDThickness / 2f + Gap
            );

            PointF point07 = new PointF
            (
                position.X,
                position.Y + CellHeight - LEDThickness - Gap
            );

            PointF point08 = new PointF
            (
                position.X + CellWidth,
                position.Y + CellHeight - LEDThickness - Gap
            );

            PointF point09 = new PointF
            (
                position.X + LEDThickness + Gap,
                position.Y
            );

            PointF point10 = new PointF
            (
                position.X + LEDThickness + Gap,
                position.Y + CellHeight
            );

            PointF point11 = new PointF
            (
                position.X + CellWidth / 2f - LEDThickness / 2f - Gap,
                position.Y
            );

            PointF point12 = new PointF
            (
                position.X + CellWidth / 2f - LEDThickness / 2f - Gap,
                position.Y + CellHeight
            );

            PointF[][] segmentArray =
            {
                new PointF[] { point05, point06, point11, point12 },
                new PointF[] { point11, point12, point03, point04 },
                new PointF[] { point03, point04, point07, point08 },
                new PointF[] { point07, point08, point09, point10 },
                new PointF[] { point09, point10, point01, point02 },
                new PointF[] { point01, point02, point05, point06 }
            };

            return GetIntersectionLEDPointArray(segmentArray);
        }

        #endregion
        #region LED 10 포인트 배열 구하기 - GetLED10PointArray(position)

        /// <summary>
        /// LED 10 포인트 배열 구하기
        /// </summary>
        /// <param name="position">위치</param>
        /// <returns>LED 10 포인트 배열</returns>
        public PointF[] GetLED10PointArray(PointF position)
        {
            PointF point1 = new PointF
            (
                position.X + CellWidth / 2f,
                position.Y + CellHeight / 2f + Gap
            );

            PointF point2 = new PointF
            (
                point1.X,
                position.Y + CellHeight - LEDThickness - Gap
            );

            return GetVerticalBottomCenterLEDPointArray(point1, point2);
        }

        #endregion
        #region LED 11 포인트 배열 구하기 - GetLED11PointArray(position)

        /// <summary>
        /// LED 11 포인트 배열 구하기
        /// </summary>
        /// <param name="position">위치</param>
        /// <returns>LED 11 포인트 배열</returns>
        public PointF[] GetLED11PointArray(PointF position)
        {
            float squareRoot2 = (float)Math.Sqrt(2.0);
            float deltaX      = LEDThickness / squareRoot2;
            float deltaY      = deltaX;

            PointF point01 = new PointF
            (
                position.X + deltaX,
                position.Y
            );

            PointF point02 = new PointF
            (
                position.X + CellWidth,
                position.Y + CellHeight - deltaY
            );

            PointF point03 = new PointF
            (
                position.X,
                position.Y + deltaY
            );

            PointF point04 = new PointF
            (
                position.X + CellWidth - deltaX,
                position.Y + CellHeight
            );

            PointF point05 = new PointF
            (
                position.X,
                position.Y + CellHeight / 2f + LEDThickness / 2f + Gap
            );

            PointF point06 = new PointF
            (
                position.X + CellWidth,
                position.Y + CellHeight / 2f + LEDThickness / 2f + Gap
            );

            PointF point07 = new PointF
            (
                position.X,
                position.Y + CellHeight - LEDThickness - Gap
            );

            PointF point08 = new PointF
            (
                position.X + CellWidth,
                position.Y + CellHeight - LEDThickness - Gap
            );

            PointF point09 = new PointF
            (
                position.X + CellWidth / 2f + LEDThickness / 2f + Gap,
                position.Y
            );

            PointF point10 = new PointF
            (
                position.X + CellWidth / 2f + LEDThickness / 2f + Gap,
                position.Y + CellHeight
            );

            PointF point11 = new PointF
            (
                position.X + CellWidth - LEDThickness - Gap,
                position.Y
            );

            PointF point12 = new PointF
            (
                position.X + CellWidth - LEDThickness - Gap,
                position.Y + CellHeight
            );

            PointF[][] segmentArray =
            {
                new PointF[] { point09, point10, point05, point06 },
                new PointF[] { point05, point06, point01, point02 },
                new PointF[] { point01, point02, point11, point12 },
                new PointF[] { point11, point12, point07, point08 },
                new PointF[] { point07, point08, point03, point04 },
                new PointF[] { point03, point04, point09, point10 }
            };

            return GetIntersectionLEDPointArray(segmentArray);
        }

        #endregion
        #region LED 12 포인트 배열 구하기 - GetLED12PointArray(position)

        /// <summary>
        /// LED 12 포인트 배열 구하기
        /// </summary>
        /// <param name="position">위치</param>
        /// <returns>LED 12 포인트 배열</returns>
        public PointF[] GetLED12PointArray(PointF position)
        {
            PointF point1 = new PointF
            (
                position.X + CellWidth - LEDThickness / 2f,
                position.Y + CellHeight / 2f + Gap
            );

            PointF point2 = new PointF
            (
                point1.X,
                position.Y + CellHeight - LEDThickness / 2f - Gap
            );

            return GetVerticalLEDPointArray(point1, point2);
        }

        #endregion
        #region LED 13 포인트 배열 구하기 - GetLED13PointArray(position)

        /// <summary>
        /// LED 13 포인트 배열 구하기
        /// </summary>
        /// <param name="position">위치</param>
        /// <returns>LED 13 포인트 배열</returns>
        public PointF[] GetLED13PointArray(PointF position)
        {
            PointF point1 = new PointF
            (
                position.X + LEDThickness / 2f + Gap,
                position.Y + CellHeight - LEDThickness / 2f
            );

            PointF point2 = new PointF
            (
                position.X + CellWidth - LEDThickness / 2f - Gap,
                point1.Y
            );

            return GetHorizontalLEDPointArray(point1, point2);
        }

        #endregion

        #region 콜론 그리기 - DrawColon(graphics, backgroundBrush, usedBrush, usedPen, unusedBrush, unusedPen, position)

        /// <summary>
        /// 콜론 그리기
        /// </summary>
        /// <param name="graphics">그래픽스</param>
        /// <param name="backgroundBrush">배경 브러시</param>
        /// <param name="usedBrush">사용 브러시</param>
        /// <param name="usedPen">사용 펜</param>
        /// <param name="unusedBrush">미사용 브러시</param>
        /// <param name="unusedPen">미사용 펜</param>
        /// <param name="position">위치</param>
        public void DrawColon
        (
            Graphics graphics,
            Brush    backgroundBrush,
            Brush    usedBrush,
            Pen      usedPen,
            Brush    unusedBrush,
            Pen      unusedPen,
            PointF   position
        )
        {
            graphics.FillRectangle
            (
                backgroundBrush,
                position.X,
                position.Y,
                LEDThickness,
                CellHeight
            );

            float y1 = position.Y + CellHeight / 4f;
            float y2 = y1 + CellHeight / 2f;

            RectangleF rectangle1 = new RectangleF
            (
                position.X,
                y1 - LEDThickness / 2f,
                LEDThickness,
                LEDThickness
            );

            graphics.FillRectangle(usedBrush, rectangle1);

            graphics.DrawRectangle(usedPen, rectangle1);

            RectangleF rectangle2 = new RectangleF
            (
                position.X,
                y2 - LEDThickness / 2f,
                LEDThickness,
                LEDThickness
            );

            graphics.FillRectangle(usedBrush, rectangle2);

            graphics.DrawRectangle(usedPen, rectangle2);
        }

        #endregion
        #region 문자 다각형 설정하기 - SetLetterPolygon(letter, position, usedPolygonList, unusedPolygonList)

        /// <summary>
        /// 문자 다각형 설정하기
        /// </summary>
        /// <param name="letter">문자</param>
        /// <param name="position">위치</param>
        /// <param name="usedPolygonList">사용 다각형 리스트</param>
        /// <param name="unusedPolygonList">미사용 다각형 리스트</param>
        public void SetLetterPolygon
        (
            char               letter,
            PointF             position,
            out List<PointF[]> usedPolygonList,
            out List<PointF[]> unusedPolygonList
        )
        {
            usedPolygonList   = new List<PointF[]>();
            unusedPolygonList = new List<PointF[]>();

            bool[] usedArray;

            if(LetterDictionary.ContainsKey(letter))
            {
                usedArray = LetterDictionary[letter];
            }
            else
            {
                usedArray = LetterDictionary[(char)0];
            }

            for(int i = 0; i < usedArray.Length; i++)
            {
                if(usedArray[i])
                {
                    usedPolygonList.Add(ledDelegateArray[i](position));
                }
                else
                {
                    unusedPolygonList.Add(ledDelegateArray[i](position));
                }
            }
        }

        #endregion
        #region 문자 그리기 - DrawLetter(graphics, backgroundBrush, usedBrush, usedPen, unusedBrush, unusedPen, position, letter)

        /// <summary>
        /// 문자 그리기
        /// </summary>
        /// <param name="graphics">그래픽스</param>
        /// <param name="backgroundBrush">배경 브러시</param>
        /// <param name="usedBrush">사용 브러시</param>
        /// <param name="usedPen">사용 펜</param>
        /// <param name="unusedBrush">미사용 브러시</param>
        /// <param name="unusedPen">미사용 펜</param>
        /// <param name="position">위치</param>
        /// <param name="letter">문자</param>
        public void DrawLetter
        (
            Graphics graphics,
            Brush    backgroundBrush,
            Brush    usedBrush,
            Pen      usedPen,
            Brush    unusedBrush,
            Pen      unusedPen,
            PointF   position,
            char     letter
        )
        {
            graphics.FillRectangle
            (
                backgroundBrush,
                position.X,
                position.Y,
                CellWidth,
                CellHeight
            );

            List<PointF[]> usedPolygonList;
            List<PointF[]> unusedPolygonList;

            SetLetterPolygon(letter, position, out usedPolygonList, out unusedPolygonList);

            foreach(PointF[] polygon in unusedPolygonList)
            {
                graphics.FillPolygon(unusedBrush, polygon);

                graphics.DrawPolygon(unusedPen, polygon);
            }

            foreach(PointF[] polygon in usedPolygonList)
            {
                graphics.FillPolygon(usedBrush, polygon);

                graphics.DrawPolygon(usedPen, polygon);
            }
        }

        #endregion
        #region 텍스트 그리기 - DrawText(graphics, backgroundBrush, usedBrush, usedPen, unusedBrush, unusedPen, position, horizontalSpacing, text)

        /// <summary>
        /// 텍스트 그리기
        /// </summary>
        /// <param name="graphics">그래픽스</param>
        /// <param name="backgroundBrush">배경 브러시</param>
        /// <param name="usedBrush">사용 브러시</param>
        /// <param name="usedPen">사용 펜</param>
        /// <param name="unusedBrush">미사용 브러시</param>
        /// <param name="unusedPen">미사용 펜</param>
        /// <param name="position">위치</param>
        /// <param name="horizontalSpacing">수평 간격</param>
        /// <param name="text">텍스트</param>
        public void DrawText
        (
            Graphics graphics,
            Brush    backgroundBrush,
            Brush    usedBrush,
            Pen      usedPen,
            Brush    unusedBrush,
            Pen      unusedPen,
            PointF   position,
            float    horizontalSpacing,
            string   text
        )
        {
            float cellPpace = CellWidth * (horizontalSpacing - 1);

            foreach(char character in text)
            {
                if(character == ':')
                {
                    DrawColon
                    (
                        graphics,
                        backgroundBrush,
                        usedBrush,
                        usedPen,
                        unusedBrush,
                        unusedPen,
                        position
                    );

                    position.X += LEDThickness;
                }
                else
                {
                    DrawLetter
                    (
                        graphics,
                        backgroundBrush,
                        usedBrush,
                        usedPen,
                        unusedBrush,
                        unusedPen,
                        position,
                        character
                    );

                    position.X += CellWidth;
                }

                position.X += cellPpace;
            }
        }

        #endregion

        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region LED 대리자 배열 설정하기 - DefineLedFuncs()

        /// <summary>
        /// LED 대리자 배열 설정하기
        /// </summary>
        private void SetLEDDelegateArray()
        {
            this.ledDelegateArray = new LEDDelegate[]
            {
                GetLED00PointArray,
                GetLED01PointArray,
                GetLED02PointArray,
                GetLED03PointArray,
                GetLED04PointArray,
                GetLED05PointArray,
                GetLED06PointArray,
                GetLED07PointArray,
                GetLED08PointArray,
                GetLED09PointArray,
                GetLED10PointArray,
                GetLED11PointArray,
                GetLED12PointArray,
                GetLED13PointArray,
            };
        }

        #endregion
        #region 문자 딕셔너리 설정하기 - SetLetterDictionary()

        /// <summary>
        /// 문자 딕셔너리 설정하기
        /// </summary>
        private void SetLetterDictionary()
        {
            if(LetterDictionary != null)
            {
                return;
            }

            LetterDictionary = new Dictionary<char, bool[]>();

            LetterDictionary.Add((char)0, GetBooleanArray("11111111111111"));
            LetterDictionary.Add('0'    , GetBooleanArray("11000100100011"));
            LetterDictionary.Add('1'    , GetBooleanArray("00001100000010"));
            LetterDictionary.Add('2'    , GetBooleanArray("10000111100001"));
            LetterDictionary.Add('3'    , GetBooleanArray("10000101000011"));
            LetterDictionary.Add('4'    , GetBooleanArray("01000111000010"));
            LetterDictionary.Add('5'    , GetBooleanArray("11000011000011"));
            LetterDictionary.Add('6'    , GetBooleanArray("11000011100011"));
            LetterDictionary.Add('7'    , GetBooleanArray("10000100000010"));
            LetterDictionary.Add('8'    , GetBooleanArray("11000111100011"));
            LetterDictionary.Add('9'    , GetBooleanArray("11000111000011"));
            LetterDictionary.Add('A'    , GetBooleanArray("11000111100010"));
            LetterDictionary.Add('B'    , GetBooleanArray("10010101001011"));
            LetterDictionary.Add('C'    , GetBooleanArray("11000000100001"));
            LetterDictionary.Add('D'    , GetBooleanArray("10010100001011"));
            LetterDictionary.Add('E'    , GetBooleanArray("11000010100001"));
            LetterDictionary.Add('F'    , GetBooleanArray("11000010100000"));
            LetterDictionary.Add('G'    , GetBooleanArray("11000001100011"));
            LetterDictionary.Add('H'    , GetBooleanArray("01000111100010"));
            LetterDictionary.Add('I'    , GetBooleanArray("10010000001001"));
            LetterDictionary.Add('J'    , GetBooleanArray("00000100100011"));
            LetterDictionary.Add('K'    , GetBooleanArray("01001010100100"));
            LetterDictionary.Add('L'    , GetBooleanArray("01000000100001"));
            LetterDictionary.Add('M'    , GetBooleanArray("01101100100010"));
            LetterDictionary.Add('N'    , GetBooleanArray("01100100100110"));
            LetterDictionary.Add('O'    , GetBooleanArray("11000100100011"));
            LetterDictionary.Add('P'    , GetBooleanArray("11000111100000"));
            LetterDictionary.Add('Q'    , GetBooleanArray("11000100100111"));
            LetterDictionary.Add('R'    , GetBooleanArray("11000111100100"));
            LetterDictionary.Add('S'    , GetBooleanArray("11000011000011"));
            LetterDictionary.Add('T'    , GetBooleanArray("10010000001000"));
            LetterDictionary.Add('U'    , GetBooleanArray("01000100100011"));
            LetterDictionary.Add('V'    , GetBooleanArray("01001000110000"));
            LetterDictionary.Add('W'    , GetBooleanArray("01000100110110"));
            LetterDictionary.Add('X'    , GetBooleanArray("00101000010100"));
            LetterDictionary.Add('Y'    , GetBooleanArray("00101000001000"));
            LetterDictionary.Add('Z'    , GetBooleanArray("10001000010001"));
            LetterDictionary.Add('/'    , GetBooleanArray("00001000010000"));
            LetterDictionary.Add(' '    , GetBooleanArray("00000000000000"));
        }

        #endregion
        #region 진리값 배열 구하기 - GetBooleanArray(source)

        /// <summary>
        /// 진리값 배열 구하기
        /// </summary>
        /// <param name="source">소스 문자열</param>
        /// <returns>진리값 배열</returns>
        private bool[] GetBooleanArray(string source)
        {
            bool[] resultArray = new bool[source.Length];

            for(int i = 0; i < source.Length; i++)
            {
                resultArray[i] = (source[i] == '1');
            }

            return resultArray;
        }

        #endregion
        #region 교차 찾기 - FindIntersection(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">포인트 4</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 FindIntersection
        (
            PointF     point1,
            PointF     point2,
            PointF     point3,
            PointF     point4,
            out bool   lineIntersect,
            out bool   segmentIntersect,
            out PointF intersectionPoint,
            out PointF closePoint1,
            out PointF closePoint2
        )
        {
            float deltaX12 = point2.X - point1.X;
            float deltaY12 = point2.Y - point1.Y;
            float deltaX34 = point4.X - point3.X;
            float deltaY34 = point4.Y - point3.Y;

            float denominator = (deltaY12 * deltaX34 - deltaX12 * deltaY34);

            float temporary1 = ((point1.X - point3.X) * deltaY34 + (point3.Y - point1.Y) * deltaX34) / denominator;

            if(float.IsInfinity(temporary1))
            {
                lineIntersect     = false;
                segmentIntersect  = false;
                intersectionPoint = new PointF(float.NaN, float.NaN);
                closePoint1       = new PointF(float.NaN, float.NaN);
                closePoint2       = new PointF(float.NaN, float.NaN);

                return;
            }

            lineIntersect = true;

            float temporary2 = ((point3.X - point1.X) * deltaY12 + (point1.Y - point3.Y) * deltaX12) / -denominator;

            intersectionPoint = new PointF(point1.X + deltaX12 * temporary1, point1.Y + deltaY12 * temporary1);

            segmentIntersect = ((temporary1 >= 0) && (temporary1 <= 1) && (temporary2 >= 0) && (temporary2 <= 1));

            if(temporary1 < 0)
            {
                temporary1 = 0;
            }
            else if(temporary1 > 1)
            {
                temporary1 = 1;
            }

            if(temporary2 < 0)
            {
                temporary2 = 0;
            }
            else if(temporary2 > 1)
            {
                temporary2 = 1;
            }

            closePoint1 = new PointF(point1.X + deltaX12 * temporary1, point1.Y + deltaY12 * temporary1);
            closePoint2 = new PointF(point3.X + deltaX34 * temporary2, point3.Y + deltaY34 * temporary2);
        }

        #endregion
    }
}

 

▶ MainForm.cs

using System;
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>
        /// 시간 LED 텍스트
        /// </summary>
        private LEDText timeLedText;

        /// <summary>
        /// 날짜 LED 텍스트
        /// </summary>
        private LEDText dateLedText;

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - MainForm()

        /// <summary>
        /// 생성자
        /// </summary>
        public MainForm()
        {
            InitializeComponent();

            Load                  += Form_Load;
            this.pictureBox.Paint += pictureBox_Paint;
            this.timer.Tick       += timer_Tick;
        }

        #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)
        {
            const float cellWidth    = 50;
            const float cellHeight   = 80;
            const float ledThickness = 7;
            const float gap          = 1.5f;

            this.timeLedText = new LEDText(cellWidth, cellHeight, ledThickness, gap);

            const float scale = 0.95f;

            this.dateLedText = new LEDText
            (
                scale * cellWidth,
                scale * cellHeight,
                scale * ledThickness,
                scale * gap
            );
        }

        #endregion
        #region 픽처 박스 페인트시 처리하기 - pictureBox_Paint(sender, e)

        /// <summary>
        /// 픽처 박스 페인트시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void pictureBox_Paint(object sender, PaintEventArgs e)
        {
            ShowTime(e.Graphics);
        }

        #endregion
        #region 타이머 틱 처리하기 - timer_Tick(sender, e)

        /// <summary>
        /// 타이머 틱 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void timer_Tick(object sender, EventArgs e)
        {
            this.pictureBox.Refresh();
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////// Function

        #region 시간 표시하기 - ShowTime(graphics)

        /// <summary>
        /// 시간 표시하기
        /// </summary>
        /// <param name="graphics">그래픽스</param>
        private void ShowTime(Graphics graphics)
        {
            graphics.Clear(Color.Black);

            graphics.SmoothingMode = SmoothingMode.AntiAlias;

            const float margin = 5f;

            PointF position = new PointF(margin, margin);

            using(Brush unusedBrush = new SolidBrush(Color.FromArgb(0, 40, 0)))
            {
                Brush backgroundBrush = Brushes.Black;
                Brush usedBrush       = Brushes.Lime;
                Pen   usedPen         = Pens.Transparent;
                Pen   unusedPen       = Pens.Transparent;

                DateTime currentTime = DateTime.Now;

                string time;

                if(currentTime.Hour > 12)
                {
                    time = DateTime.Now.ToString("hh:mm:ss") + " PM";
                }
                else
                {
                    time = DateTime.Now.ToString("hh:mm:ss") + " AM";
                }

                this.timeLedText.DrawText
                (
                    graphics,
                    backgroundBrush,
                    usedBrush,
                    usedPen,
                    unusedBrush,
                    unusedPen,
                    position,
                    1.2f,
                    time
                );
            }

            using(Brush unusedBrush = new SolidBrush(Color.FromArgb(0, 0, 60)))
            {
                Brush backgroundBrush = Brushes.Black;
                Brush usedBrush       = Brushes.Blue;
                Pen   usedPen         = Pens.Transparent;
                Pen   unusedPen       = Pens.Transparent;

                position.Y += this.timeLedText.CellHeight + 4 * this.timeLedText.LEDThickness;

                string date = DateTime.Now.DayOfWeek.ToString();

                date = date.ToUpper().Substring(0, 3);
                date += " "                               +
                        DateTime.Now.Day.ToString() + "/" +
                        DateTime.Now.Year.ToString().Substring(0, 2);

                this.dateLedText.DrawText
                (
                    graphics,
                    backgroundBrush,
                    usedBrush,
                    usedPen,
                    unusedBrush,
                    unusedPen,
                    position,
                    1.2f,
                    date
                );
            }
        }

        #endregion
    }
}
728x90
그리드형(광고전용)
Posted by icodebroker
,