프로젝트/C# Wafer 코팅 시뮬

3. 라이브러리 만들기 [Wafer 코팅 시뮬레이션]

언휴 2024. 1. 10. 15:04

유튜브 동영상 강의

Wafer 코팅 시뮬레이션 - 라이브러리 만들기

안녕하세요. 언제나휴일입니다.

1. 해야 할 일

Wafer 클래스를 정의하고 Double Buffering 가능한 DPanel을 정의했습니다.

그리고 Wafer의 코팅 상태를 시각화하는 부분을 작성했습니다.

Wafer 코팅 시뮬레이션에서 Wafer 클래스는 WaferLineLib에 정의할 것입니다.

그리고 DPanel과 Waper를 시각화하는 WaferPanel은 WaferLineControlLib에 정의할 것입니다.

이번에는 WaferLineLib와 WaferLineControlLib를 만드는 실습을 할 거예요.

물론 앞에서 만든 Wafer 클래스를 WaferLineLib에 추가하고 DPanel과 Panel을 시각화하는 부분을 WaferPanel 클래스로 정의하여 WaferLineControlLib에 추가하는 것이죠.

[그림] Wafer 라이브러리 컴포넌트 다이어그램
[그림] Wafer 라이브러리 컴포넌트 다이어그램

2. Wafer 소스 코드

namespace WaferLineLib
{
    /// <summary>
    /// Wafer 클래스
    /// </summary>
    public class Wafer
    {
        static int last_wn;
        readonly int wn;
        int[] cells = new int[100];
        int now;
        /// <summary>
        /// 기본 생성자
        /// </summary>
        public Wafer()
        {
            last_wn++;
            wn = last_wn;
        }
        /// <summary>
        /// 현재 코팅할 쉘 번호 - 가져오기
        /// </summary>
        public int Now
        {
            get
            {
                return now;
            }
        }
        /// <summary>
        /// 코팅할 쉘 번호 증가시키기
        /// </summary>
        /// <returns>증가 성공 여부</returns>
        public bool Increment()
        {
            if (now < 100)
            {
                now++;
                if (now == 100)
                {
                    return false;
                }
                return true;
            }
            return false;
        }
        /// <summary>
        /// 코팅 메서드
        /// </summary>
        /// <param name="quality">품질 수준</param>
        public void Coating(int quality)
        {
            if (Now < 100)
            {
                cells[Now] = quality;
            }
        }
        /// <summary>
        /// 특정 쉘의 품질 수준 인덱서  - 가져오기
        /// </summary>
        /// <param name="index">쉘 인덱스</param>
        /// <returns>특정 쉘의 품질</returns>
        public int this[int index]
        {
            get
            {
                if ((index < 0) || (index >= 100))
                {
                    return 0;
                }
                return cells[index];
            }
        }
        /// <summary>
        /// 평균 품질 - 가져오기
        /// </summary>
        public double Quality
        {
            get
            {
                int sum = 0;
                foreach (int elem in cells)
                {
                    sum += elem;
                }
                return sum / 100.0;
            }
        }
        /// <summary>
        /// ToString 메서드 재정의
        /// </summary>
        /// <returns>Wafer 번호와 평균 품질</returns>
        public override string ToString()
        {
            return string.Format("No:{0}, Quality:{1}", wn, Quality);
        }
    }
}

3. DPanel 소스 코드

using System.Windows.Forms;

namespace WaferLineControlLib
{
    /// <summary>
    /// 더블 버퍼링 스타일을 지정한 패널 클래스
    /// </summary>
    public class DPanel : Panel
    {
        /// <summary>
        /// 기본 생성자(더블 버퍼링 가능하게 스타일 지정하였음)
        /// </summary>
        public DPanel()
        {
            SetStyle(System.Windows.Forms.ControlStyles.OptimizedDoubleBuffer |
                System.Windows.Forms.ControlStyles.UserPaint |
                System.Windows.Forms.ControlStyles.AllPaintingInWmPaint, true);
            UpdateStyles();
        }
    }
}

4. WaferPanel 소스 코드

using System.Drawing;
using WaferLineLib;

namespace WaferLineControlLib
{
    /// <summary>
    /// WaferPanel 클래스 - Wafer를 시각화하는 패널
    /// </summary>
    public class WaferPanel:DPanel
    {
        /// <summary>
        /// Wafer 속성 - 가져오기 및 설정하기
        /// </summary>
        public Wafer Wafer
        {
            get;
            set;
        }
        /// <summary>
        /// 기본 생성자
        /// </summary>
        public WaferPanel()
        {
            this.Paint += WaferPanel_Paint;
        }
        /// <summary>
        /// Paint 이벤트 핸들러 - Wafer의 품질 수준 시각화
        /// </summary>
        /// <param name="sender">이벤트 전송자</param>
        /// <param name="e">이벤트 처리 인자</param>
        private void WaferPanel_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
        {
            Graphics graphics = e.Graphics;
            Brush brush = Brushes.Silver;
            Rectangle rect = new Rectangle(0, 0, Width, Height);
            graphics.FillEllipse(brush, rect);
            int width = Width;
            int height = Height;
            int sx = (int)(width * 0.15);
            int sy = (int)(height * 0.15);
            Rectangle rect2 = new Rectangle(sx, sy, (int)(width * 0.7), (int)(height * 0.7));
            graphics.DrawRectangle(Pens.Red, rect2);
            int xu = rect2.Width / 10;
            int yu = rect2.Height / 10;
            Pen pen = new Pen(Color.DarkGray, 1);
            for (int x = 1; x < 10; x++)
            {
                graphics.DrawLine(pen, new Point(sx + x * xu, sy), new Point(sx + x * xu, sy + rect2.Height));
            }
            for (int y = 1; y < 10; y++)
            {
                graphics.DrawLine(pen, new Point(sx, sy + y * yu), new Point(sx + rect2.Width, sy + y * yu));
            }

            if (Wafer == null)
            {
                return;
            }
            int dir = 0;
            int step = 1, nowstep = step;
            int nx = 4, ny = 5;
            for (int i = 0; i < 100; i++)
            {
                int qual = Wafer[i];
                Color color = Color.FromArgb(200 - qual * 2, 55 + qual * 2, 0);
                Rectangle rt = new Rectangle(sx + nx * xu + 1, sy + ny * yu + 1, xu - 1, yu - 1);
                graphics.FillRectangle(new SolidBrush(color), rt);
                if (nowstep == 0)
                {
                    dir = (dir + 1) % 4;
                    if (dir % 2 == 0)
                    {
                        step++;
                    }
                    nowstep = step;
                }
                nowstep--;
                switch (dir)
                {
                    case 0: ny--; break;
                    case 1: nx++; break;
                    case 2: ny++; break;
                    case 3: nx--; break;
                }
            }
        }
    }
}