在c++中使用easyx画一个实时走动的钟表(方法细节)

这次的任务是用c++画出实时走动的钟表,并且与当前系统的时间一致。

由于我们使用的是c++语言,我们更需要用这个例子来提高我们对面向对象程序设计的理解。

我们首先需要分析出需求,“画一个能够实时走动的钟表”,根据需求我们可以好处两个对象,钟表对象与画图对象,所以我们大致先建立两个类,Clock类与Paint类。

Clock类中的成员变量都有:表的中心坐标x与y、表的时间(时、分、秒)、表的大小r(即半径)、表盘的颜色color。

Clock类中无其他函数,只有用于初始化的构造函数。

Paint类中无任何成员变量,只有三个函数:画表盘函数drawClock_bk、画表盘刻度函数drawClock_scale、画表针函数drawClock_sharp、

其中画表盘是非常简单的,最最困难的就是画刻度函数与画表针函数。

要想要画出刻度与表针,就必须知道如何得画刻度的两个坐标。

下面先来了解下如何求得坐标(纯数学知识)

如图:

在c++中使用easyx画一个实时走动的钟表(方法细节)_第1张图片

如果要求圆上一点a的坐标(x,y),利用三角函数,若a点与圆心o(x0,y0)连线与x轴的夹角大小为c,r为半径,则a的横坐标x值为x0+cos(c)*r,a的纵坐标y为y0-sin(c)*r,这样就可求得圆上任意一点的坐标。然后我们需要画出刻度,即我们还需要圆心o与圆上一点a的连线上的另一个坐标,这样才可以画出刻度。如图:

在c++中使用easyx画一个实时走动的钟表(方法细节)_第2张图片

如图点b是点a与圆心o连线上的一点。假设我们需要画的刻度长度是s,所以a与b连线的距离为s,b与圆心连线的距离为r-s,所以根据三角函数也可以求得点b的坐标为x:x0+cos(c)*(r-s),y为:y0-sin(c)*(r-s)。

这下有a、b这两点的坐标就可以画出一个刻度了,然后根据表盘的实际分布可以将所有的刻度画出来了(即每个刻度为5度)。

表针的画法与刻度类似:需要找这个b这种点(圆心与圆上的点连线上的点),然后根据你指定的针长和夹角,就可以求出b点的坐标。然后用b点坐标和圆心坐标就可以画出对应的指针了。

 

最重要的坐标求法就是这样了,剩下具体的细节请看下面代码:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 


#define PI 3.1415
using namespace std;

class Clock
{
public:
	int _x;
	int _y;
	int _hour;
	int _minute;
	int _second;
	int _r;
	COLORREF _bk_col;
public:
	Clock(int x,int y,int h,int m,int s,int r,COLORREF bk_color)
	{
		this->_x = x;
		this->_y = y;
		this->_hour = h;
		this->_minute = m;
		this->_second = s;
		this->_r = r;
		this->_bk_col = bk_color;
	}
};

class Paint
{
public :
	void drawclock_bk(Clock c);
	void drawclock_scale(Clock c);
	void drawclock_sharp(Clock c);
};

void Paint::drawclock_bk(Clock c)
{
	setcolor(RGB(0,0,0));
	setfillcolor(RGB(0,0,0));
	fillcircle(c._x,c._y,c._r);
}

