#include "Clock.h"
Clock::Clock()
{
// 这行代码用于使得该图形窗口使用设备实际像素点大小,而不是Windows缩放后的大小
// Windows放大后像素点大小变大,容易出现锯齿化现象
SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE);
// 加载初始屏幕
initgraph(WIDTH, HEIGHT);
// 反转y轴,使逻辑坐标符合数学习惯
// 反转后坐标方向
/*
* y^
* |
* |
* |
* |
* +---------->x
*/
setaspectratio(1, -1);
// 设置坐标原点为绘图设备的物理坐标的中心
setorigin(WIDTH / 2, HEIGHT / 2);
// 初始化时分秒针长度
hourHandRadius = 180;
minuteHandRadius = 240;
secondHandRadius = 300;
// 初始化时分秒针末端坐标
hourCoord = { 0,hourHandRadius };
minuteCoord = { 0,minuteHandRadius };
secondCoord = { 0,secondHandRadius };
// 初始化时分秒针粗细
hourHandThick = 16;
minuteHandThick = 12;
secondHandThick = 10;
// 初始化时分秒针颜色
hourHandColor = LIGHTBLUE;
minuteHandColor = LIGHTRED;
secondHandColor = YELLOW;
// 绘制钟表外廓
setlinecolor(BROWN);
setlinestyle(PS_SOLID, 12);
circle(0, 0, 350);
// 绘制刻度点
int scaleRadius = 335;
for (int angle = 0; angle < 360; angle += 6)
{
if (!(angle % 90))
{
double x = cos(Ang2Rad(angle))*scaleRadius;
double y = sin(Ang2Rad(angle))*scaleRadius;
setfillcolor(WHITE);
solidrectangle(x - 8, y + 8, x + 8, y - 8);
}
else if (!(angle % 30))
{
double x = cos(Ang2Rad(angle))*scaleRadius;
double y = sin(Ang2Rad(angle))*scaleRadius;
setlinestyle(PS_SOLID, 10);
setlinecolor(BROWN);
circle(x, y, 5);
}
else
{
double x = cos(Ang2Rad(angle))*scaleRadius;
double y = sin(Ang2Rad(angle))*scaleRadius;
setlinestyle(PS_SOLID, 2);
setlinecolor(WHITE);
circle(x, y, 1);
}
}
}
void Clock::UpdateTime()
{
time(&timeStamp);
if (lastStamp)
{
if (lastStamp == timeStamp)
{
// 本次的时间戳与上次迭代时相同(变化量小于1秒)就不重新绘制了
return;
}
else
{
lastStamp = timeStamp;
}
}
else
{
lastStamp = timeStamp;
}
localTime = localtime(&timeStamp);
// 获取本地时间
hour = localTime->tm_hour;
minute = localTime->tm_min;
second = localTime->tm_sec;
// tm_year表示从1900开始的总年数
year = localTime->tm_year + 1900;
// tm_month是从0开始算的
month = localTime->tm_mon + 1 ;
day = localTime->tm_mday;
wchar_t outStr[200];
// memset(outStr, 0, 200);
wcscpy(outStr, L"");
wchar_t wYear[20],wMonth[20], wDay[20], wHour[20], wMinute[20], wSecond[20];
_itow_s(year, wYear, 10);
_itow_s(day, wDay, 10);
_itow_s(month, wMonth, 10);
_itow_s(hour, wHour,10);
_itow_s(minute, wMinute, 10);
_itow_s(second, wSecond, 10);
wcscat(outStr,wYear);
wcscat(outStr, L"年");
wcscat(outStr, wMonth);
wcscat(outStr, L"月");
wcscat(outStr, wDay);
wcscat(outStr, L"日 ");
wcscat(outStr, wHour);
wcscat(outStr, L":");
wcscat(outStr, wMinute);
wcscat(outStr, L":");
wcscat(outStr, wSecond);
BeginBatchDraw();
// 使用BeginBatchDraw()和EndBatchDraw()会将两行指令中间所有的内容先写入缓存区再统一绘制,可以防止闪屏
// 下面两行代码用来用一个黑色的圆形区域覆盖上一次在表盘内绘制的所有内容
setfillcolor(BLACK);
solidcircle(0, 0, 310);
// 打印WYB
setaspectratio(1, 1);
settextstyle(70, 50, _T("黑体"));
settextcolor(CYAN);
wchar_t wyb[] = L"WYB";
outtextxy(-75, -200, wyb);
setaspectratio(1, -1);
// 用文字在表盘上显示日期
setaspectratio(1, 1);
settextstyle(30, 15, _T("黑体"));
settextcolor(LIGHTGRAY);
outtextxy(-160, 150, outStr);
setaspectratio(1, -1);
// 计算本次时间更新的指针角度
hourHandAngle = (90 - (int)(((hour % 12)/12.0) * 360))%360;
minuteHandAngle = (90 - (int)((minute / 60.0) * 360))%360;
secondHandAngle = (90 - (int)((second / 60.0) * 360))%360;
// 计算本次时间更新的指针角度
hourCoord.x = cos(Ang2Rad(hourHandAngle))*hourHandRadius;
hourCoord.y = sin(Ang2Rad(hourHandAngle))*hourHandRadius;
minuteCoord.x = cos(Ang2Rad(minuteHandAngle))*minuteHandRadius;
minuteCoord.y = sin(Ang2Rad(minuteHandAngle))*minuteHandRadius;
secondCoord.x = cos(Ang2Rad(secondHandAngle))*secondHandRadius;
secondCoord.y = sin(Ang2Rad(secondHandAngle))*secondHandRadius;
// 重新绘制时分秒针
setlinecolor(hourHandColor);
setlinestyle(PS_SOLID, hourHandThick);
line(0, 0, hourCoord.x, hourCoord.y);
setlinecolor(minuteHandColor);
setlinestyle(PS_SOLID, minuteHandThick);
line(0, 0, minuteCoord.x, minuteCoord.y);
setlinecolor(secondHandColor);
setlinestyle(PS_SOLID, secondHandThick);
line(0, 0, secondCoord.x, secondCoord.y);
// 结束从BeginBatchDraw()开始中间所有的缓存,开始绘制
EndBatchDraw();
}