一、項目介紹
這是一個用C語言繪制的動態(tài)萬象時鐘。
編譯環(huán)境:Visual Studio2019
第三方庫:Easyx2022 注意需要提前安裝easyX,如沒有基礎(chǔ)可以先了解easyX圖形編程
二、運行截圖
三、部分代碼
1.引入圖形頭文件
#include <graphics.h>
2.定義窗口大小
#define Width 550 #define Height 550
3.設(shè)定圓的結(jié)構(gòu)
struct TimeCircle { int fors;// 每一圈分成的份數(shù) int R;// 圈的半徑 double NextTime;// 上一個時刻時間 double Radian;// 累加的弧度 }; int main() { initgraph(Width, Height); SYSTEMTIME ti; TimeCircle TC[7]; TCHAR str[25]; for (int i = 0; i < 7; i++) { TC[i].R = (i + 1) * 35; TC[i].Radian = 0; TC[i].NextTime = 0; switch (i) { case 0:TC[i].fors = 1; break;// 年 case 1:TC[i].fors = 12; break;// 月 case 2:TC[i].fors = 30; break;// 日 case 3:TC[i].fors = 7; break;// 周 case 4:TC[i].fors = 24; break;// 時 case 5:TC[i].fors = 60; break;// 分 case 6:TC[i].fors = 60; break;// 秒 } } BeginBatchDraw(); while (true) { GetLocalTime(&ti); TC[2].fors = monthdasy(ti.wYear, ti.wMonth); for (int j = 0; j < 7; j++) { if (TC[5].NextTime != ti.wMinute) { TC[5].NextTime = ti.wMinute; TC[5].Radian = 0; } else { TC[5].Radian = TC[5].Radian + (2 * PI / TC[5].fors - TC[5].Radian) / 10; } if (TC[6].NextTime != ti.wSecond) { TC[6].NextTime = ti.wSecond; TC[6].Radian = 0; } else { TC[6].Radian = TC[6].Radian + (2 * PI / TC[6].fors - TC[6].Radian) / 10; } for (int i = 0; i < TC[j].fors; i++) { switch (j) { case 0: _stprintf_s(str, _T("%d年"), ti.wYear); break; case 1: _stprintf_s(str, _T("%d月"), (i + ti.wMonth) % TC[j].fors ? (i + ti.wMonth) % TC[j].fors : TC[j].fors); break; case 2: _stprintf_s(str, _T("%d號"), (i + ti.wDay) % TC[j].fors ? (i + ti.wDay) % TC[j].fors : i + ti.wDay); break; case 3: str[0] = L"周"[0]; str[1] = L"日一二三四五六"[(i + ti.wDayOfWeek) % 7]; str[2] = L""[0]; break; case 4: _stprintf_s(str, _T("%d時"), (i + ti.wHour) % TC[j].fors); break; case 5: _stprintf_s(str, _T("%d分"), (i + ti.wMinute) % TC[j].fors); break; case 6: _stprintf_s(str, _T("%d秒"), (i + ti.wSecond) % TC[j].fors); break; } DrawCircle(str, i, TC[j].fors, TC[j].R, TC[j].Radian);; } } FlushBatchDraw(); cleardevice(); } EndBatchDraw(); return 0; }
四、完整源碼
#include <graphics.h> #include <easyx.h> #include <conio.h> #include <math.h> #include <time.h> #include <stdio.h> const double PI = acos(-1.0); #define Width 550 #define Height 550 // str代表繪制的字符串 // variable 代表每次的變量 // fors 每次需要循環(huán)的次數(shù)總數(shù) // R 該圈的半徑 // Radian 累加的弧度 void DrawCircle(TCHAR str[25], int variable, int fors, int R, double Radian);// 繪制一圈字符 int monthdasy(int y, int m);// 某年某月的天數(shù) y 代表年份 m 代表月份 // 一個圈的結(jié)構(gòu)體 struct TimeCircle { int fors;// 每一圈分成的份數(shù) int R;// 圈的半徑 double NextTime;// 上一個時刻時間 double Radian;// 累加的弧度 }; int main() { initgraph(Width, Height); SYSTEMTIME ti; TimeCircle TC[7]; TCHAR str[25]; for (int i = 0; i < 7; i++) { TC[i].R = (i + 1) * 35; TC[i].Radian = 0; TC[i].NextTime = 0; switch (i) { case 0:TC[i].fors = 1; break;// 年 case 1:TC[i].fors = 12; break;// 月 case 2:TC[i].fors = 30; break;// 日 case 3:TC[i].fors = 7; break;// 周 case 4:TC[i].fors = 24; break;// 時 case 5:TC[i].fors = 60; break;// 分 case 6:TC[i].fors = 60; break;// 秒 } } BeginBatchDraw(); while (true) { GetLocalTime(&ti); TC[2].fors = monthdasy(ti.wYear, ti.wMonth); for (int j = 0; j < 7; j++) { if (TC[5].NextTime != ti.wMinute) { TC[5].NextTime = ti.wMinute; TC[5].Radian = 0; } else { TC[5].Radian = TC[5].Radian + (2 * PI / TC[5].fors - TC[5].Radian) / 10; } if (TC[6].NextTime != ti.wSecond) { TC[6].NextTime = ti.wSecond; TC[6].Radian = 0; } else { TC[6].Radian = TC[6].Radian + (2 * PI / TC[6].fors - TC[6].Radian) / 10; } for (int i = 0; i < TC[j].fors; i++) { switch (j) { case 0: _stprintf_s(str, _T("%d年"), ti.wYear); break; case 1: _stprintf_s(str, _T("%d月"), (i + ti.wMonth) % TC[j].fors ? (i + ti.wMonth) % TC[j].fors : TC[j].fors); break; case 2: _stprintf_s(str, _T("%d號"), (i + ti.wDay) % TC[j].fors ? (i + ti.wDay) % TC[j].fors : i + ti.wDay); break; case 3: str[0] = L"周"[0]; str[1] = L"日一二三四五六"[(i + ti.wDayOfWeek) % 7]; str[2] = L""[0]; break; case 4: _stprintf_s(str, _T("%d時"), (i + ti.wHour) % TC[j].fors); break; case 5: _stprintf_s(str, _T("%d分"), (i + ti.wMinute) % TC[j].fors); break; case 6: _stprintf_s(str, _T("%d秒"), (i + ti.wSecond) % TC[j].fors); break; } DrawCircle(str, i, TC[j].fors, TC[j].R, TC[j].Radian);; } } FlushBatchDraw(); cleardevice(); } EndBatchDraw(); return 0; } int monthdasy(int y, int m) { if (m == 2) return ((y % 4 == 0 && y % 100 != 0) || y % 400 == 0) ? 29 : 28; else return 31 - (m - 3) % 5 % 2; } void DrawCircle(TCHAR str[25], int variable, int fors, int R, double Radian) { settextcolor(variable ? HSLtoRGB((360.f / fors) * variable, 1, 0.5f) : WHITE); double a, x0, y0, w, h, x1, y1; int x, y; settextstyle(16, 0, L"楷體", variable * 3600 / fors, variable * 3600 / fors, 0, false, false, false, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY, DEFAULT_PITCH); a = (fors == 60) ? ((variable + 1) * PI * 2 / fors - Radian) : (variable * PI * 2 / fors);// 計算字符串弧度 a w = textwidth(str);// 計算字符串寬 w、高 h h = textheight(str); x1 = R * cos(a);// 計算輸出字符串的左上角位置 y1 = R * sin(a); x0 = x1 * cos(-a) - y1 * sin(-a);// 將字符串繞原點順時針旋轉(zhuǎn) a 弧度 y0 = y1 * cos(-a) + x1 * sin(-a); x0 -= w / 2;// 將字符串向左上偏移 w/2、h/2 y0 += h / 2;// 繪圖坐標向下為正 x = (int)(x0 * cos(a) - y0 * sin(a));// 將字符串繞原點逆時針旋轉(zhuǎn) a 弧度 y = (int)(y0 * cos(a) + x0 * sin(a)); outtextxy(int(Width / 2 + x + 0.5), int(Height / 2 - y + 0.5), str);// 繪圖坐標向下為正 }
C語言網(wǎng)提供由在職研發(fā)工程師或ACM藍橋杯競賽優(yōu)秀選手錄制的視頻教程,并配有習題和答疑,點擊了解:
一點編程也不會寫的:零基礎(chǔ)C語言學練課程
解決困擾你多年的C語言疑難雜癥特性的C語言進階課程
從零到寫出一個爬蟲的Python編程課程
只會語法寫不出代碼?手把手帶你寫100個編程真題的編程百練課程
信息學奧賽或C++選手的 必學C++課程
藍橋杯ACM、信息學奧賽的必學課程:算法競賽課入門課程
手把手講解近五年真題的藍橋杯輔導課程