/*这是一个模拟指针式仪表摆动的小程序,环境设置时选用多字节字符集。*/
/*编程练习内容涉及easyX库中画线、文字显示等函数、c++中类、有参构造函数、成员函数、随机数、三目运算等内容*/
/*程序特点:显示文字大小、指针宽度等都随调用者给定的参数自动调整 ,程序注释详细注明了语句的功能。拷贝即可运行,供初学C++者参考*/
#include <stdio.h>
#include <graphics.h>
#include <conio.h>
#include <math.h>
#include <time.h>
#define RATIO_A 0.75 //仪表盘长宽比
#define Fr 200 //指针摆动一次的时间间隔ms数
//下面:声明一个指针式仪表类
class PointMeter
{ public:
int pointMeterCenter_x; //成员变量 圆角矩形表盘中心x坐标
int pointMeterCenter_y; //成员变量 圆角矩形表盘中心y坐标
int pointMeterCenter_scale; //成员变量 矩形仪表盘宽度,高度取宽度0.75
PointMeter(int x,int y,int z)//参构造函数 用于赋值
{
pointMeterCenter_x=x;
pointMeterCenter_y=y;
pointMeterCenter_scale=z;
};
void drawMeterPanel(); //成员函数 画出仪表盘
};
//下面:实现画出仪表盘及指针动作的代码
void PointMeter::drawMeterPanel()
{
//以下画仪表盘及刻度线等
setorigin(pointMeterCenter_x,pointMeterCenter_y);//作图原点设置在仪表盘中心点
setaspectratio(1,-1);//将y坐标方向调整为向上
setbkcolor(RGB(186,206,195));//背景颜色设置为浅绿
cleardevice();//清屏
setlinecolor(GREEN);//画线颜色设定为绿色
setlinestyle(0,2);// 线型选择 0--实线 2--像素宽
roundrect //用下列坐标点画出仪表盘外形(带圆角的长方形)
(
this->pointMeterCenter_scale/2*RATIO_A,
this->pointMeterCenter_scale/2*RATIO_A*0.618,//长宽比取0.618
-this->pointMeterCenter_scale/2*RATIO_A,
-this->pointMeterCenter_scale/2*RATIO_A*0.618,
this->pointMeterCenter_scale*0.15,//圆角用椭圆宽、高表示,选长宽的0.15
this->pointMeterCenter_scale*.61*0.15
);
setorigin(pointMeterCenter_x, //为方便指针作图,将原点下移圆角矩形的1/3
pointMeterCenter_y+this->pointMeterCenter_scale/2*RATIO_A*0.618*0.33);
float R_out=this->pointMeterCenter_scale/3.45;//此处,选择float是为了保证中间计算过程的精度,实际使用时仍是int
float R_mid=this->pointMeterCenter_scale/3.85;
float R_in =this->pointMeterCenter_scale/4.35;
float R_center=this->pointMeterCenter_scale/25;//这里的3.45 3.85 4.35 25几个数字是依美观效果选的
int count=0;
for(float degree=16;degree<=166;degree=degree+5.0f)//在16度至166度之间每隔5度画一刻度线
{
int x_out=R_out*cos(degree/180*3.1415); //out刻度线外轮廓半径
int y_out=R_out*sin(degree/180*3.1415);
int x_mid=R_mid*cos(degree/180*3.1415); //mid刻度线中间轮廓半径
int y_mid=R_mid*sin(degree/180*3.1415);
int x_in=R_in*cos(degree/180*3.1415); //mid刻度线内轮廓半径
int y_in=R_in*sin(degree/180*3.1415);
line(x_mid,y_mid,x_out,y_out); //画出刻度线
if(count%5==0){ line(x_in,y_in,x_out,y_out);} //每间隔4个短刻度线画一长刻度线
count+=1;//计数
}
//以下画指针,指针位置用随机数
int a=rand()%36;
double P_degree=3.1415*(a+90-18)/180; //指针在垂直方向+-18度之间
double point_x2=R_mid*cos(P_degree);
double point_y2=R_mid*sin(P_degree);
double point_x1=R_center*cos(P_degree);
double point_y1=R_center*sin(P_degree);
double point_x0=-R_center*cos(P_degree);
double point_y0=-R_center*sin(P_degree);
setlinecolor(RED);//指针颜色红色
//下一行的设置中使用了三目运算,保证指针宽度不低于1或2个像素
setlinestyle(0,(this->pointMeterCenter_scale/200 > 1 ? this->pointMeterCenter_scale/300 : 1));//指针前端细一些
line((int)point_x1,(int)point_y1,(int)point_x2,(int)point_y2); //画指针前段
setlinestyle(0,(this->pointMeterCenter_scale/100> 2 ? this->pointMeterCenter_scale/150 : 2));//指针靠近圆心部分宽一些
line((int)point_x0,(int)point_y0,(int)point_x1,(int)point_y1);//画指针靠近圆心部分
setfillcolor(RED);
fillcircle(0,0,(this->pointMeterCenter_scale/100> 2 ? this->pointMeterCenter_scale/150 : 4)); //指针转动圆心
setfillcolor(BLACK);
fillcircle(0,0,(this->pointMeterCenter_scale/100> 2 ? this->pointMeterCenter_scale/150 :2)); //指针转动中心造型
//以下标出仪表盘上的文字
char text0[]="指针式仪表盘模拟";
char text1[]="仪表指针";
setaspectratio(1,1); //将y正方向调整为向上
setbkmode(TRANSPARENT); //背景透明模式
settextcolor(BLACK); //文字颜色
settextstyle((int)R_center*1.4,0,"仿宋"); //这里字体高度都是可变的,在函数调用时随表盘的大小变化
outtextxy(0-textwidth(text0)/2,-(int)R_center*9.5,text0);
settextstyle((int)R_center,0,"仿宋");
settextcolor(RED);
outtextxy(0-textwidth(text1)/2,(int)R_center*1.8,text1);
Sleep(200);
}
int main()
{
srand((int)time(NULL)); //设置随机数种子
PointMeter pm(400,380,700); //实例化一个仪表盘类,并赋初值
initgraph(pm.pointMeterCenter_scale*1.2,pm.pointMeterCenter_scale,1);//初始化一个比仪表盘大一些的窗口
//下面循环显示指针式仪表盘模拟工作
while(TRUE)
{
BeginBatchDraw();//防止屏闪
pm.drawMeterPanel();
EndBatchDraw();
}
closegraph();
getchar();
return 0;
}