Analog Clock ก็คือนาฬิกาที่เป็นเข็มๆนั่นแหละครับคงจะรู้จักกันดี แต่เคยสงสัยไหมครับว่าถ้าเราจะสร้างมันได้ยังไงโดยการเขียนโปรแกรม เดี๋ยวผมจะลองเขียนโดย C# ก่อนแล้วกันนะครับเพราะง่ายสำหรับผมตอนนี้ ส่วนใครที่อยากได้โค๊ดของจาวาก็คงต้องรอไปก่อนนะครับ
ขั้นตอนที่ 1 สร้าง Windows Forms Application ขึ้นมาก่อนในที่นี้ผมตั้งชื่อโปรเจคว่า AnalogClock
ขั้นตอนที่ 2 นำ Panel จาก ToolBox มาวางบน Form และเปลี่ยน Properties ดังนี้
Name : ClockPanel, BackColor : Black, Size : [300, 300]
ขั้นตอนที่ 3 นำ Button จาก ToolBox มาวางบน Form และเปลี่ยน Properties ดังนี้
Name : SetTime, Text : Set Time
ขั้นตอนที่ 4 นำ NumericUpDown จาก ToolBox มาวางบน Form จำนวน 3 อัน โดยจะใช้เป็นตัวกำหนดค่าของ วินาที, นาทีและชั่วโมง โดยเปลี่ยน Properties ดังนี้
ส่วนของวินาที Name : UDsec, Maximum : 60, Minimum : 0, Value : 0
ส่วนของนาที Name : UDmin, Maximum : 60, Minimum : 0, Value : 0
ส่วนของชั่วโมง Name : UDhour, Maximum : 12, Minimum : 0, Value : 0
ส่วนทั้งหมดนี้จะเป็นส่วน GUI ทั้งหมดที่เราจะใช้ผู้อ่านสามารถปรับแต่งได้ตามความต้องการครับ ^_^
ขั้นตอนที่ 5 ในส่วนนี้เราจะมาเรียนรู้เรื่องการวาดเข็มนาฬิกากันครับ ซึ่งจะมีคณิตศาสตร์เข้ามาเกี่ยวข้องนิดหน่อย ส่วนพารามิเตอร์หลักที่เราจำเป็นต้องใช้คือ จุดศูนย์กลางของ Panel (xCenter, yCenter), ความยาวของเข็มนาฬิกาซึ่งมีทั้งหมด 3 อัน(secLength, minLength, hourLength) และจุดปลายของเข็มทั้ง 3 ที่เราจะวาดนั่นแหละครับ(xSec, ySec, xMin, yMin, xHour, yHour) แต่เอ๊ะ! แล้วเราจะรู้ได้ยังไงหล่ะครับว่าจุดปลายจะเอามาจากไหน เราจะสามารถหาจุดปลายของเข็มนาทีได้ดังนี้ครับ
xSec = xCenter + secLength*sin(θ)
ySec = yCenter - secLength*cos(θ)
θ = second*(2π/60) -> ส่วนของวินาที
θ = (minute+second/60)*(2π/60) -> ส่วนของนาที
θ = (hour%12+minute/60))*(2π/12) -> ส่วนของชั่วโมง
สามารถเขียนโค๊ดได้ดังต่อไปนี้
xSec = Convert.ToInt32(xCenter+SecLength*Math.Sin(sec*(((2*Math.PI)/60))));ขั้นตอนที่ 6 ให้เราทำการสร้าง Event Paint ของ Panel ขึ้นมาซึ่งจะใช้วาดองค์ประกอบหลักของนั่นก็คือวงกลมขอบนาฬิกาและตัวเลข ตามโค๊ดต่อไปนี้
ySec = Convert.ToInt32(xCenter-SecLength*Math.Cos(sec*(((2*Math.PI)/60))));
xMin = Convert.ToInt32(xCenter + MinLength * Math.Sin(min * (((2 * Math.PI) / 60))));
yMin = Convert.ToInt32(xCenter - MinLength * Math.Cos(min * (((2 * Math.PI) / 60))));
xHour = Convert.ToInt32(xCenter + HourLength * Math.Sin((hour % 12 + min / 60) * ((2 * Math.PI) / 12)));
yHour = Convert.ToInt32(yCenter - HourLength * Math.Cos((hour % 12 + min / 60) * ((2 * Math.PI) / 12)));
private void ClockPanel_Paint(object sender, PaintEventArgs e) { Graphics g = ClockPanel.CreateGraphics(); g.DrawEllipse(new Pen(Color.Yellow), xCenter-130, yCenter-130, 260, 260); //วาดวงกลมสีเหลืองขนาด 260*260 g.DrawString("3", new Font("Arial", 16), new SolidBrush(Color.Green), xCenter + 110, yCenter-10); g.DrawString("6", new Font("Arial", 16), new SolidBrush(Color.Green), xCenter - 10, yCenter + 106); g.DrawString("9", new Font("Arial", 16), new SolidBrush(Color.Green), xCenter - 130, yCenter - 10); g.DrawString("12", new Font("Arial", 16), new SolidBrush(Color.Green), xCenter - 16, yCenter - 130); }ขั้นตอนที่ 7 ให้เราทำการสร้าง Event Click ของปุ่ม SetTime แล้วเพิ่มโค๊ดต่อไปนี้ลงไป
ClockPanel.Refresh(); int sec = Convert.ToInt32(UDsec.Value); //อ่านค่าจาก NumericUpDown int min = Convert.ToInt32(UDmin.Value); int hour = Convert.ToInt32(UDhour.Value); xSec = Convert.ToInt32(xCenter+SecLength*Math.Sin(sec*(((2*Math.PI)/60)))); ySec = Convert.ToInt32(xCenter-SecLength*Math.Cos(sec*(((2*Math.PI)/60)))); xMin = Convert.ToInt32(xCenter + MinLength * Math.Sin(min * (((2 * Math.PI) / 60)))); yMin = Convert.ToInt32(xCenter - MinLength * Math.Cos(min * (((2 * Math.PI) / 60)))); xHour = Convert.ToInt32(xCenter + HourLength * Math.Sin((hour % 12 + min / 60) * ((2 * Math.PI) / 12))); yHour = Convert.ToInt32(yCenter - HourLength * Math.Cos((hour % 12 + min / 60) * ((2 * Math.PI) / 12))); Graphics g = ClockPanel.CreateGraphics(); g.DrawLine(new Pen(Color.Red), xCenter, yCenter, xSec, ySec); g.DrawLine(new Pen(Color.Yellow,3), xCenter, yCenter, xMin, yMin); g.DrawLine(new Pen(Color.White,3), xCenter, yCenter, xHour, yHour); g.DrawLine(new Pen(Color.Red), xCenter, yCenter, xSec, ySec);จากนั้นก็ลองรันโปรแกรมดูนะครับว่าผลลัพธ์เป็นยังไง