การออกแบบ
ตัวเรือนนาฬิกา
โครงสร้างหลักของนาฬิการมี 2 ส่วนคือ ตัวเรือนและเข็ม
1. ตัวเรือน คือวงกลมใหญ่แทนตัวเรือน และวงกลมเล็กอยู่ตรงกลางตัวเรือนแทนตำแหน่งของจุดหมุนของเข็มนาฬิกา
รูปที่ 1 |
2. เข็มนาฬิกา คือเส้นตรง 3 เส้นขนาดต่างกัน เส้นยาวสุดแทนเข็มวินาที เส้นสั้นสุดแทนเข็มชั่วโมง และเส้นที่มีความยาวระหว่างสองเส้นแรกแทนเข็มนาที
รูปที่ 2 |
นำองค์ประกอบมารวมเป็นตัวนาฬิกา
รูปที่ 3 |
การสร้างโปรแกรม
1. การวาดตัวเรือนนาฬิกา
1.1 กำหนดตำแหน่งที่ของนาฬิกา โดยให้อยู่ที่ตรงกลางของหน้าต่าง (window)
// constants :
const int WIN_WIDTH=400;
const int WIN_HEIGHT=400;
const float cx = (float)(WIN_WIDTH / 2);
const float cy = (float)(WIN_HEIGHt / 2);
1.2 การวาดตัวเรือนนาฬิกาใช้ function
void DrawRing(Vector2 center,
float innerRadius,
float outerRadius,
float startAngle,
float endAngle,
int segments,
Color color);
function นี้ต้องใช้ 7 parameters :
♦ center : ตำแหน่งจุดศูนย์กลาง ในการทำงานครั้งนี้คือค่าของ cx,cy แต่ต้องนำมาแปลงให้เป็นตัวแปรแบบ Vector2 ก่อน
♦ innerRadius : ความยาวของรัศมีของวงกลมด้านใน
♦ outerRadius : ความยาวของรัศมีของวงกลมด้านนอก
♦ startAngle : มุมของจุดเริ่มต้นใช้หน่วยเป็น degree โดยมุมจะเริ่มวัดจากแนวของ X+ axis (แนวตั้งฉากกับพื้น) แล้ววัดไปในทิศทวนเข็มนาฬิกา
♦ endAngle : มุมของจุดสุดท้าย
♦ segMents : จำนวนเหลี่ยมที่ต้องการ เริ่มต้นจาก 0 (ไม่มีการวาด) จำนวนเหลี่ยมยิ่งมากขึ้น รูปทรงจะออกมาใกล้กับเส้นโค้งของวงกลมมากขึ้น
♦ color : สีที่ต้องการเติ่ม
ข้อดีของการกำหนด startAngle , endAngle ทำให้สามารถวาดรูป arc ได้ และการที่สามารถกำหนดจำนวนเหลี่ยมก็ทำให้สามารถวาดรูปอื่นที่ไม่มีส่วนโค้งได้ เช่น รูป 6 เหลี่ยม ได้
รูปที่ 4 |
การวาดวงกลมตรงกลางของนาฬิกาจะใช้
void DrawCircle(int centerX,
int centerY,
float radius,
Color color);
1.3 สร้าง function ของการวาดตัวเรือน
void draw_clock(){
float thickness = 5.0f; // thickness of the ring
float inrad = 100.0f; // inner radius
float ourad = inrad + thickness; // outter radius
float stang = 0.0f; // start angle
float enang = 360.0f; // end angle
float seg = 360.0f; // segments
Vector2 cnt = {cx,cy}; // cast cx,cy to Vector2
DrawRing(cnt,inrad,ourad,stang,enang,seg,BLUE); // draw blue clock
DrawCircle((int)cx,(int)cy,10,BLACK); // draw black circle with radius 10 pixels on the middle of the clock
}
2. การวาดเข็มนาฬิกา
การวาดเข็มคือการวาดเส้นตรง 3 เส้นที่มีความยาวต่างกันด้วย function
void DrawLineEx(Vector2 startPos,
Vector2 endPos,
float thick,
Color color);
function นี้ต้องการ 4 parameters:
♦ startPos : coordinate ของตำแหน่งเริ่มต้น
♦ endPos : coordinate ของตำแหน่งสิ้นสุด
♦ thick : ขนาดความหนาของเส้น
♦ color : สีของเส้น
ควรกำหนดขนาดความยาวไว้เป็นค่าคงที่
// constants :
//clock
const int WIN_WIDTH=400;
const int WIN_HEIGHT=400;
const float cx = (float)(WIN_WIDTH / 2);
const float cy = (float)(WIN_HEIGHt / 2);
// arms
const int SEC_ARM_LEN = 70;
const int MIN_ARM_LEN = 60;
const int HRS_ARM_LEN = 50;
เพื่อให้ง่ายในการแก้ไข ควรแยก function ของการวาดเข็มแยกกันระหว่าง เข็มวินาที, เข็มนาทีและเข็มชั่วโมง แม้วิธีการทำงานจะเหมือนกันก็ตาม ถ้าหากเข้าใจการทำงานดีแล้วก็สามารถปรับแต่งได้ตามความต้องการภายหลัง
void draw_sec_arm(){
float thickness = 3.0f;
Vector2 start = {cx,cy};
Vector2 end = {(float)(cx+SEC_ARM_LEN),(float)(cy+SEC_ARM_LEN)};
DrawLineEx(start,end,thickness,RED);
}
void draw_min_arm(){
float thickness = 7.0f;
Vector2 start = {cx,cy};
Vector2 end = {(float)(cx+SEC_MIN_LEN),(float)(cy+SEC_MIN_LEN)};
DrawLineEx(start,end,thickness,BLUE);
}
void draw_hrs_arm(){
float thickness = 11.0f;
Vector2 start = {cx,cy};
Vector2 end = {(float)(cx+SEC_HRS_LEN),(float)(cy+SEC_HRS_LEN)};
DrawLineEx(start,end,thickness,DARKPURPLE);
}
3. Complete Code
#include "raylib.h"
/ constants :
//clock
const int WIN_WIDTH=400;
const int WIN_HEIGHT=400;
const float cx = (float)(WIN_WIDTH / 2);
const float cy = (float)(WIN_HEIGHT / 2);
// arms
const int SEC_ARM_LEN = 70;
const int MIN_ARM_LEN = 60;
const int HRS_ARM_LEN = 50;
const int FPS = 20;
// functions
void draw_clock();
void draw_sec_arm();
void draw_min_arm();
void draw_hrs_arm();
int main(void){
InitWindow(SCR_WIDTH,SCR_HEIGHT,"Clock");
SetTargetFPS(FPS);
while(!WindowShouldClose()){
ClearBackground(WHITE);
draw_hrs_arm();
draw_min_arm();
draw_sec_arm();
draw_clock();
EndDrawing();
}
CloseWindow();
return 0;
}
void draw_clock(){
float thickness = 5.0f; // thickness of the ring
float inrad = 100.0f; // inner radius
float ourad = inrad + thickness; // outter radius
float stang = 0.0f; // start angle
float enang = 360.0f; // end angle
float seg = 360.0f; // segments
Vector2 cnt = {cx,cy}; // cast cx,cy to Vector2
DrawRing(cnt,inrad,ourad,stang,enang,seg,BLUE); // draw blue clock
DrawCircle((int)cx,(int)cy,10,BLACK); // draw black circle with radius 10 pixels on the middle of the clock
}
void draw_sec_arm(){
float thickness = 3.0f;
Vector2 start = {cx,cy};
Vector2 end = {(float)(cx+SEC_ARM_LEN),(float)(cy+SEC_ARM_LEN)};
DrawLineEx(start,end,thickness,RED);
}
void draw_min_arm(){
float thickness = 7.0f;
Vector2 start = {cx,cy};
Vector2 end = {(float)(cx+SEC_MIN_LEN),(float)(cy+SEC_MIN_LEN)};
DrawLineEx(start,end,thickness,BLUE);
}
void draw_hrs_arm(){
float thickness = 11.0f;
Vector2 start = {cx,cy};
Vector2 end = {(float)(cx+SEC_HRS_LEN),(float)(cy+SEC_HRS_LEN)};
DrawLineEx(start,end,thickness,DARKPURPLE);
}
ผลลัพธ์ที่ได้จะเป็นดังรูปที่ 5
รูปที่ 5 |
การบ้าน
♦ ทดลองเปลี่ยนรูปทรงของนาฬิกาจากวงกลมไปเป็นรูปหลายเหลี่ยม
♦ ทดลองเปลี่ยนค่า parameters ต่างๆ
Vector2 เป็น datatype แบบโครงสร้าง (structure) มี 2 components คือ x และ y ในโปรแกรมนี้จะใช้เพื่อเก็บตำแหน่งของวัตถุ
typedef struct Vector2 {
float x; // Vector x component
float y; // Vector y component
} Vector2;
Color เป็น datatype แบบโครงสร้าง (structure) มี 4 components คือ r,g,b และ a ใช้เก็บค่าสีของ pixel
typedef struct Color {
unsigned char r; // Color red value
unsigned char g; // Color green value
unsigned char b; // Color blue value
unsigned char a; // Color alpha value
} Color;
Raylib มีการสร้างตัวแปรสำหรับแทนค่าสีไว้แล้วบางค่า สามารถนำไปใช้ได้
ความคิดเห็น
แสดงความคิดเห็น