void Paint::drawclock_scale(Clock c)
{
	int x1,y1;
	int x2, y2;
	setlinecolor(RGB(255, 255, 255));
	for (int a = 1; a <= 60;a++)
	{
		if (a <= 15)
		{
			x1 = static_cast(c._x + (cos(a*(PI / 30)))*c._r);
			y1= static_cast(c._y - (sin(a*(PI / 30)))*c._r);
			if (a % 5 == 0)
			{
				x2 = static_cast(c._x + (cos(a*(PI / 30)))*(c._r - 15));
				y2 = static_cast(c._y - (sin(a*(PI / 30)))*(c._r - 15));
			}
			else
			{
				x2 = static_cast(c._x + (cos(a*(PI / 30)))*(c._r - 5));
				y2 = static_cast(c._y - (sin(a*(PI / 30)))*(c._r - 5));
			}
		}
		else if (a > 15 && a <= 30)
		{
			x1 = static_cast(c._x + (cos(a*(PI / 30)))*c._r);
			y1 = static_cast(c._y - (sin(a*(PI / 30)))*c._r);
			if (a % 5 == 0)
			{
				x2 = static_cast(c._x + (cos(a*(PI / 30)))*(c._r - 15));
				y2 = static_cast(c._y - (sin(a*(PI / 30)))*(c._r - 15));
			}
			else
			{
				x2 = static_cast(c._x + (cos(a*(PI / 30)))*(c._r - 5));
				y2 = static_cast(c._y - (sin(a*(PI / 30)))*(c._r - 5));
			}
		}
		else if (a > 30 && a <= 45)
		{
			x1 = static_cast(c._x + (cos(a*(PI / 30)))*c._r);
			y1 = static_cast(c._y - (sin(a*(PI / 30)))*c._r);
			if (a % 5 == 0)
			{
				x2 = static_cast(c._x + (cos(a*(PI / 30)))*(c._r - 15));
				y2 = static_cast(c._y - (sin(a*(PI / 30)))*(c._r - 15));
			}
			else
			{
				x2 = static_cast(c._x + (cos(a*(PI / 30)))*(c._r - 5));
				y2 = static_cast(c._y - (sin(a*(PI / 30)))*(c._r - 5));
			}
		}
		else if (a > 45 && a <= 60)
		{
			x1 = static_cast(c._x + (cos(a*(PI / 30)))*c._r);
			y1 = static_cast(c._y - (sin(a*(PI / 30)))*c._r);
			if (a % 5 == 0)
			{
				x2 = static_cast(c._x + (cos(a*(PI / 30)))*(c._r - 15));
				y2 = static_cast(c._y - (sin(a*(PI / 30)))*(c._r - 15));
			}
			else
			{
				x2 = static_cast(c._x + (cos(a*(PI / 30)))*(c._r - 5));
				y2 = static_cast(c._y - (sin(a*(PI / 30)))*(c._r - 5));
			}
		}
	
		line(x1, y1,x2, y2);
	}
	setfillcolor(RGB(255,255,255));
	fillcircle(c._x,c._y,5);
}

void Paint::drawclock_sharp(Clock c)
{	
	int x1, y1;
	int x2, y2;
	int x3, y3;
	setlinecolor(RGB(255,255,255));
	x3 = static_cast(c._x + (cos(static_cast(15 - c._second)*(PI / 30)))*static_cast(0.8*c._r));
	x2 = static_cast(c._x + (cos(static_cast(15 - c._minute - static_cast(c._second) / 60)*(PI / 30)))*static_cast(0.6*c._r));
	x1 = static_cast(c._x + (cos(static_cast(3 - c._hour - static_cast(c._minute) / 60)*(PI / 6)))*static_cast(0.4*c._r));
	y3 = static_cast(c._y - (sin(static_cast(15 - c._second)*(PI / 30)))*static_cast(0.8*c._r));
	y2 = static_cast(c._y - (sin(static_cast(15 - c._minute - static_cast(c._second) / 60)*(PI / 30)))*static_cast(0.6*c._r));
	y1 = static_cast(c._y - (sin(static_cast(3 - c._hour - static_cast(c._minute) / 60)*(PI / 6)))*static_cast(0.4*c._r));
	line(c._x, c._y, x1, y1);
	line(c._x, c._y, x2, y2);
	line(c._x, c._y, x3, y3);
}

int main()
{
	initgraph(1024,576);
	setbkcolor(RGB(255, 255, 255));
	cleardevice();
	time_t nowtime;
	struct  tm* ptime;
	
	if (time(&nowtime))
	{
		ptime = localtime(&nowtime);
	}
	Clock c(512, 288,ptime->tm_hour, ptime->tm_min, ptime->tm_sec, 120, RGB(255, 255, 255));
	Paint p1;
	p1.drawclock_bk(c);
	p1.drawclock_scale(c);
	p1.drawclock_sharp(c);
        int flag=0;
	while (true)
	{
		Sleep(1000);
		++c._second;
		c._second%=60;
		if (c._second== 0)
		{

			c._minute++;
		}
			c._minute %= 60;
                if(c._minute==1)
                {
                    flag=0;

		if (c._minute == 0&&flag==0)
		{
			c._hour++;
                        flag=1;
		}
			c._hour %= 24;
		p1.drawclock_bk(c);
		p1.drawclock_scale(c);
		p1.drawclock_sharp(c);
	}

	_getch();
	closegraph();
	return 0; 
}

vs2013运行效果如图:

在c++中使用easyx画一个实时走动的钟表(方法细节)_第3张图片

 

如有其它疑惑,敬请留言,本人会尽快作以回复,谢谢。

你可能感兴趣的:(学习记录,经验分享,互动交流)