农学小作业(根据降雨量计算排灌水量)

//-------------------------------------------------------------------------------------------------------------------
//农学小作业(根据降雨量计算排灌水量)
//01.参考书目:ISBN-7-80734-087-8.
//01.农作物生长发育阶段需要消耗水份.
//02.水份由降雨和灌溉提供.
//03.当供水不足或供水过量都会影响农作物的生产发育,进而影响产量.
//04.供水的额度:以不超过适宜上限,不低于适宜下限为宜.
//05.当降雨充沛,水位超高,需要进行排水.
//06.排水的额度:以不高于允许蓄水深度为宜.
//07.以上面的考虑进行每天的水位保持和水量平衡.       
//程序编制要求:
//1.提供作物生长发育阶段耗水量表,生长发育阶段降雨量表.
//2.要求绘制农作物每天水位线,排灌图表.
//--------------------------------------------------------------------------------------------------------------------
#include //包含Easyx模拟TC的BGI绘图库头文件
#include //包含数学运算头文件
#include //包含标准输入输出头文件
#include //包含输入输出头文件
#include //包含标准库头文件
#include //包含字符串函数头文件
#include //
//宏定义农作物数据------------------------------------------------------------
#define M 7//矩阵行数(作物生育阶段)
#define N 5//矩阵列数(每阶段天数及水量)
#define r_w_a 435//全生育期耗水量(mm)
#define d_start 20130425//生育期起始日期
#define w_start 20//起始水层厚度(mm)
#define d_pervasion 1.5//日平均渗透量(mm)
//宏定义窗口格式数据----------------------------------------------------------
#define DD 40//宏定义标题边框距离
#define DW 10//宏定义宽度边框距离
#define DH 10//宏定义高度边框距离
#define DC 200//宏定义控件区域宽度
#define c1 RGB(38,47,86)//宏定义辅助线颜色1
#define c2 RGB(38,47,86)//宏定义辅助线颜色2
#define c3 RGB(255,255,255)//宏定义文字及边框颜色
#define cc1 RGB(255,0,0)//宏定义曲线颜色1(红色)
#define cc2 RGB(0,255,0)//宏定义曲线颜色2(绿色)
#define cc3 RGB(0,0,255)//宏定义曲线颜色3(蓝色)
#define cc4 RGB(255,255,0)//宏定义曲线颜色4(黄色)
#define cc5 RGB(0,255,255)//宏定义曲线颜色5(青色)
#define cc6 RGB(0,255,0)//宏定义曲线颜色6(绿色)
#define cc7 RGB(255,0,255)//宏定义曲线颜色7(品红)
#define cc8 RGB(0,0,255)//宏定义曲线颜色8(蓝色)
//定义结构体-------------------------------------------------------------------------------------------------------
//定义结构体
struct node
{
	int numberical;//序号
    long serialnumber;//日期
    char date[10];//降雨量数据
    struct node *next;//链表指针
};//结束结构体定义
//定义农作物全局变量------------------------------------------------------------------------------------------------
static double a[M][N]={//生育阶段天数+耗水百分比+适宜水层下限+适宜水层上限+允许最大蓄水深度
	{8,4.8,5,30.0,50.0},//1.返青
	{8,9.9,20.0,50.0,70.0},//2.分薛前
	{19,24.0,20.0,50.0,80.0},//3.分薛后
	{16,26.6,30.0,60.0,90.0},//4.拨节孕穗
	{13,22.4,10.0,30.0,80.0},//5.抽穗开花
	{11,7.1,10.0,30.0,60.0},//6.乳熟
	{8,5.2,10.0,20.0,20.0}//7.黄熟
};//定义双精度数组(作物生育阶段耗水规律)
double b[M+1]={d_start};//日期数组
double c[M]={a[0][0]};//生长发育阶段累计天数
double every_d_r[400][10]={0};//雨水量表
double every_d_w[400][10]={0};//水位量表	
double a_d=0,m_w=100.0;//全天数
int i=0,j=0,k=0;//定义整型变量
char is1[20],is2[20],is3[20],is4[20],is5[20],is6[20],is7[20],is8[20],is9[20],is10[20],is11[20],is12[20],is13[20],is14[20],is15[20];//
double d1,d2,d3,d4,d5,d6,d7,d8,d9,d10,d11,d12,d13,d14,d15;
struct node *create();//子函数原型声明
//定义窗口全局变量-------------------------------------------------------------------------------------------------
int W = GetSystemMetrics(SM_CXSCREEN);//获取整个屏幕右下角X坐标
int H = GetSystemMetrics(SM_CYSCREEN);//屏幕Y坐标
double xstep;
double ystep;
int c_h=26;//定义控件高度
int c_x1=W-DW-DC,c_x2=W-DW;//控件左右x坐标
int c_y1=H-DH;//第1个控件下y坐标	
//函数声明---------------------------------------------------------------------------------------------------------
double r_m_d(double d);//日期函数
void sub_frame();//绘制框架子函数
void sub_calculate();//计算数据子函数
void rain_table();//获取降雨量图表
void phase(double i,double *low,double *up,double *plenty,double *cost);//
void phase1(double i,double *d1,double *d2);//
void sub_text();//
//主函数-----------------------------------------------------------------------------------------------------------
void main()
{
	rain_table();//获得降雨量图表
	//1.获得全生育阶段天数------------------------------
	for(i=0;i=DW && m.x<=W-DW-DC)
				{
					sub_calculate();//调用计算绘图函数
					//根据鼠标位置获得日期
					int date=(m.x-DW)/xstep;
					phase1(date,&d1,&d2);//1.日期+2.阶段编号
					d3=a[int(d2-1)][0];//3.天数
					d4=r_w_a;//4.总水量
					d5=a[int(d2-1)][1];//5.需水百分比
					d6=d5*d4*0.01;//6.当前阶段耗水量
					d7=d6/(1.0*d3);//7.每天耗水量
					d8=a[int(d2-1)][2];//8.适宜水层下限
                    d9=a[int(d2-1)][3];//9.适宜水层上限
					d10=a[int(d2-1)][4];//10.允许蓄水深度
					d11=every_d_r[date][1];//11.当天降雨量
					d12=d_pervasion;//12.当天渗透量
					d13=every_d_w[date][1];//13.排灌前水层
					d14=every_d_w[date][3];//14.需排灌水层
					d15=every_d_w[date][2];//15.排灌后水层
					sub_text();//字符函数
				}//结束if
				break;//
			}//结束case(结束鼠标左键单击事件消息处理)
		case WM_RBUTTONDOWN://鼠标移动的时候画个空心的圆
			return;//返回while
		}//结束switch(结束鼠标消息)
	}//结束while
}//结束主函数
double r_m_d(double d)
{
	//1.取年月日
	double d1;//
	int year=0,month=0,day=0,leap=0;//年月日,(闰年2月29天)(平年2月29天)
	year=d/10000;//年
    month=(d-year*10000)/100;//月
	day=(d-year*10000-month*100);//日
	//cout<<"年_"<31){day=day-31;month++;}
	if(month==2&&day>28&&leap==0){day=day-28;month++;}
	if(month==2&&day>29&&leap==1){day=day-29;month++;}
	if(month==3&&day>31){day=day-31;month++;}
	if(month==4&&day>30){day=day-30;month++;}
	if(month==5&&day>31){day=day-31;month++;}
	if(month==6&&day>30){day=day-30;month++;}
	if(month==7&&day>31){day=day-31;month++;}
	if(month==8&&day>31){day=day-31;month++;}
	if(month==9&&day>30){day=day-30;month++;}
	if(month==10&&day>31){day=day-31;month++;}
	if(month==11&&day>30){day=day-30;month++;}
	if(month==12&&day>31){day=day-31;month=month-12;year++;}
	//返回日期------------------------------------------------------
	d1=year*10000+month*100+day;
	return d1;
}//结束子函数
//-------------------------------------------------------------------------------------------------------------------
//读入txt文件到链表的函数
/* 以下是rain.txt文本文件保持原来格式
001 20130427 1.0
002 20130428 23.5
003 20130429 9.3
004 20130504 3.3
005 20130505 4.0
006 20130506 4.4
007 20130508 2.7
008 20130509 7.6
009 20130514 20.9
010 20130515 1.8
011 20130520 8.4
012 20130523 2.5
013 20130524 2.3
014 20130531 8.5
015 20130603 2.2
016 20130604 11.2
017 20130605 23.4
018 20130610 9.0
019 20130612 0.7
020 20130616 1.0
021 20130617 20.1
022 20130618 51.6
023 20130625 26.3
024 20130626 2.2
025 20130629 3.2
026 20130707 8.4
*/
void rain_table()
{
	struct node *q;//定义链表指针
	q=create();//调用函数读取txt文件到链表,并获取链表首地址	
}//结束主函数
//子函数
struct node *create()
{
	FILE *fp;//定义文件指针
	struct node *head,*tail,*p;//定义三个链表指针
	char bal[30];//定义字符数组
	int i,j=0,m=0,n=0;//定义整型变量
	int max=0;//定义整型变量
	head=tail=NULL;//初始化为空
	//1.打开文件-----------------------------------------------
	if(!(fp=fopen("d:\\rain.txt","r")))//如果打开文件失败
	{
		printf("cannot open file,\n");//输出提示
		exit(1);//退出
	}//结束if
	//2.读取文件-----------------------------------------------
	while(!feof(fp))//如果没有到文件结尾
	{
		p=(struct node *)malloc(sizeof(struct node));//分配内存区域
		m=0;//
		n=0;//
		j=0;//
		if(fgets(bal,19,fp))//从fp文件流中读取一行指定长度19的字符串到bal中
		{
			//fgets(char *buf,int bufsize,FILE *stream)
			//从文件结构体指针stream中读取数据,每次读取1行.
			//每次最多读取bufsize-1个字符(第bufsize个字符自动赋值为'\0'字符串结束符)
			//使用fgets()读取文件时,bufsize大于该行的字符总数+2(1个保存换行'\n',1个保存字符串结束符'\0').
			for(i=0;i<(int)strlen(bal);i++)//对字符串进行分类取值
			{
				if(i<3)//第1个字符
				{
					n=n*10+bal[i]-'0';//获得的字符累乘10进位得到数字标号(-'0'表示将字符转为数字)
					p->numberical=n;//存储为编号
				}
				else if(i>3&&i<12)//第5到12个字符
				{
					m=m*10+bal[i]-'0';//获得的字符累乘10进位得到数字标号(-'0'表示将字符转为数字)
					p->serialnumber=m;//存储为编号
				}
				else if(i>12 && i<17)//第14到17个字符
				{
					p->date[j]=bal[i];//存储为数据字符
					j++;//
				}//结束if_elseif
			}//结束for
			p->date[4]='\0';//数据字符读完加上结束符
			p->next=NULL;//指针指向为空
			//将读入的表添加到链表中---------------------------
			if(head==NULL)//如果是读第1个表
				head=tail=p;//为head指针和tail指针赋初值
			else//剩下的表(中间的表+最后1个表)
			{
				tail->next=p;//将新读入的表存储到链表尾端
				tail=p;//更新尾部指针
			}//结束if(添加链表)--------------------------------
		}//结束if(读取1行)
	}//结束while(读取文件结束)
	//3.关闭文件并返回链表指针--------------------------------------
	fclose(fp);//关闭文件
	return(head);//返回链表的头指针
}//结束子函数*/
//---------------------------------------------------------------------------------------------------------------
//绘制框架子函数
void sub_frame()
{
	//1.全屏效果---------------------------------------------------------------------------
	initgraph(W,H);//初始化绘图窗口
	HWND hWnd = GetHWnd();//获取窗口句柄
	LONG style = GetWindowLong(hWnd,-16);//获得窗口风格
	style = style & ~WS_CAPTION & ~WS_SIZEBOX; //窗口全屏显示且不可改变大小
	SetWindowLong(hWnd,-16,style);//设置窗口风格
	SetWindowPos(hWnd, NULL,0,0,W,H,SWP_NOZORDER);//改变窗口位置,尺寸和Z序
	//ShowCursor(FALSE);//显示时隐藏鼠标
	//------------------------------------------------------------------------------------
	//2.绘制工作区边框
	setcolor(c3);
	rectangle(DW,DD,W-DW,H-DH);//外边框
	rectangle(W-DW-DC,DD,W-DW,H-DH);//控件区域边框
	//3.输出标题
	setfont(16,0,"黑体");
	outtextxy(5,10,"农学小作业(根据降雨量计算排灌水量)");
	//4.输出简单说明
	RECT r={W-DW-DC+10,DD+10,W-DW-10,H-DH-10};//
	setfont(12,0,"宋体");//
	drawtext("农学小作业:\n \n \
				根据降雨量计算排灌水量\
				\
				\n\n\
				操作说明:\n\n\
				鼠标左键  : 数据输入\n\
				鼠标右键  : 退出程序\n\
			\n\
			左键在工作区选择日期,查询当日水量及排灌量\n\
			\n\n\
			\n\n\
			\
			\n", &r, DT_WORDBREAK);//
	//5.调整说明文字下面的矩形控件
	for(int i=1;i<=22;i++)
	{
		rectangle(c_x1,c_y1,c_x2,c_y1-c_h);//
		c_y1=c_y1-c_h;
	}//结束for
	//6.绘制控件说明文字
	outtextxy(c_x1+10,H-DH-22*c_h+10,"1.选择日期:");//输出字符串模拟控件文字
	outtextxy(c_x1+10,H-DH-21*c_h+10,"2.作物生育阶段:");//输出字符串模拟控件文字
	outtextxy(c_x1+10,H-DH-20*c_h+10,"3.当前阶段天数:");//输出字符串模拟控件文字
    outtextxy(c_x1+10,H-DH-19*c_h+10,"4.作物总耗水量(mm):");//输出字符串模拟控件文字
	outtextxy(c_x1+10,H-DH-18*c_h+10,"5.当前阶段耗水百分比:");//输出字符串模拟控件文字
	outtextxy(c_x1+10,H-DH-17*c_h+10,"6.当前阶段耗水量(mm):");//输出字符串模拟控件文字
	outtextxy(c_x1+10,H-DH-16*c_h+10,"7.当前每天耗水量(mm):");//输出字符串模拟控件文字    
	outtextxy(c_x1+10,H-DH-15*c_h+10,"8.适宜水层下限(mm):");//输出字符串模拟控件文字
	outtextxy(c_x1+10,H-DH-14*c_h+10,"9.适宜水层上限(mm):");//输出字符串模拟控件文字
	outtextxy(c_x1+10,H-DH-13*c_h+10,"10.允许蓄水深度(mm):");//输出字符串模拟控件文字
	outtextxy(c_x1+10,H-DH-12*c_h+10,"11.当天降雨量(mm):");//输出字符串模拟控件文字
	outtextxy(c_x1+10,H-DH-11*c_h+10,"12.当天渗透量(mm):");//输出字符串模拟控件文字
	outtextxy(c_x1+10,H-DH-10*c_h+10,"13.排灌前水层(mm):");//输出字符串模拟控件文字
    outtextxy(c_x1+10,H-DH-9*c_h+10,"14.需排灌水层(mm):");//输出字符串模拟控件文字
	outtextxy(c_x1+10,H-DH-8*c_h+10,"15.排灌后水层(mm):");//输出字符串模拟控件文字
	//7.初始化原始数据
	//------------------------------------------------------------
    setcolor(cc1);//说明曲线颜色
	line(W-DW-DC+10,H-DH-7*c_h+15,W-DW-DC+0.35*DC,H-DH-7*c_h+15);
	setcolor(cc2);//说明曲线颜色
	line(W-DW-DC+10,H-DH-6*c_h+15,W-DW-DC+0.35*DC,H-DH-6*c_h+15);
	setcolor(cc3);//说明曲线颜色
	line(W-DW-DC+10,H-DH-5*c_h+15,W-DW-DC+0.35*DC,H-DH-5*c_h+15);
	setcolor(cc4);//说明曲线颜色
	line(W-DW-DC+10,H-DH-4*c_h+15,W-DW-DC+0.35*DC,H-DH-4*c_h+15);
	setcolor(cc5);//说明曲线颜色
	line(W-DW-DC+10,H-DH-3*c_h+15,W-DW-DC+0.35*DC,H-DH-3*c_h+15);
	setcolor(cc6);//说明曲线颜色
	line(W-DW-DC+10,H-DH-2*c_h+15,W-DW-DC+0.35*DC,H-DH-2*c_h+15);
	setcolor(cc7);//说明曲线颜色
	line(W-DW-DC+10,H-DH-1*c_h+15,W-DW-DC+0.35*DC,H-DH-1*c_h+15);
	//------------------------------------------------------------
	setcolor(c3);//说明文字颜色
	outtextxy(W-DW-DC+0.4*DC,H-DH-7*c_h+10,"1.适宜水层下限");//写控件字符串
    outtextxy(W-DW-DC+0.4*DC,H-DH-6*c_h+10,"2.适宜水层上限");//写控件字符串
	outtextxy(W-DW-DC+0.4*DC,H-DH-5*c_h+10,"3.允许水层深度");//写控件字符串
	outtextxy(W-DW-DC+0.4*DC,H-DH-4*c_h+10,"4.当天耗水量");//写控件字符串
	outtextxy(W-DW-DC+0.4*DC,H-DH-3*c_h+10,"5.当天降雨量");//写控件字符串
	outtextxy(W-DW-DC+0.4*DC,H-DH-2*c_h+10,"6.当天水位线");//写控件字符串
	outtextxy(W-DW-DC+0.4*DC,H-DH-1*c_h+10,"7.当天排灌量");//写控件字符串
	//------------------------------------------------------------
}//结束子程序
//计算数据子函数
void sub_calculate()
{
	//1.计算变量初始化==-------------------------------------------------------------
	int flag;
	double d_current,d_next,current,d_f;//
	double low,up,plenty,drain,fill,cost;//下限+上限+超高+当前+排水+灌水+耗水
	double low1,up1,plenty1,drain1,fill1,cost1;
	double d_plus,d_minus,d_drain,d_fill,current_n,current_f;//
	double d_plus1,d_minus1,d_drain1,d_fill1,current_n1,current_f1;//
	//2.生长发育阶段累计天数---------------------------------------------------------
	for(i=0;iserialnumber == every_d_r[i][0]){every_d_r[i][1]=atof(q->date);}//按照日期存储雨水量
		}//结束for
		q=q->next;//链表中的下个表
	}//结束while
	//5.绘制当天水位线及计算当天排灌量-----------------------------------------------
	d_current=d_start;//起始日期
	current=w_start;//起始水位
	for(i=0;i low && current_n <= plenty)//1.不需要人工干预
		{
			flag=0;
			current_f=current_n;//当天末了水位
		}
		else if(current_n <= low)//2.需要灌水
		{
			flag=1;
			fill=up-current_n;//灌水量
			current_f=up;//当天末了水位
		}
		else if(current_n > plenty)//3.需要排水
		{
			flag=2;
			drain=current_n-plenty;//排水量
			current_f=plenty;//当天末了水位
		}
        switch(flag)
		{
		case 0:current_f=current_n;break;//
		case 1:current_f=current_n+fill;break;//
		case 2:current_f=current_n-drain;break;//
		default:printf("data error.");break;//
		}//结束switch
		//存储当前日期和起始水位和末了水位
		every_d_w[i][0]=d_current;//
		every_d_w[i][1]=current;//
		every_d_w[i][2]=current_f;//
		//存储当前日期排灌水位
		switch(flag)
		{
		case 0:d_f=0;break;//
		case 1:d_f=fill;break;//
		case 2:d_f=-drain;break;//
		default:printf("data error.");break;//
		}//结束switch
		every_d_w[i][3]=d_f;//
		//------------------------------------------------------------
		current=current_f;//下个当前日水位
		d_current=d_current+1;//逐日计算(下个当前日日期)
	}//结束for
	//6.绘制工作区坐标线
	//a.画x1轴刻度标线及文字(作物生长日期每天)--------------------------------------
	double value;//定义双精度变量
	char stt[10];//定义字符数组
	int acc_d=0;//累加天数
	xstep=(W-2*DW-DC)/(1.0*a_d);//x方向步长(nx个刻度)(对应的绘图单位)
	ystep=(H-DH-DD)/(10.0);//y方向步长(ny个刻度)(对应的绘图单位)
	for(int i=0;i<=a_d;i++)
	{
		setcolor(c1);//颜色
		line(DW+xstep*i,H-DH,DW+xstep*i,DD);//画竖直小刻度线
	}//结束for
    //b.画x2轴刻度标线及文字(作物生长日期每阶段)---------------------------
	outtextxy(DW+xstep*acc_d-10,H-DH-20,gcvt(b[0],8,stt));//在规定的位置放置字符串
	for(i=0;i<=M;i++)
	{
		setcolor(c3);//竖直辅助线颜色
		line(DW+xstep*acc_d,H-DH,DW+xstep*acc_d,DD);//画竖直小刻度线
		acc_d=acc_d+a[i][0];//累加天数
		setcolor(c3);//文字颜色
		value=b[i+1];//所在的刻度数值
		gcvt(value,8,stt);//将浮点数value转换为字符串stt
		outtextxy(DW+xstep*acc_d-10,H-DH-20,stt);//在规定的位置放置字符串
	}//结束for
	//c.画y1轴刻度标线及文字(耗水量)-----------------------------------------------
	for(i=0;i<=10.0;i++)
	{
		setcolor(c2);//水平辅助线颜色
		line(DW,DD+ystep*i,W-DW-DC,DD+ystep*i);//画水平小刻度线
		setcolor(c3);//文字颜色
		value=ystep*(10.0-i)*100.0/(H-DH-DD);//所在的刻度数值
		gcvt(value,3,stt);//将浮点数value转换为字符串stt
		outtextxy(DW+15,DD+ystep*i+5,stt);//在规定的位置放置字符串
	}//结束for
	//d.绘制适宜水层下限和上限-----------------------------------------------------
	acc_d=0;
	for(i=0;i<=M;i++)
	{
		setcolor(cc1);//1.适宜水层下限
		line(DW+xstep*acc_d,H-DH-ystep*0.1*a[i][2],DW+xstep*(acc_d+a[i][0]),H-DH-ystep*0.1*a[i][2]);//画竖直小刻度线
		setcolor(cc2);//2.适宜水层上限
		line(DW+xstep*acc_d,H-DH-ystep*0.1*a[i][3],DW+xstep*(acc_d+a[i][0]),H-DH-ystep*0.1*a[i][3]);//画竖直小刻度线
		setcolor(cc3);//3.允许水层深度
		line(DW+xstep*acc_d,H-DH-ystep*0.1*a[i][4],DW+xstep*(acc_d+a[i][0]),H-DH-ystep*0.1*a[i][4]);//画竖直小刻度线
		setcolor(cc4);//4.当天耗水量
		line(DW+xstep*acc_d,H-DH-ystep*0.1*(a[i][1]*r_w_a*0.01/a[i][0]+d_pervasion),DW+xstep*(acc_d+a[i][0]),H-DH-ystep*0.1*(a[i][1]*r_w_a*0.01/a[i][0]+d_pervasion));//画竖直小刻度线
		acc_d=acc_d+a[i][0];//累加天数
		//cout<0){setcolor(cc7);}
		if(every_d_w[i][3] <0){setcolor(cc8);}
		if(every_d_w[i][3] !=0)
		{
			line(DW+xstep*(i+0.5),H-DH-ystep*0.1*every_d_w[i][1],DW+xstep*(i+0.5),H-DH-ystep*0.1*(every_d_w[i][1]+every_d_w[i][3]));//画竖直小刻度线
		}//结束if
	}//结束for	
	//6.重新绘制工作区边框
	setcolor(c3);
	rectangle(DW,DD,W-DW,H-DH);//外边框
	rectangle(W-DW-DC,DD,W-DW,H-DH);//控件区域边框	
}//结束子函数
//返回耗水量的子函数
void phase(double i,double *low,double *up,double *plenty,double *cost)
{
	if(i>=0 && i=c[0] && i=c[1] && i=c[2] && i=c[3] && i=c[4] && i=c[5] && i=0 && i=c[0] && i=c[1] && i=c[2] && i=c[3] && i=c[4] && i=c[5] && i

农学小作业(根据降雨量计算排灌水量)_第1张图片

你可能感兴趣的:(算法,c++,数学建模,信息可视化)