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

//-------------------------------------------------------------------------------------------------------------------
//农学小作业(根据降雨量计算排灌水量)(旱地版)
//01.参考书目:ISBN-7-80734-087-8.ISBN-7-80124-644-6.
//01.农作物生长发育阶段需要消耗水份.
//02.对旱作物:水份由降雨,灌溉和土壤湿润层保水量提供.
//03.当供水不足或供水过量都会影响农作物的生产发育,进而影响产量.
//04.对于旱地作物,相应于它的不同的生育阶段,都有一个最适宜的土壤含水率范围.
//05.土壤计划湿润层深度:旱作物农田实施灌水时,计划调节控制土壤水份状况的土层深度.
//06.灌水的额度:一般以作物的适宜土壤含水量下限作为是否需要灌水的衡量指标.
//07.排水的额度:一般旱作物是不太耐淹涝的,排水以适宜土壤含水量上限为宜.
//08.以上面的考虑进行每天的土壤含水量保持和水量平衡.       
//程序编制要求:
//1.提供作物生长发育阶段耗水量表,生长发育阶段降雨量表.
//2.要求绘制农作物每天土壤含水量线,排灌图表.
//--------------------------------------------------------------------------------------------------------------------
#include //包含Easyx模拟TC的BGI绘图库头文件
#include //包含数学运算头文件
#include //包含标准输入输出头文件
#include //包含输入输出头文件
#include //包含标准库头文件
#include //包含字符串函数头文件
#include //
//宏定义农作物数据------------------------------------------------------------
#define M 5//矩阵行数(作物生育阶段)
#define N 5//矩阵列数(每阶段天数及水量)
#define r_w_a 390//全生育期耗水量(mm)
#define d_start 20130615//生育期起始日期
#define w_start 120//起始土层含水量(mm)
#define th_start 300//起始湿润层厚度(mm)
#define th_incre 0.324//湿润层保水比率
#define d_pervasion 0.0//日平均渗透量(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]={//生育阶段天数+耗水百分比+期末土壤计划湿润厚度+适宜含水率下限+适宜含水率上限
	{23,20.2,400,19.44,32.4},//1.苗期
	{20,30,500,19.44,32.4},//2.拔节
	{22,22,600,19.44,32.4},//3.抽穗
	{25,20.5,700,19.44,32.4},//4.灌浆
	{10,7.3,700,19.44,32.4}//5.成熟
};//定义双精度数组(作物生育阶段耗水规律)
double b[M+1]={d_start};//日期数组
double c[M]={a[0][0]};//生长发育阶段累计天数
double incre[400]={0.0};//每天的湿润层增量
double thickness[400][10]={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,m=0,n=0,p=0;//定义整型变量
double mm,nn,pp;//
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 *l_r,double *h_r,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=a[int(d2-1)][1];//4.需水百分比
					d5=r_w_a*d4*0.01/(1.0*d3);//5.每天耗水量
					d11=every_d_r[date][1];//11.当天降雨量
					d6=incre[date];//6.计划湿润层厚度增量
					d7=thickness[date][1];//7.日初润湿层厚度
					d8=thickness[date][2];//8.日末润湿层厚度
					d9=thickness[date][3];//9.适宜含水量下限
					d10=thickness[date][4];//10.适宜含水量上限
					d12=incre[date]*th_incre;//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 20130615 46.7
002 20130624 11.4
003 20130629 11.8
004 20130702 8.9
005 20130703 9.1
006 20130724 7.3
007 20130813 27.1
008 20130818 20.7
009 20130827 14.6
010 20130828 1.2
011 20130830 5.4
012 20130905 5.0
013 20130908 9.2
*/
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:\\rain1.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.当前阶段耗水百分比:");//输出字符串模拟控件文字
	outtextxy(c_x1+10,H-DH-18*c_h+10,"5.当前每天耗水量(mm):");//输出字符串模拟控件文字
    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.当天耗水量(L)");//写控件字符串
	outtextxy(W-DW-DC+0.4*DC,H-DH-3*c_h+10,"5.当天降雨量(L)");//写控件字符串
	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 l_r,h_r,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 <= up)//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 > up)//3.需要排水
		{
			flag=2;
			drain=current_n-up;//排水量
			current_f=up;//当天末了水位
		}
        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.画y2轴刻度标线及文字(耗水量)-----------------------------------------------
	for(i=0;i<=10.0;i++)
	{
		setcolor(c2);//水平辅助线颜色
		line(DW,DD+ystep*i,W-DW-DC,DD+ystep*i);//画水平小刻度线
		setcolor(c3);//文字颜色
		value=1000.0-ystep*(10.0-i)*1000.0/(H-DH-DD);//所在的刻度数值
		gcvt(value,3,stt);//将浮点数value转换为字符串stt
		outtextxy(W-2*DW-DC-15,DD+ystep*i+5,stt);//在规定的位置放置字符串
	}//结束for
	//e.绘制降雨量------------------------------------------------------------------
	for(i=0;i0){setcolor(cc7);}
		if(every_d_w[i][3] <0){setcolor(cc8);}
		if(every_d_w[i][3] !=0)
		{
			line(DW+xstep*(i+0.5),DD+ystep*0.01*every_d_w[i][1],DW+xstep*(i+0.5),DD+ystep*0.01*(every_d_w[i][1]+every_d_w[i][3]));//画竖直小刻度线
		}//结束if
	}//结束for	
	//7.重新绘制工作区边框
	setcolor(c3);
	rectangle(DW,DD,W-DW,H-DH);//外边框
	rectangle(W-DW-DC,DD,W-DW,H-DH);//控件区域边框	
}//结束子函数
//根据天数返回:(下限率+上限率+耗水量)
void phase(double i,double *l_r,double *h_r,double *cost)//根据天数返回:(下限率+上限率+耗水量)
{
	if(i>=0 && i=c[0] && i=c[1] && i=c[2] && i=c[3] && i=0 && i=c[0] && i=c[1] && i=c[2] && i=c[3] && i

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

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