C语言绘图小作业(根据型值表绘制船模型线图)

发布时间:2023年12月25日
//--------------------------------------------------------------------------------------------------
//C语言绘图小作业(根据型值表绘制船模型线图)
//题目描述:
//01.参考书目:ISBN 7-313-00140-1.
//01.绘制船模型必须依赖型值表和型线图.型线图由三部分组成:横剖线图,半宽水线图,纵剖线图.
//[横剖线图]--------------------------------------------------------
//01.沿船长度方向20等分,取21个等间距的横截面,共有21个站号(对小船取10等分,11个站号).
//02.将各横剖面所截的表面曲线(横剖线)叠置在中站面上,即得到横剖线图.
//03.对民用船,习惯上0~10为尾半段,10~20为首半段,第10站即为中剖面.
//04.由于船体左右对称,每一横剖线只需画出半边即可.习惯上,将尾半段(0~10)画在左边,首半段(10~20)画在右边.
//05.在船体首尾两端,线型变化较大,为了提高其精确性,常在首尾端再增添(1/2)站距的横剖线.
//06.为了使图面清晰,不画出甲板线和舷墙线,而只是将各甲板边缘和舷墙线的高度分别连接起来,称为甲板边线和舷墙顶线.
//[半宽水线图]------------------------------------------------------
//07.沿吃水方向平行于设计水线面取若干个等间距的水平截面(一般取7~9个).
//08.将各水平剖面所截的表面曲线(水线),叠置在同一水平面上.
//09.由于船体左右对称,每一水线面只画出半边即可,称为半宽水线图.
//10.还需画出上甲板边线,首楼甲板边线,舷墙顶线等水平投影,反映俯视轮廓.
//11.水线编号自基线向上分别用1,2,3...等数字编号;也可用水线距基平面的编号,如500mm水线...等.
//[纵剖线图]--------------------------------------------------------
//12.沿船宽方向平行于中线面,取2~4个纵截面,所截的表面曲线(纵剖线).
//13.叠置在中线面上即得纵剖线图.
//14.通常从中线面开始往舷侧编号,如I纵剖线,II...;也可用距中线面的距离编号,如1000面,2000面...等.
//15.还需画出龙骨线,首尾轮廓线,甲板边线,甲板中线和舷墙顶线的侧投影.
//[型线图]----------------------------------------------------------
//16.型线图由3组相互垂直的切面轮廓曲线所组成.
//17.每一组剖线在与它对应的投影面上为曲线(表达了它的真实形状),而在另外的两个投影面上为直线.
//18.型线的光顺:曲线的凹凸性和曲率的变化要求.要求三向光顺.
//19.有效的做法:控制曲面的重要部位(型值表的交叉点)开始,三向(至少两向)间隔交叉进行,使三向光顺经过一个逐步逼近的过程来完成.
//------------------------------------------------------------------------------------------------------------
//程序编制要求:
//1.给出型值表.
//2.绘制型线示意图.
//--------------------------------------------------------------------------------------------------------------------
#include <graphics.h>//包含Easyx模拟TC的BGI绘图库头文件
#include <math.h>//包含数学运算头文件
#include <iostream.h>//
#define DD 40//宏定义标题边框距离
#define DW 10//宏定义宽度边框距离
#define DH 10//宏定义高度边框距离
#define PI 3.1415926//宏定义圆周率
//宏定义型值表数据------------------------------------------------------------
#define LOA 75.0//船总长度(m)
#define LPP 70.0//垂线间长度(m)
#define B 13.4//型宽(m)
#define D 5.4//型深(m)
#define d 4.2//吃水深(m)
#define d1 4.58//水线面深度(m)
//---------------------------------------
#define M 23//矩阵行数(横截面站数)
#define N1 7//矩阵列数(水线剖面数)
#define N2 4//矩阵列数(纵剖面数)
#define P3 (LPP*1000.0/(M-3))//横剖面站距(mm)
//辅助颜色------------------------------------------
#define c1 RGB(38,47,86)//宏定义辅助线颜色1
#define c2 RGB(38,47,86)//宏定义辅助线颜色2
#define c3 RGB(255,255,255)//宏定义文字及边框颜色
//定义结构体(平面二维点)-------------------------------------------------------------------------------------------
typedef struct points//
{
	double x,y;//定义双精度变量
}DPOINT;//结束结构体
//定义结构体(平面三维点)-------------------------------------------------------------------------------------------
typedef struct points3
{
	double x,y,z,m,n;//定义双精度变量(前3个计算坐标+后2个投影坐标)
}DPOINT3;//结束结构体
//窗口全局变量-----------------------------------------------------------------------------------------------------
int W = GetSystemMetrics(SM_CXSCREEN);//获取整个屏幕右下角X坐标
int H = GetSystemMetrics(SM_CYSCREEN);//屏幕Y坐标 
int c_h=25;//定义控件高度
double c_xa=DW,dxa=(W-2.0*DW)/5.0;//控件x坐标及x坐标增量
double t_scale=(W-2.0*DW)/(H-DD-DH-c_h);//绘图区全局比例
//横剖面窗口全局变量
double x_1=DW+(W-2.0*DW)/2.0;//片区1起点x
double y_1=H-DH;//片区1起点y
double xscale_1=1.0*(W-2.0*DW)/(B*1000.0);//片区1比例x
double yscale_1=1.0*(H-DD-DH-c_h)/(d1*1000.0);//片区1比例y
double scale_1=((1.0*B)/d1 >= t_scale) ? xscale_1:yscale_1;//片区1全局比例
//半宽水线面窗口全局变量
double x_2=DW;//片区2起点x
double y_2=H-DH;//片区2起点y
double xscale_2=1.0*(W-2.0*DW)/(LPP*1000.0);//片区2比例x
double yscale_2=1.0*(H-DD-DH-c_h)/(0.5*B*1000.0);//片区2比例y
double scale_2=(LPP/(0.5*B) >= t_scale) ? xscale_2:yscale_2;//片区2全局比例
//纵剖面窗口全局变量
double x_3=DW;//片区3起点x
double y_3=H-DH;//片区3起点y
double xscale_3=1.0*(W-2.0*DW)/(LPP*1000.0);//片区3比例x
double yscale_3=1.0*(H-DD-DH-c_h)/(d1*1000.0);//片区3比例y
double scale_3=(LPP/(1.0*d1) >= t_scale) ? xscale_3:yscale_3;//片区3全局比例
//三维示意面窗口全局变量
double aaa=(4.65/5.0);//宏定义三维原点占x比例
double bbb=(4.0/5.0);//宏定义三维原点占y比例
double x_4=DW+(W-2.0*DW)*(1-aaa);//三维原点x位置
double y_4=(DD+c_h)+bbb*(H-DD-DH-c_h);//三维原点y位置
double xscale_4=aaa*(W-2.0*DW)/(LPP*1000.0);//片区4比例x
double scale_4=xscale_4;//片区4全局比例
double d_B=(0.5*B*1000)*scale_4*(sqrt(2.0)/4.0);//型宽投影增量
double d_B1=1.0*scale_4*(sqrt(2.0)/4.0);//型宽投影增量
double xmin=x_4-d_B;//
double ymin=y_4+d_B;//
//型值表数据全局变量-----------------------------------------------------------------------------------------------
static double ar_a[M][N1+N2]={//
	{0,0,0,0,0,1450,2450,4000,4250,4960,6080},//0.
	{0,0,0,0,0,2240,3095,3730,4000,4650,5635},//(0.5).
	{200,550,770,980,1255,3015,3720,0,3525,4280,5310},//1.
	{760,1690,2050,2595,3200,4430,4875,0,420,3000,4520},//2.
	{1660,2850,3360,4085,4740,5540,5790,0,0,825,3020},//3.
	{2700,3990,4585,5310,5830,6260,6380,0,0,110,1240},//4.
	{3730,4985,5540,6115,6395,6575,6630,0,0,0,380},//5.
	{4540,5700,6150,6550,6640,6685,6700,0,0,0,40},//6.
	{4965,6100,6480,6700,6700,6700,6700,0,0,0,0},//7.
	{5200,6300,6590,6700,6700,6700,6700,0,0,0,0},//8.
	{5200,6300,6590,6700,6700,6700,6700,0,0,0,0},//9.
	{5200,6300,6590,6700,6700,6700,6700,0,0,0,0},//10.
	{5000,6180,6520,6700,6700,6700,6700,0,0,0,0},//11.
	{4615,5965,6380,6700,6700,6700,6700,0,0,0,0},//12.
	{4045,5630,6140,6600,6700,6700,6700,0,0,0,110},//13.
	{3280,5100,5730,6300,6580,6700,6700,0,0,0,330},//14.
	{2345,4360,5055,5790,6250,6570,6600,0,0,90,780},//15.
	{1415,3420,4140,4935,5565,6160,6360,0,25,390,1790},//16.
	{655,2365,2970,3735,4415,5260,5680,0,160,1275,3580},//17.
	{220,1325,1760,2345,2940,3855,4300,0,790,3385,4990},//18.
	{0,380,630,1020,1420,2120,2470,200,3375,5170,7310},//19.
	{0,0,0,420,690,1200,1450,1000,4780,6480,0},//19.5
	{0,0,0,0,0,0,390,4200,6270,8500,0}//20.
};//定义双精度数组(型值表)
static double ar_b[M]={0,0.5,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,19.5,20};//横剖面站号
static double ar_c[N1]={0,500,1000,2000,3000,4200,4580};//水线面
static double ar_d[N2]={0,1600,3200,4800};//纵剖面
//横截面点表数组-----------------------------------
DPOINT3 cr_sec[M][N1+N2];//初始点表
DPOINT3 cr_sec1[M][N1+N2];//点表(坐标转换)
DPOINT3 cr_sec2[M][N1+N2];//点表(截取排序)
double cr_eft[M];//点表(有效点数)
//水线面点表数组-----------------------------------
DPOINT3 wl_sec[N1][M];//初始点表
DPOINT3 wl_sec1[N1][M];//点表(坐标转换)
//纵截面点表数组-----------------------------------
DPOINT3 pt_sec[N2][M];//定义纵截面点表
DPOINT3 pt_sec1[N2][M];//点表(坐标转换)	
double color1[M]={
			      //左侧(0~10)船首(红橙黄)
			      RGB(243,0,0),//0.
			      RGB(243,109,0),//0.5.
			      RGB(243,183,0),//1.
				  RGB(154,243,0),//2.  
				  RGB(0,243,109),//3.
				  RGB(0,242,205),//4.
				  RGB(0,143,243),//5.
				  RGB(0,34,243),//6.
				  RGB(120,0,243),//7.
				  RGB(223,0,243),//8.
				  RGB(242,0,120),//9.
				  RGB(255,255,255),//10.
				  //右侧(10~20)船首(绿青蓝)
				  RGB(255,0,0),//11.纯红
			      RGB(178,34,34),//12.耐火砖
			      RGB(255,140,0),//13.深橙
				  RGB(222,184,135),//14.硬木
				  RGB(255,255,0),//15.纯黄
				  RGB(255,250,205),//16.柠檬黄
				  RGB(0,255,0),//17.闪光绿
				  RGB(0,128,0),//18.纯绿
				  RGB(0,255,255),//19.青
				  RGB(0,128,128),//19.5水鸭色
				  RGB(0,0,255)//20.蓝色
};//横截面颜色数组
//全局变量--------------------------------------------------------------------------------------------------------
int i,j,k,flag,flag1;//
double value;//定义双精度变量
char stt[10];//定义字符数组	
//函数声明---------------------------------------------------------------------------------------------------------
void sub_frame();//绘制框架子函数
void sub_calculate();//计算数据子函数
void trans1(double x0,double y0,double *x1,double *y1);//坐标变换(绘制坐标用)
void trans1a(double x0,double y0,double *x1,double *y1);//坐标变换(绘制坐标用)
void trans2(double x0,double y0,double *x1,double *y1);//坐标变换(绘制坐标用)
void trans3(double x0,double y0,double *x1,double *y1);//坐标变换(绘制坐标用)
void fuc_trans1(DPOINT3 pa,DPOINT3 pb,int flag1,DPOINT3 *pa1,DPOINT3 *pb1);//坐标变换(绘制曲线用)
void cross1(double x1,double y1,double sec,double cc);//交叉点样式1
void hline(double x1,double y1,double dx,double cc);//根据起点长度间距和颜色绘制线段(水平颜色标线)
void cr_sort();//对横截面点表排序
void get_cr_data();//获取横截面点表
void get_wl_data();//获取水线面点表
void get_pt_data();//获取水线面点表
void draw_cr_1(int i);//绘制特定截面横剖面线
void draw_wl_1(int i);//绘制特定截面水线面线
void draw_pt_1(int i);//绘制特定截面纵截面线
void func_draw1();//绘制横剖面图
void func_draw2();//绘制半宽水线图
void func_draw3();//绘制纵剖面图
void dline(DPOINT3 x1,DPOINT3 x2,double cc);//根据两点和颜色绘制线段(辅助线和轮廓线)
void cr_cl(DPOINT3 p1,DPOINT3 p2,double ang1,double ang2,int flag1,double cc);//绘制方向角渐变的曲线(一阶导数连续)
//主函数-----------------------------------------------------------------------------------------------------------
void main()
{
	sub_frame();//绘图初始化
	MOUSEMSG m;//定义鼠标消息 
	while(true)//循环
	{
		m=GetMouseMsg();//获取一条鼠标消息 
		switch(m.uMsg)//根据获得的消息选择分支
		{
		case WM_LBUTTONDOWN://鼠标左键单击时判断数据输入
			{
				//判断鼠标位置是否在指定的控件区域
				//A.获取原始数据(横坐标在输入区域时输入数据)------
				if(m.y>=DD && m.y<=DD+c_h)
				{
					//1.[船模]横剖线图:----------------------------------------
					if(m.x>=c_xa && m.y<=c_xa+1.0*dxa){flag=0;}//结束if
					//2.[船模]半宽水线图:--------------------------------------
					if(m.x>=c_xa+1.0*dxa && m.y<=c_xa+2.0*dxa){flag=1;}//结束if
					//3.[船模]纵剖线图:----------------------------------------
					if(m.x>=c_xa+2.0*dxa && m.y<=c_xa+3.0*dxa){flag=2;}//结束if
				}//结束if(横坐标在输入区域时输入数据)
				sub_frame();//重绘框架
				//B.计算并绘图(横坐标在绘图区域时计算绘图)--------
				if(m.x>=DW && m.x<=W-2.0*DW)
				{
					sub_calculate();//调用计算绘图函数
				}//结束if
				break;//
			}//结束case(结束鼠标左键单击事件消息处理)
		case WM_RBUTTONDOWN://鼠标移动的时候画个空心的圆
			return;//返回while
		}//结束switch(结束鼠标消息)
	}//结束while
}//结束主函数
//绘制框架子函数---------------------------------------------------------------------------------------------------
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序	
	//2.绘制工作区边框----------------------------------
	setcolor(c3);rectangle(DW,DD,W-DW,H-DH);//外边框
	setfont(16,0,"黑体");outtextxy(5,10,"C语言绘图小作业(根据型值表绘制船模型线图)");//输出标题
	//3.调整说明文字下面的矩形控件----------------------
	for(i=0;i<=4;i++)
	{
		rectangle(c_xa,DD,c_xa+dxa,DD+c_h);//
		c_xa=c_xa+dxa;
	}//结束for
	c_xa=DW;setfont(12,0,"宋体");//	
	//4.绘制控件说明文字---------------------------------
	outtextxy(c_xa+0.0*dxa+10,DD+10,"1.[船模]横剖线图:");//输出字符串模拟控件文字
	outtextxy(c_xa+1.0*dxa+10,DD+10,"2.[船模]半宽水线图:");//输出字符串模拟控件文字
	outtextxy(c_xa+2.0*dxa+10,DD+10,"3.[船模]纵剖线图:");//输出字符串模拟控件文字
	outtextxy(c_xa+3.0*dxa+10,DD+10,"4.[说明]船模使用不作依据:");//输出字符串模拟控件文字
	outtextxy(c_xa+4.0*dxa+10,DD+10,"5.[说明]左键选取目录,右键退出:");//输出字符串模拟控件文字
}//结束子程序
//计算数据子函数-----------------------------------------------------------------------------------------
void sub_calculate()
{
	if(flag == 0)
	{
		setfillcolor(GREEN);bar(c_xa+1.0*dxa-10,DD+10,c_xa+1.0*dxa-5,DD+20);//绘制颜色提示方块
		func_draw1();//绘制图形
	}//
	else if(flag == 1)
	{
		setfillcolor(GREEN);bar(c_xa+2.0*dxa-10,DD+10,c_xa+2.0*dxa-5,DD+20);//绘制颜色提示方块
		func_draw2();//绘制图形
	}//
	else if(flag == 2)
	{
		setfillcolor(GREEN);bar(c_xa+3.0*dxa-10,DD+10,c_xa+3.0*dxa-5,DD+20);//绘制颜色提示方块
		func_draw3();//绘制图形
	}//
}//结束子函数
//绘制横剖面图---------------------------------------------------------------------------------------
void func_draw1()
{
	//1.绘制工作区坐标线-----------------------
	for(i=0;i<N2;i++)//画x轴刻度标线及文字(纵剖面线)
	{
		setcolor(c1);//竖直辅助线颜色		
		line(x_1-scale_1*ar_d[i],H-DH,x_1-scale_1*ar_d[i],H-DH-ar_c[N1-1]*scale_1);//画竖直小刻度线(左侧)
		line(x_1+scale_1*ar_d[i],H-DH,x_1+scale_1*ar_d[i],H-DH-ar_c[N1-1]*scale_1);//画竖直小刻度线(右侧)
		setcolor(c3);value=ar_d[i];gcvt(value,6,stt);//文字颜色//所在的刻度数值//将浮点数value转换为字符串stt	
		outtextxy(x_1-scale_1*ar_d[i]-5,H-DH-20,stt);//在规定的位置放置字符串(左侧)
		outtextxy(x_1+scale_1*ar_d[i]-5,H-DH-20,stt);//在规定的位置放置字符串(右侧)
	}//结束for
		//补齐边线--------------
		setcolor(c1);//水平辅助线颜色
		line(x_1-scale_1*(B*0.5*1000.0),H-DH,x_1-scale_1*(B*0.5*1000.0),H-DH-ar_c[N1-1]*scale_1);//(左侧)
		line(x_1+scale_1*(B*0.5*1000.0),H-DH,x_1+scale_1*(B*0.5*1000.0),H-DH-ar_c[N1-1]*scale_1);//(右侧)
		setcolor(c3);value=B*0.5*1000.0;gcvt(value,5,stt);//文字颜色//所在的刻度数值//将浮点数value转换为字符串stt
		outtextxy(x_1-scale_1*(B*0.5*1000.0)-10,H-DH-20,stt);//(左侧)
		outtextxy(x_1+scale_1*(B*0.5*1000.0)-10,H-DH-20,stt);//(右侧)	
	for(i=0;i<=N1;i++)//画y轴刻度标线及文字(半宽水线剖面)-----
	{
		setcolor(c1);//水平辅助线颜色
		line(x_1,y_1-scale_1*ar_c[i],DW,y_1-scale_1*ar_c[i]);//画水平小刻度线(左侧)
		line(x_1,y_1-scale_1*ar_c[i],W-1.0*DW,y_1-scale_1*ar_c[i]);//画水平小刻度线(右侧)		
		setcolor(c3);value=ar_c[i];gcvt(value,5,stt);//文字颜色//所在的刻度数值//将浮点数value转换为字符串stt
		outtextxy(DW+5,y_1-scale_1*ar_c[i]-10,stt);//(左侧)
		outtextxy(W-1.0*DW-20,y_1-scale_1*ar_c[i]-10,stt);//(右侧)
	}//结束for
	//2.重新绘制工作区边框
	setcolor(c3);rectangle(DW,DD,W-DW,H-DH);//外边框
	//3.获取横截面点表
	get_cr_data();
	//4.绘制点表曲线
	for(int P=0;P<M;P++)
	{
		draw_cr_1(P);//
	}//结束for
}//结束子函数
//绘制半宽水线图---------------------------------------------------------------------------------------
void func_draw2()
{
	//1.绘制工作区坐标线		
	//画x轴刻度标线及文字(横剖面线)---
	for(i=0;i<M;i++)
	{
		setcolor(c1);//竖直辅助线颜色
		line(x_2+scale_2*(ar_b[i]*P3),H-DH,x_2+scale_2*(ar_b[i]*P3),H-DH-B*0.5*1000*scale_2);//画竖直小刻度线
		setcolor(c3);value=ar_b[i];gcvt(value,6,stt);//文字颜色
		outtextxy(x_2+scale_2*(ar_b[i]*P3)-5,H-DH-B*0.5*1000*scale_2-25,stt);//在规定的位置放置字符串
		value=ar_b[i]*P3*0.001;gcvt(value,6,stt);//
		outtextxy(x_2+scale_2*(ar_b[i]*P3)-5,H-DH-B*0.5*1000*scale_2-40,stt);//在规定的位置放置字符串
	}//结束for
	//画y轴刻度标线及文字(纵剖线)----
	for(i=0;i<N2;i++)
	{
		setcolor(c1);//水平辅助线颜色
		line(x_2,y_2-scale_2*(ar_d[i]),W-1.0*DW,y_2-scale_2*(ar_d[i]));//画水平小刻度线
		setcolor(c3);//文字颜色
		value=ar_d[i];//所在的刻度数值
		gcvt(value,5,stt);//将浮点数value转换为字符串stt
		outtextxy(DW+5,y_2-scale_2*(ar_d[i])-10,stt);//在规定的位置放置字符串
	}//结束for
	//补齐边线--------------
	setcolor(c1);//水平辅助线颜色
	line(x_2,y_2-B*0.5*1000.0*scale_2,W-1.0*DW,y_2-B*0.5*1000.0*scale_2);//画水平小刻度线
	setcolor(c3);value=B*0.5*1000.0;gcvt(value,5,stt);//字符串stt
	outtextxy(DW+5,y_2-B*0.5*1000.0*scale_2-10,stt);//在规定的位置放置字符串
	//2.重新绘制工作区边框
	setcolor(c3);rectangle(DW,DD,W-DW,H-DH);//外边框
	//3.获取横截面点表
	get_wl_data();
	//4.绘制点表曲线
	for(int P=0;P<N1;P++)
	{
		draw_wl_1(P);
	}//结束for
}//结束子函数
//绘制纵剖面图----------------------------------------------------------------------------------------------
void func_draw3()
{
	//1.绘制工作区坐标线		
	//画x轴刻度标线及文字(横剖面线)----
	for(i=0;i<M;i++)
	{
		setcolor(c1);//竖直辅助线颜色
		line(x_3+scale_3*(ar_b[i]*P3),H-DH,x_3+scale_3*(ar_b[i]*P3),H-DH-d1*1000*scale_3);//画竖直小刻度线
		setcolor(c3);value=ar_b[i];gcvt(value,6,stt);//字符串stt
		outtextxy(x_3+scale_3*(ar_b[i]*P3)-5,H-DH-d1*1000*scale_2-25,stt);//在规定的位置放置字符串
		setcolor(c3);value=ar_b[i]*P3*0.001;gcvt(value,6,stt);//字符串stt
		outtextxy(x_3+scale_3*(ar_b[i]*P3)-5,H-DH-d1*1000*scale_2-40,stt);//在规定的位置放置字符串
	}//结束for
	//画y轴刻度标线及文字(纵剖线)------
	for(i=0;i<N1;i++)
	{
		setcolor(c1);//水平辅助线颜色
		line(x_3,y_3-scale_3*(ar_c[i]),W-1.0*DW,y_3-scale_3*(ar_c[i]));//画水平小刻度线
		setcolor(c3);value=ar_c[i];gcvt(value,5,stt);//将浮点数value转换为字符串stt
		if(i%2 == 0){outtextxy(DW+5,y_3-scale_3*(ar_c[i])-10,stt);}//
		else{outtextxy(W-DW-20,y_3-scale_3*(ar_c[i])-10,stt);}//		
	}//结束for
	//2.重新绘制工作区边框
	setcolor(c3);
	rectangle(DW,DD,W-DW,H-DH);//外边框
	//3.获取横截面点表
	get_pt_data();
	//4.绘制点表曲线
	for(int P=0;P<M;P++)
	{
		draw_pt_1(P);
	}//结束for
}//结束子函数
void cross1(double x1,double y1,double sec,double cc)//交叉点样式1
{
	setcolor(cc);//
	line(x1-sec,y1,x1+sec,y1);//
	line(x1,y1-sec,x1,y1+sec);//
	setcolor(c3);//
}//
void trans1(double x0,double y0,double *x1,double *y1)//横截面(右侧)
{
	*x1=x_1+x0*scale_1;//
	*y1=y_1-y0*scale_1;//
}//
void trans1a(double x0,double y0,double *x1,double *y1)//横截面(左侧)
{
	*x1=x_1-x0*scale_1;//
	*y1=y_1-y0*scale_1;//
}//
void trans2(double x0,double y0,double *x1,double *y1)//将片区2的点坐标转换为绘图坐标
{
	*x1=x_2+x0*scale_2;//
	*y1=y_2-y0*scale_2;//
}//
void trans3(double x0,double y0,double *x1,double *y1)//将片区2的点坐标转换为绘图坐标
{
	*x1=x_3+x0*scale_3;//
	*y1=y_3-y0*scale_3;//
}//
void hline(double x1,double y1,double dx,double cc)//根据起点长度间距和颜色绘制线段(水平颜色标线)
{
	setcolor(cc);//画线颜色
	line(x1,y1,x1+dx,y1);//
	setcolor(c3);//恢复颜色
}//
void get_cr_data()//获取横截面点表
{
	//1.获取横截面原始点表----------------------
	for(i=0;i<M;i++)//对每一个横截面
	{
		for(j=0;j<N1;j++)//从水线面获取
		{
			cr_sec[i][j].x=ar_a[i][j];//
			cr_sec[i][j].y=ar_c[j];//
			cr_sec[i][j].z=ar_b[i]*P3;//
		}//结束for
		for(j=N1;j<N1+N2;j++)//从纵截面获取
		{
			cr_sec[i][j].x=ar_d[j-N1];//
			cr_sec[i][j].y=ar_a[i][j];//
			cr_sec[i][j].z=ar_b[i]*P3;//
		}//结束for
	}//结束for
	//2.绘制辅助坐标点-----------------------
	double x1=30,y1=100,x2=W-DW-40,y2=100;//
	for(i=0;i<M;i++)//对每一个横截面
	{
		//绘制坐标点------------
		for(j=0;j<N1+N2;j++)//
		{
			if(i<=int((M-1)/2.0))//左侧
			{
				trans1a(cr_sec[i][j].x,cr_sec[i][j].y,&cr_sec1[i][j].x,&cr_sec1[i][j].y);//
				cross1(cr_sec1[i][j].x,cr_sec1[i][j].y,5,color1[i]);//
			}//
			else//右侧
			{
				trans1(cr_sec[i][j].x,cr_sec[i][j].y,&cr_sec1[i][j].x,&cr_sec1[i][j].y);//
				cross1(cr_sec1[i][j].x,cr_sec1[i][j].y,5,color1[i]);//
			}//
		}//结束for
		//绘制水平颜色标记-------
		if(i<=int((M-1)/2.0))
		{
			hline(x1,y1,20,color1[i]);//根据起点长度间距和颜色绘制线段(水平颜色标线)		
			setcolor(color1[i]);value=ar_b[i];gcvt(value,6,stt);//字符串stt
			outtextxy(x1+30,y1-5,stt);//在规定的位置放置字符串
			y1=y1+10;//
		}//
		else
		{
			hline(x2,y2,-20,color1[i]);//根据起点长度间距和颜色绘制线段(水平颜色标线)		
			setcolor(color1[i]);value=ar_b[i];gcvt(value,6,stt);//字符串stt
			outtextxy(x2+10,y2-5,stt);//在规定的位置放置字符串
			y2=y2+10;//
		}//	
	}//结束for
	//3.对点表排序
	cr_sort();//
}//结束子函数
void get_wl_data()//获取水线面点表
{
	//1.获取水线面原始点表----------------------
	for(i=0;i<N1;i++)//对每一个水线面
	{
		for(j=0;j<M;j++)//从横剖面获取
		{
			wl_sec[i][j].z=ar_c[i];//
			wl_sec[i][j].y=ar_a[j][i];//
			wl_sec[i][j].x=ar_b[j]*P3;//
		}//结束for
	}//结束for
	//2.绘制辅助坐标点-----------------------
	double x1=30,y1=100,x2=W-DW-40,y2=100;//
	for(i=0;i<N1;i++)//对每一个横截面
	{
		//绘制坐标点------------
		for(j=0;j<M;j++)//
		{
			trans2(wl_sec[i][j].x,wl_sec[i][j].y,&(wl_sec1[i][j].x),&(wl_sec1[i][j].y));//
			cross1(wl_sec1[i][j].x,wl_sec1[i][j].y,5,color1[i]);//
		}//结束for
		//绘制水平颜色标记-------
	    hline(x1,y1,20,color1[i]);//根据起点长度间距和颜色绘制线段(水平颜色标线)		
		setcolor(color1[i]);value=ar_c[i];gcvt(value,6,stt);//字符串stt
		outtextxy(x1+30,y1-5,stt);//在规定的位置放置字符串
		y1=y1+10;//
	}//结束for
}//结束子函数
void get_pt_data()//获取纵截面点表
{
	//1.获取纵截面原始点表----------------------
	for(i=0;i<N2;i++)//对每一个水线面
	{
		for(j=0;j<M;j++)//从横剖面获取
		{
			pt_sec[i][j].z=ar_c[i];//
			pt_sec[i][j].y=ar_a[j][N1+i];//
			pt_sec[i][j].x=ar_b[j]*P3;//
		}//结束for
	}//结束for
	//2.绘制辅助坐标点-----------------------
	double x1=30,y1=100,x2=W-DW-40,y2=100;//
	for(i=0;i<N2;i++)//对每一个横截面
	{
		//绘制坐标点------------
		for(j=0;j<M;j++)//
		{
			trans3(pt_sec[i][j].x,pt_sec[i][j].y,&(pt_sec1[i][j].x),&(pt_sec1[i][j].y));//
			cross1(pt_sec1[i][j].x,pt_sec1[i][j].y,5,color1[i]);//
		}//结束for
		//绘制水平颜色标记-------
	    hline(x1,y1,20,color1[i]);//根据起点长度间距和颜色绘制线段(水平颜色标线)		
		setcolor(color1[i]);value=ar_d[i];gcvt(value,6,stt);//字符串stt
		outtextxy(x1+30,y1-5,stt);//在规定的位置放置字符串
		y1=y1+10;//
	}//结束for
}//结束子函数
void cr_sort()//对横截面点表排序
{
	DPOINT3 t;//供交换用的中间变量
	DPOINT3 cr_sec_a[M][N1+N2]={0};//(y<=d1)&&(x!=0)的点表
	DPOINT3 cr_sec_b[M]={0};//取x=0时y的最大值(中剖面上的截距)
	DPOINT3 cr_sec_c[M][N1+N2]={0};//
    for(i=0;i<M;i++)//对每个横截面
	{
		//0.删除无效点([相同点][距离小于100的点][两点距离突变点])--------------------------
		for(j=0;j<N1+N2-1;j++)//对这个横截面的每个点(不含最后一个点)
		{
			for(k=j+1;k<N1+N2;k++)//对之后的所有点
			{
				if((cr_sec[i][j].x == cr_sec[i][k].x) && (cr_sec[i][j].y == cr_sec[i][k].y)
					|| (sqrt(pow(cr_sec[i][j].x-cr_sec[i][k].x,2.0)+pow(cr_sec[i][j].y-cr_sec[i][k].y,2.0)) <= 80.0))
				{
					cr_sec[i][j].x=0;//
					cr_sec[i][j].y=0;//
				    cr_sec[i][j].z=0;//
				}//结束if
			}//结束for
		}//结束for		
		//1.按照x从小到大的顺序排列--------------------
		for(j=0;j<N1+N2-1;j++)//对这个横截面的每个点(不含最后一个点)
		{
			for(k=j+1;k<N1+N2;k++)//对之后的所有点
			{
				if(cr_sec[i][j].x >= cr_sec[i][k].x)
				{
					t=cr_sec[i][j];//
					cr_sec[i][j]=cr_sec[i][k];//
					cr_sec[i][k]=t;//
				}//结束if
			}//结束for
		}//结束for
		//如果x相同,y从小到大的顺序排列-----------------------
		for(j=0;j<N1+N2-1;j++)//对这个横截面的每个点(不含最后一个点)
		{
			for(k=j+1;k<N1+N2;k++)//对之后的所有点
			{
				if((cr_sec[i][j].x == cr_sec[i][k].x) && (cr_sec[i][j].y >= cr_sec[i][k].y))
				{
					t=cr_sec[i][j];//
					cr_sec[i][j]=cr_sec[i][k];//
					cr_sec[i][k]=t;//
				}//结束if
			}//结束for
		}//结束for	
		//[两点距离突变点])--------------------------
		for(j=0;j<N1+N2-1;j++)//对这个横截面的每个点(不含最后一个点)
		{
			if(fabs(cr_sec[i][j].y-cr_sec[i][j+1].y) >= d1*1000.0)//
			{
				cr_sec[i][j+1].x=0;//
				cr_sec[i][j+1].y=0;//
			    cr_sec[i][j+1].z=0;//
			}//结束if
		}//结束for
		//2.取(y<=d1)&&(x!=0)的点表------------------------------
		for(j=0;j<N1+N2;j++)//对这个横截面的每个点
		{
			if(cr_sec[i][j].y <= d1*1000.0 && cr_sec[i][j].x != 0)
			{
				cr_sec_a[i][j]=cr_sec[i][j];//
			}//结束if
		}//结束for
		//3.取x=0时y的最大值(如果有的话)--------------
		double m=0;//比对中间变量
		cr_eft[i]=0;
		for(j=0;j<N1+N2;j++)//对这个横截面的每个点
		{
			if(cr_sec[i][j].x == 0.0)
			{
				if(cr_sec[i][j].y >= m)
				{
					m=cr_sec[i][j].y;//
					cr_sec_b[i]=cr_sec[i][j];//存储这个点
				}//结束if
			}//结束if			
		}//结束for
		//4.取cr_eft[i]的值--------------------------
		if(cr_sec_b[i].y != 0.0){cr_eft[i]++;}//
		for(j=0;j<N1+N2;j++)//对这个横截面的每个点
		{
			if(cr_sec_a[i][j].x != 0.0){cr_eft[i]++;}//
		}//结束for
		//5.叠加两个点表--------------
		j=0;//
		if(j<cr_eft[i])//对这个横截面的每个点
		{
			//首元素
			if(cr_sec_b[i].y != 0.0)
			{
				cr_sec_c[i][0]=cr_sec_b[i];//
				j=1;//
			}//结束if
			//剩余元素
			for(k=0;k<N1+N2;k++)
			{
				if(cr_sec_a[i][k].x != 0.0)//
				{
					cr_sec_c[i][j]=cr_sec_a[i][k];//					
					j++;//
				}//结束if
			}//结束for
		}//结束if
		for(j=0;j<cr_eft[i];j++)
		{
			cr_sec2[i][j]=cr_sec_c[i][j];//赋值到全局变量
		}//结束for
	}//结束for
}//结束子函数
void dline(DPOINT3 x1,DPOINT3 x2,double cc)//根据两点和颜色绘制线段(辅助线和轮廓线)
{
	setcolor(cc);//画线颜色
	line(x1.x,x1.y,x2.x,x2.y);//
	setcolor(c3);//恢复颜色
}//
void cr_cl(DPOINT3 p1,DPOINT3 p2,double ang1,double ang2,int flag1,double cc)//绘制方向角渐变的曲线(一阶导数连续)
{
	double num=20.0;//分段数
	double d_ang=(ang2-ang1)*1000.0/num;//角度增量
	double d_dis=sqrt((p2.x-p1.x)*(p2.x-p1.x)+(p2.y-p1.y)*(p2.y-p1.y))/num;//距离增量
	double dx1,dy1,c_ang;//xy方向增量+角度当前量
	double d_x=0.0;//x方向修正量
	double d_y=0.0;//y方向修正量
	DPOINT3 pa=p1;//
	DPOINT3 pb=p1;//
	DPOINT3 pa1=p1;//
	DPOINT3 pb1=p1;//
	//[概略描线](存在累计误差)-------------------------------------------
	for(i=0;i<num;i++)//逐段计算,初始点位(概略)
	{
		c_ang=ang1+i*d_ang*0.001;//角度当前量
		dx1=d_dis*cos(c_ang);//
		dy1=d_dis*sin(c_ang);//
		pb.x=pa.x+dx1;//
		pb.y=pa.y+dy1;//
		fuc_trans1(pa,pb,flag1,&pa1,&pb1);//坐标变换
		//dline(pa1,pb1,cc);//
		pa=pb;//
	}//结束for
	//[修正描线](修正累计误差)-------------------------------------------
	d_x=1.0*(p2.x-pb.x)/num;//x方向修正量
	d_y=1.0*(p2.y-pb.y)/num;//y方向修正量
	pa=p1;//
	pb=p1;//
	for(i=0;i<num;i++)//逐段计算,修正点位(根据反馈误差修正)
	{
		c_ang=ang1+i*d_ang*0.001;//角度当前量
		dx1=d_dis*cos(c_ang);//
		dy1=d_dis*sin(c_ang);//
		pb.x=pa.x+dx1+d_x;//修正x
		pb.y=pa.y+dy1+d_y;//修正y
		fuc_trans1(pa,pb,flag1,&pa1,&pb1);//坐标变换
		dline(pa1,pb1,cc);//
		pa=pb;//
	}//结束for	
}//结束子函数
void draw_cr_1(int i)//绘制特定截面横剖面线
{
	double ang_1,ang_2;//
	if(i<=int((M-1)/2.0)){flag1=1;}//左侧
	else{flag1=2;}//右侧
	//1.第1点--------------------------------
	j=0;
	if(cr_sec2[i][j].x == 0 //1.起点在中剖面上
	   && cr_sec2[i][j+1].y != d1*1000.0)//2.第2点不在顶边上
	{
		ang_1=0.0*atan2((cr_sec2[i][j+1].y-cr_sec2[i][j].y),(cr_sec2[i][j+1].x-cr_sec2[i][j].x));//
		ang_2=atan2((cr_sec2[i][j+2].y-cr_sec2[i][j].y),(cr_sec2[i][j+2].x-cr_sec2[i][j].x));//
	}//
	else if(cr_sec2[i][j].x == 0 //1.起点在中剖面上
		    && cr_sec2[i][j+1].y == d1*1000.0)//2.第2点在顶边上
	{
		ang_1=0.0*atan2((cr_sec2[i][j+1].y-cr_sec2[i][j].y),(cr_sec2[i][j+1].x-cr_sec2[i][j].x));//
		ang_2=atan2((cr_sec2[i][j+2].y-cr_sec2[i][j].y),(cr_sec2[i][j+2].x-cr_sec2[i][j].x));//
	}//
	else if(cr_sec2[i][j].y == 0 //1.起点在底面上
		    && cr_sec2[i][j+1].y != 0)//2.第2点不在底边上
	{
		ang_1=0.0*atan2((cr_sec2[i][j+1].y-cr_sec2[i][j].y),(cr_sec2[i][j+1].x-cr_sec2[i][j].x));//
		ang_2=atan2((cr_sec2[i][j+2].y-cr_sec2[i][j].y),(cr_sec2[i][j+2].x-cr_sec2[i][j].x));//
	}//
	else if(cr_sec2[i][j].y == 0 //1.起点在底面上
		    && cr_sec2[i][j+1].y == 0)//2.第2点在底边上
	{
		ang_1=0.0;ang_2=0.0;//
	}//
	cr_cl(cr_sec2[i][j],cr_sec2[i][j+1],ang_1,ang_2,flag1,color1[i]);//绘制渐变曲线
	//2.中间点----------------------------------
	if(cr_eft[i] >= 3)
	{//存在中间点的条件
		for(j=1;j<cr_eft[i]-2;j++)//
		{
			if((cr_sec2[i][j+1].x-cr_sec2[i][j-1].x) !=0    //1.前后两点横坐标之差不为0
				&& (cr_sec2[i][j+2].x-cr_sec2[i][j+1].x) !=0 //2.下一点的导数有意义
				&& (cr_sec2[i][j+1].x-cr_sec2[i][j].x) !=0 //3.这一点与下一点不在垂直线上
				&& cr_sec2[i][j+1].x != 0.5*B*1000.0) //4.这一点的下一点不在垂直边线上
			{
				ang_1=atan2((cr_sec2[i][j+1].y-cr_sec2[i][j-1].y),(cr_sec2[i][j+1].x-cr_sec2[i][j-1].x));//
				ang_2=atan2((cr_sec2[i][j+2].y-cr_sec2[i][j].y),(cr_sec2[i][j+2].x-cr_sec2[i][j].x));//
			}//
			else if(cr_sec2[i][j+1].x == 0.5*B*1000.0 //1.这点的下一点在垂直线上
					&& cr_sec2[i][j].x != 0.5*B*1000.0) //2.且这一点不在垂直线上
			{
				ang_1=atan2((cr_sec2[i][j+1].y-cr_sec2[i][j-1].y),(cr_sec2[i][j+1].x-cr_sec2[i][j-1].x));//
				ang_2=PI/2.0;//
			}//
			else
			{
				ang_1=PI/2.0;ang_2=PI/2.0;//
			}//
			cr_cl(cr_sec2[i][j],cr_sec2[i][j+1],ang_1,ang_2,flag1,color1[i]);//绘制渐变曲线
		}//结束for
	}//中间点
	//3.最后1点-----------------------------------------------------
	if(cr_eft[i] >= 3)
	{
		//最后1点的条件
	    j=cr_eft[i]-2;//
		if((cr_sec2[i][j+1].x-cr_sec2[i][j-1].x) !=0 //1.前一点后一点不在垂直线上
			&& (cr_sec2[i][j+1].x-cr_sec2[i][j].x) !=0) //2.这一点与后一点不在垂直线上
		{
			ang_1=atan2((cr_sec2[i][j+1].y-cr_sec2[i][j-1].y),(cr_sec2[i][j+1].x-cr_sec2[i][j-1].x));//
			ang_2=1.3*ang_1;
		}
		else
		{
			ang_1=PI/2.0;
			ang_2=PI/2.0;
		}//
		cr_cl(cr_sec2[i][j],cr_sec2[i][j+1],ang_1,ang_2,flag1,color1[i]);//绘制渐变曲线
	}//端点
}//结束子函数
void draw_wl_1(int i)//绘制特定水线面线
{
	double ang_1,ang_2;//
	//1.第1点--------------------------------
	j=0;
	ang_2=atan2((wl_sec[i][j+2].y-wl_sec[i][j].y),(wl_sec[i][j+2].x-wl_sec[i][j].x));//
	ang_1=0.5*ang_2;//	
	cr_cl(wl_sec[i][j],wl_sec[i][j+1],ang_1,ang_2,3,color1[i]);//绘制渐变曲线
	//2.中间点----------------------------------
	for(j=1;j<M-2;j++)//
	{
		ang_1=atan2((wl_sec[i][j+1].y-wl_sec[i][j-1].y),(wl_sec[i][j+1].x-wl_sec[i][j-1].x));//
		ang_2=atan2((wl_sec[i][j+2].y-wl_sec[i][j].y),(wl_sec[i][j+2].x-wl_sec[i][j].x));//
		cr_cl(wl_sec[i][j],wl_sec[i][j+1],ang_1,ang_2,3,color1[i]);//绘制渐变曲线
	}//结束for
	//3.最后1点-----------------------------------------------------
	j=M-2;//
	ang_1=atan2((wl_sec[i][j+1].y-wl_sec[i][j-1].y),(wl_sec[i][j+1].x-wl_sec[i][j-1].x));//
	ang_2=0.5*ang_1;
	cr_cl(wl_sec[i][j],wl_sec[i][j+1],ang_1,ang_2,3,color1[i]);//绘制渐变曲线
}//结束子函数
void draw_pt_1(int i)//绘制特定水线面线
{
	double ang_1,ang_2;//
	//1.第1点--------------------------------
	j=0;
	ang_2=atan2((pt_sec[i][j+2].y-pt_sec[i][j].y),(pt_sec[i][j+2].x-pt_sec[i][j].x));//
	ang_1=0.5*ang_2;//	
	cr_cl(pt_sec[i][j],pt_sec[i][j+1],ang_1,ang_2,3,color1[i]);//绘制渐变曲线
	//2.中间点----------------------------------
	for(j=1;j<M-2;j++)//
	{
		if(fabs(pt_sec[i][j+2].y-pt_sec[i][j].y) <= d1*1000.0)//逐渐圆顺点(有效点)
		{
			ang_1=atan2((pt_sec[i][j+1].y-pt_sec[i][j-1].y),(pt_sec[i][j+1].x-pt_sec[i][j-1].x));//
			ang_2=atan2((pt_sec[i][j+2].y-pt_sec[i][j].y),(pt_sec[i][j+2].x-pt_sec[i][j].x));//			
			cr_cl(pt_sec[i][j],pt_sec[i][j+1],ang_1,ang_2,3,color1[i]);//绘制渐变曲线
		}
		else if(fabs(pt_sec[i][j+1].y-pt_sec[i][j+2].y) >= d1*1000.0)//落差点(无效点)
		{
			ang_1=atan2((pt_sec[i][j+1].y-pt_sec[i][j-1].y),(pt_sec[i][j+1].x-pt_sec[i][j-1].x));//
			ang_2=atan2((pt_sec[i][j+1].y-pt_sec[i][j].y),(pt_sec[i][j+1].x-pt_sec[i][j].x));//			
			cr_cl(pt_sec[i][j],pt_sec[i][j+1],ang_1,ang_2,3,color1[i]);//绘制渐变曲线
		}//
	}//结束for
	//3.最后1点-----------------------------------------------------
	j=M-2;//
	if(fabs(pt_sec[i][j+1].y-pt_sec[i][j].y) != 0.0)//无效点的简化
	{
		ang_1=atan2((pt_sec[i][j+1].y-pt_sec[i][j-1].y),(pt_sec[i][j+1].x-pt_sec[i][j-1].x));//
		ang_2=0.5*ang_1;
		cr_cl(pt_sec[i][j],pt_sec[i][j+1],ang_1,ang_2,4,color1[i]);//绘制渐变曲线
	}//
}//结束子函数
void fuc_trans1(DPOINT3 pa,DPOINT3 pb,int flag1,DPOINT3 *pa1,DPOINT3 *pb1)//坐标变换
{
	if(flag1 == 1)
	{
		trans1a(pa.x,pa.y,&(*pa1).x,&(*pa1).y);//左侧
		trans1a(pb.x,pb.y,&(*pb1).x,&(*pb1).y);//
	}
	else if(flag1 == 2)
	{
		trans1(pa.x,pa.y,&(*pa1).x,&(*pa1).y);//右侧
		trans1(pb.x,pb.y,&(*pb1).x,&(*pb1).y);//
	}
	else if(flag1 == 3)
	{
		trans2(pa.x,pa.y,&(*pa1).x,&(*pa1).y);//水线面
		trans2(pb.x,pb.y,&(*pb1).x,&(*pb1).y);//
	}
	else if(flag1 == 4)
	{
		trans3(pa.x,pa.y,&(*pa1).x,&(*pa1).y);//水线面
		trans3(pb.x,pb.y,&(*pb1).x,&(*pb1).y);//
	}
}//结束子函数
//*/
//-------------------------------------------------------------------------------------------------------------------

文章来源:https://blog.csdn.net/gisshow135540019/article/details/135190978
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。