星期日, 5月 24, 2015

[C#] PictureBox - 亂數產生圓

論壇問題,討論 Random class 使用,拿來練習

Random 產生相同值的 MSDN 說明
預設的種子值是從系統時鐘衍生而來,而且解析度有限。 因此,若在極短時間內連續呼叫預設建構函式,建立不同的 Random 物件,這些物件就會有完全相同的預設種子值,也就會產生完全相同的幾組亂數。 只要使用單一 Random 物件來產生所有的亂數,就可以避免這個問題。 您也可以解決它,方法是修改系統時鐘傳回的種子值,然後明確地提供這個新的種子值給 Random(Int32) 建構函式。
採用下列寫法來避免 Random 產生相同值
Random r = new Random(Guid.NewGuid().GetHashCode());

畫面配置,利用 Timer 每隔一秒自動畫圓

C# Code
namespace DrawRandom
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            // Timer 預設每一秒觸發一次
            tmrDraw.Enabled = false;
            tmrDraw.Interval = 1000;
        }

        private void btnClear_Click(object sender, EventArgs e)
        {
            // 覆蓋一張顏色畫布在 PictureBox 上
            Graphics g = PBRandom.CreateGraphics();
            g.Clear(this.BackColor);
        }

        public void DrawPie()
        {
            int
              PieWidth = 100,
              PieHeight = 100,
              PBWidth = PBRandom.Width,
              PBHeight = PBRandom.Height;

            Random RX = new Random(Guid.NewGuid().GetHashCode());
            Random RY = new Random(Guid.NewGuid().GetHashCode());
            Random RR = new Random(Guid.NewGuid().GetHashCode());
            Random RG = new Random(Guid.NewGuid().GetHashCode());
            Random RB = new Random(Guid.NewGuid().GetHashCode());

            // 限制亂數範圍
            // 1. 圓的寬和高必須在畫布內
            // 2. RGB 數字必須在 0 - 255 之間
            int
              X = RX.Next(0, PBWidth - PieWidth),
              Y = RY.Next(0, PBHeight - PieHeight),
              R = RR.Next(0, 255),
              G = RG.Next(0, 255),
              B = RB.Next(0, 255);

            // 在 PictureBox 上產生畫布
            Graphics g = PBRandom.CreateGraphics();

            // 設定 Brush 顏色
            Color RandomColor = new Color();
            RandomColor = Color.FromArgb(R, G, B);
            SolidBrush brush = new SolidBrush(RandomColor);

            // 畫實心圓
            g.FillPie(brush, X, Y, PieWidth, PieHeight, 0, 360);
        }

        #region Timer 相關
        private void txtTimerStart_Click(object sender, EventArgs e)
        {
            tmrDraw.Start();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            tmrDraw.Stop();
        }

        private void tmrDraw_Tick(object sender, EventArgs e)
        {
            DrawPie();
        } 
        #endregion
    }
}

沒有留言:

張貼留言