//--------------------------------------------------------------------------------------------------
//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);//
}
}//结束子函数
//*/
//-------------------------------------------------------------------------------------------------------------------