C++ 时钟;多角星;花环实现。
最近在回顾C++,写了几个小玩意儿练习一下,该找工作了,十分焦虑。
好了,开始正文
首先如何画多角星?比如五角星,六角星等等?
这里以五角星为例,r1需要被指定,r2可以通过正弦定理得到。然后通过每一步增加360/2n的角度,依次通过短半径和长半径循环计算每个顶点的坐标。如果需要绘制的图形堆成,那么仅需计算一半,另一半通过对称得出。直接贴代码:
void InitNStar(int n, int x, int y, float radius, float offest) { POINT* pts = new POINT[n * 2]; float angle_A = 360.0 / n; float angle_D = 180.0 - 90.0 * (n - 2) / n; float angle_E = 180.0 - angle_D - angle_A / 2.0; float short_radius = radius / sinf(to_radian(angle_D)) * sinf(to_radian(angle_E)); float rs[] = {radius,short_radius}; for (int i = 0; i < 2*n; i++) { int sx = cosf(to_radian(270.0 + i * angle_A / 2.0 + offest)) * rs[i % 2] + 0.5; int sy = sinf(to_radian(270.0 + i * angle_A / 2.0 + offest)) * rs[i % 2] + 0.5; pts[i].x = sx+x; pts[i].y = sy+y; } solidpolygon(pts, n * 2); }
同理,对于花环的绘制依然可以参考这个思路。
如果不需要考虑每个小圆的弧度,直接绘制圆即可。
void DrawFlower(int n, int radius, int angle_C, int offest_x=0, int offest_y=0) { float angle_A = 2 * PI / n; float small_radius = radius * sinf(angle_A / 2) / sinf(to_radian(angle_C) / 2); float mid_radius = radius * sinf((2 * PI - to_radian(angle_C) - angle_A) / 2) / sinf(to_radian(angle_C) / 2); int x, y = 0; for (int i = 0; i < n; i++) { x = cosf(PI * 3 / 2 + angle_A * i) * mid_radius + 0.5; y = sinf(PI * 3 / 2 + angle_A * i) * mid_radius + 0.5; setfillcolor(RGB(253, 91 + i * (80 / n), 120 + i * (80 / n))); solidcircle(x + offest_x, y + offest_y, small_radius); } }
然后加一点细节让他动起来:
#include <iostream> #include <cmath> #include <graphics.h> #include <Windows.h> #define PI 3.1415926 using namespace std; float to_radian(float a) { return a * 3.1415926 / 180.0; } void DrawFlower(int n, int radius, int angle_C, int offest_x=0, int offest_y=0, int R=255,int G=91,int B=120, bool gradual=true, float offest_ang= PI * 3 / 2) { float angle_A = 2 * PI / n; float small_radius = radius * sinf(angle_A / 2) / sinf(to_radian(angle_C) / 2); float mid_radius = radius * sinf((2 * PI - to_radian(angle_C) - angle_A) / 2) / sinf(to_radian(angle_C) / 2); int x, y, x1, y1, x2, y2 = 0; for (int i = 0; i < n; i++) { x = cosf(offest_ang + angle_A * i) * mid_radius + 0.5 + offest_x; y = sinf(offest_ang + angle_A * i) * mid_radius + 0.5 + offest_y; if (gradual) setfillcolor(RGB(R, G + i * (80 / n), B + i * (80 / n))); else setfillcolor(RGB(R, G, B)); /*solidcircle(x + offest_x, y + offest_y, small_radius);*/ float ang = offest_ang + PI - to_radian(angle_C) / 2.0 + i * angle_A; solidpie(x - small_radius, y - small_radius, x + small_radius, y + small_radius, -ang, -ang - to_radian(angle_C)); x1 = cosf(offest_ang + angle_A * i - angle_A * 0.5) * (radius + 2) + 0.5 + offest_x; y1 = sinf(offest_ang + angle_A * i - angle_A * 0.5) * (radius + 2) + 0.5 + offest_y; x2 = cosf(offest_ang + angle_A * (i + 1) - angle_A * 0.5) * (radius + 2) + 0.5 + offest_x; y2 = sinf(offest_ang + angle_A * (i + 1) - angle_A * 0.5) * (radius + 2) + 0.5 + offest_y; POINT pts[4] = { {x1,y1},{x,y},{x2,y2} ,{0+offest_x,0+offest_y} }; solidpolygon(pts, 4); } } int main() { initgraph(800, 1000); setorigin(400, 400); setbkcolor(RGB(135, 206, 235)); cleardevice(); int n = 8, i = 0; while (1) { cleardevice(); BeginBatchDraw(); int x = sinf(PI * i / 400) * 50; int y = sinf(PI * i / 400) * 10; POINT pts[4] = { {x,y},{100,200},{-100,400},{0,600} }; setlinestyle(PS_SOLID | PS_ENDCAP_ROUND, 16); setlinecolor(RGB(0, 120, 80)); polybezier(pts, 4); DrawFlower(8, 150, 120, x+3, y+3, 220, 220, 220, false, PI * i++ / 400); DrawFlower(8, 150, 120, x, y, 255, 92, 120, true, PI * i++ / 400); setfillcolor(RGB(238, 232, 171)); solidcircle(x, y, 30); FlushBatchDraw(); if (i > 800) i = 0; Sleep(10); } getchar(); return 0; }
如何画时钟?
获取时分秒之后,通过时分秒的值得到指针角度,每个循环进行更新。
time_t nowtime; time(&nowtime); tm p; localtime_s(&p, &nowtime); int hour = p.tm_hour; int minute = p.tm_min; int second = p.tm_sec; int x1, y1, x2, y2 = 0; // 时针 setlinecolor(RGB(23,124,80)); setlinestyle(PS_SOLID | PS_ENDCAP_ROUND, 16); x1 = int(cosf(to_radian(90 + hour * 30)) * 30 + 0.5); y1 = int(sinf(to_radian(90 + hour * 30)) * 30 + 0.5); x2 = int(cosf(to_radian(270 + hour * 30)) * 150 + 0.5); y2 = int(sinf(to_radian(270 + hour * 30)) * 150 + 0.5); line(x1, y1, x2, y2); //solidroundrect(-30, -8, 200, 8, 20, 10); //分针 setlinecolor(RGB(23, 124, 180)); setlinestyle(PS_SOLID | PS_ENDCAP_ROUND, 12); x1 = int(cosf(to_radian(90 + minute * 6)) * 35 + 0.5); y1 = int(sinf(to_radian(90 + minute * 6)) * 35 + 0.5); x2 = int(cosf(to_radian(270 + minute * 6)) * 165 + 0.5); y2 = int(sinf(to_radian(270 + minute * 6)) * 165 + 0.5); line(x1, y1, x2, y2); //秒针 setlinecolor(BLACK); setlinestyle(PS_SOLID | PS_ENDCAP_ROUND, 8); x1 = int(cosf(to_radian(90 + second * 6)) * 40 + 0.5); y1 = int(sinf(to_radian(90 + second * 6)) * 40 + 0.5); x2 = int(cosf(to_radian(270 + second * 6)) * 180 +0.5); y2 = int(sinf(to_radian(270 + second * 6)) * 180 +0.5); line(x1, y1, x2, y2); setfillcolor(RGB(123, 34, 80)); solidcircle(0, 0, 15);
最后的代码在这里:来往/EasyX_Clock (gitee.com)