中南大学土木工程软件课程设计.docx
《中南大学土木工程软件课程设计.docx》由会员分享,可在线阅读,更多相关《中南大学土木工程软件课程设计.docx(36页珍藏版)》请在冰豆网上搜索。
中南大学土木工程软件课程设计
基于C++编写线路CAD程序
1.1 曲线要素计算程序
1.1.1主要内容和计算函数
(1)计算内容:
在txt文件中读取交点信息,编程计算线路曲线要素、特征点里程及坐标、逐桩里程和坐标,并读出到txt文件。
(2)计算函数:
structJDDATA//定义交点数据结构体
structrandompoint//定义任意点坐标数据结构
doubleJSFWJ(doublex1,doublex2,doubley1,doubley2);//计算方位角的函数
doubleJSp(doublelo,doubleR);//计算内移距p的函数
doubleJSm(doublelo);//计算切垂距m的函数
charJSZYP(doublefwj1,doublefwj2);//判断左右偏函数
(其中左偏记为”L”,右偏记为”R”)
doubleJSalpha(doublefwj1,doublefwj2);//计算α的函数
doubleJST(doubleR,doublep,doublem,doublealpha);//计算切线长的函数
doubleJSL(doubleR,doublelo,doublealpha);//计算曲线长的函数
doubleJSE(doubleR,doublep,doublealpha);//计算外矢距的函数
doubleJSKZH(doubleK,doublex1,doubley1,doublex2,doubley2,doubleT1,doubleT2);//计算直缓点里程的函数
doubleJSKHY(doubleKZH,doublelo);//计算缓圆点里程的函数
doubleJSKYH(doubleKZH,doubleL,doublelo);//计算圆缓点里程的函数
doubleJSKHZ(doubleKZH,doubleL);//计算缓直点里程的函数
doubleJSKQZ(doubleKZH,doubleL);//计算曲中点里程的函数
doubleJSZHx(doublex,doublefwj,doubleT);//计算直缓点x坐标的函数
doubleJSZHy(doubley,doublefwj,doubleT);//计算直缓点y坐标的函数
doubleJSHZx(doublex,doublefwj,doubleT);//计算缓直点x坐标的函数
doubleJSHZy(doubley,doublefwj,doubleT);//计算缓直点y坐标的函数
doubleJSHYx(doublelo,doubleR,doublefwj,charzyp,doublex);
//计算缓圆点x坐标的函数
doubleJSHYy(doublelo,doubleR,doublefwj,charzyp,doubley);
//计算缓圆点y坐标的函数
doubleJSYHx(doublelo,doubleR,doublefwj,charzyp,doublex);
//计算圆缓点x坐标的函数
doubleJSYHy(doublelo,doubleR,doublefwj,charzyp,doubley);
//计算圆缓点y坐标的函数
voidJSQZZB(doublex,doubley,doublefwj,doubleL,doubleR,doublelo,doublem,doublep,charzyp,double*qzx,double*qzy);//计算曲中点坐标的函数
voidJSZZZB(doubleLC,inti,double*zbx,double*zby);//里程转坐标的函数
1.1.2编程流程图
1.1.3定义交点数据结构体
本文将交点的数据存储于结构体中,结构体的定义如下:
structJDDATA
{
doublex;
doublex;//交点的x坐标
doubley;//交点的y坐标
doubleR;//交点的半径
doublelo;//交点的缓长
doublefwj;//交点到下一个交点连线的方位角
doublep;//交点的内移距
doublem;//交点的切垂距
charzyp;//交点的左右偏(左偏记为L,右偏记为R)
doublealpha;//交点的α
doubleT;//交点的切线长
doubleL;//交点的曲线长
doubleE;//交点的外矢距
doubleKZH;//交点的直缓点里程
doubleKHY;//交点的缓圆点里程
doubleKYH;//交点的圆缓点里程
doubleKHZ;//交点的缓直点里程
doubleKQZ;//交点的曲中点里程
doubleZHx;//直缓点的x坐标
doubleZHy;//直缓点的y坐标
doubleHZx;//缓直点的x坐标
doubleHZy;//缓直点的y坐标
doubleHYx;//缓圆点的x坐标
doubleHYy;//缓圆点的y坐标
doubleYHx;//圆缓点的x坐标
doubleYHy;//圆缓点的y坐标
doubleQZx;//曲中点的x坐标
doubleQZy;//曲中点的y坐标
}jd[20];
设计线路中有数个交点,故把每个交点的数据存储于结构体数组中,每个个体又包含如上列举的共性属性。
本程序是用的是一个静态数组jd[20],考虑到交点数据不是很多,故把容量暂定为20个,但是较有局限性,需要根据实际情况反复地改写程序。
期望的改进方法是使用动态数组或者是Carray,使得程序能够随着实际情况动态的提供数组容量,以节省需要的内存空间,但是现下能力有限,在尝试的过程中程序报错,不知如何修改,所以最终还是选用了静态数组。
1.1.4交点数据的读入
以本选题所设计的昌吉赣客专横岗—江家段线路为例,将交点数据存储在”JD.data.txt”中,如图:
第一行的数据代表的是起始点的里程,以下每行的数据分别代表的是各个交点的纬度坐标、经度坐标、圆曲线长度、缓和曲线长度。
利用文件流将数据读入。
ifstreaminput;
input.open("JDdata.txt");
if(input.fail())//判断文件读取是否正常
{
cout<<"Filedoesnotexist"<cout<<"Exitprogram"<}
input>>jd[0].KZH;
inti=0;
while(!
input.eof())
{
input>>jd[i].x>>jd[i].y>>jd[i].R>>jd[i].lo;//将交点数据存放于结构体中
i++;
}
cout<<"共检测到"<
input.close();
这一部分程序运行完之后,会出现一个对话框,读取到的交点个数会显示到对话框上,而相应的交点数据已经存入到结构体当中去了。
1.1.5曲线要素计算原理及程序的实现
(1)方位角
计算方位角需要用到两个交点的坐标数据。
对于不同象限的方位角,所对应的计算方法也会有所不同。
如下程序首先判断方位角在哪一个象限,再根据判断的结果进行方位角的计算。
现已在第一象限为例,对计算原理进行阐释:
(4-1)
计算方位角函数的定义:
doubleJSFWJ(doublex1,doubley1,doublex2,doubley2)
{
doublefwj;
doubledx;
doubledy;
dx=x2-x1;
dy=y2-y1;
if(dx==0&&dy>0)
fwj=0;
elseif(dx>0&&dy>0)
fwj=atan(dx/dy)*180/PI;
elseif(dx>0&&dy==0)
fwj=90;
elseif(dx>0&&dy<0)
fwj=atan(dx/dy)*180/PI+180;
elseif(dx==0&&dy<0)
fwj=180;
elseif(dx<0&&dy<0)
fwj=atan(dx/dy)*180/PI+180;
elseif(dx<0&&dy==0)
fwj=270;
elseif(dx<0&&dy>0)
fwj=atan(dx/dy)*180/PI+360;
returnfwj;
}
计算方位角函数的调用:
for(intn=0;n{
jd[n].fwj=JSFWJ(jd[n].x,jd[n].y,jd[n+1].x,jd[n+1].y);
}
利用循环语句将交点的方位角都计算了出来。
此外,本文中默认的一个交点的方位角是该交点到下一个交点连线的方位角。
(2)转向角
转向角是相邻两个方位角之差,并取绝对值。
计算转向角函数的定义:
doubleJSalpha(doublefwj1,doublefwj2)
{
doublealpha;
if(fabs(fwj2-fwj1)<180)
{alpha=fabs(fwj2-fwj1);}
else
{alpha=360-fabs(fwj2-fwj1);}
returnalpha;
计算转向角函数的调用:
jd[count].alpha=JSalpha(jd[count-1].fwj,jd[count].fwj);
其中count是循环语句的计数器,以下内容的计算都用到的循环的思想,在下文就不再赘述。
(3)判断左右偏
一般来说,
但是若前方位角角度较小,接近0度,后方位角较大,接近360度,虽然后方位角大于前方位角,但实际偏转应当是左偏。
所以本文中对这一情况进行了判断,由于本文是实际线路为例,考虑到实际线路转角偏转不会太大,故以180度为判断界限,若差值小于180,则按正常计算方法进行计算;若差值大于180,则应认为是出现了上述的特殊情况,则不能按一般情况进行计算
判断左右偏函数的定义:
charJSZYP(doublefwj1,doublefwj2)
{
charturn;
if(abs(fwj2-fwj1)<=180)
{
if(fwj2>fwj1)
turn='R';
elseturn='L';
}
else
{
if(fwj2>fwj1)
turn='L';
else
turn='R';
}
returnturn;
判断左右偏函数的调用:
jd[count].zyp=JSZYP(jd[count-1].fwj,jd[count].fwj);
(4)曲线要素
根据实际情况,选定线路的交点,在符合规范的条件下,选定合适的半径和缓和曲线长度,根据以下公式进行计算:
(4-2)
(4-3)
(4-4)
(4-5)
(4-6)
(4-7)
式中:
p为内移距,m为切垂距,
为缓和曲线角,T为切线长,L为曲线长,E为内移距。
特征点里程的计算:
ZH点里程为上一点HZ点里程加两个交点的距离减去两个交点的切线长。
(其中交点0的HZ点里程按起始点里程算,切线长认为是0)
HY点里程=ZH(里程)+
;
YH点里程=ZH(里程)+
-
;
HZ点里程=ZH(里程)+
;
QZ点里程=ZH(里程)+
÷2;
曲线要素计算的部分,程序内容比较简单,就是定义一个函数,然后在主函数中调用它,得到需要的结果。
详细程序请参见附录。
1.1.6逐桩坐标的计算
这里的逐桩坐标的计算,其实就是给出任意点的里程,要能计算出这个点的坐标。
由于整条线路比较长,故选10米为一个点,也就是计算10米桩的坐标。
大致的思路是这样的:
一、得到一个点的里程,判断它落在哪一部分的曲线上(直线、圆曲线还是缓和曲线),不同的曲线部分计算的方法有所不同;二、计算得到局部坐标。
三、利用坐标转换原理得到整体坐标。
在直线段部分,坐标的计算比较简单,利用方位角和里程差就能轻松求得。
在缓和曲线段和圆曲线段,需要用到切线支距法,以夹直线所在直线为x轴,垂直夹直线所在直线的直线为y轴
计算公式:
(1)缓和曲线部分
(4-8)
(4-9)
(2)圆曲线部分
(4-10)
(4-11)
(4-12)
相应的,后缓和曲线则以HZ点为坐标原点用切线支距法进行计算。
(3)局部坐标转换为整体坐标
转换公式如下:
(4-13)
需要注意的是,由于左偏还是右偏对局部坐标的计算是有影响的,所以在计算前应根据不同的左右偏情况分情况进行讨论计算,再根据具体的情况判断局部坐标系下x,y的正负,保证计算的正确。
(4)逐桩坐标数据结构
structrandompoint
{
doublex;
doubley;
doubleLC;
}point[4000];
这里用到的也是结构体的思想,把任意点的x坐标,y坐标和里程都放到结构体里面去。
逐桩坐标计算程序定义如下:
voidJSZZZB(doubleLC,inti,double*zbx,double*zby)
{
for(intcount2=1;count2
if(LC>=jd[count2-1].KHZ&&LC<=jd[count2].KZH)//直线段
{
doublel=LC-jd[count2-1].KHZ;
*zbx=jd[count2-1].HZx+l*sin(jd[count2-1].fwj*PI/180);
*zby=jd[count2-1].HZy+l*cos(jd[count2-1].fwj*PI/180);
break;
}
elseif(LC>=jd[count2].KZH&&LC<=jd[count2].KHY)//前缓段
{
doublel=LC-jd[count2].KZH;
doublehyx=l-pow(l,5)/40/pow(jd[count2].R,2)/pow(jd[count2].lo,2);
doublehyy;
if(jd[count2].zyp=='L')
{
hyy=pow(l,3)/6/jd[count2].R/jd[count2].lo;
}
else
{
hyy=-pow(l,3)/6/jd[count2].R/jd[count2].lo;
}
*zbx=jd[count2].ZHx+hyx*sin(jd[count2-1].fwj*PI/180)-hyy*cos(jd[count2-1].fwj*PI/180);
*zby=jd[count2].ZHy+hyx*cos(jd[count2-1].fwj*PI/180)+hyy*sin(jd[count2-1].fwj*PI/180);
break;
}
elseif(LC>=jd[count2].KHY&&LC{
doublel=LC-jd[count2].KZH;
doubleQalfa=(l-jd[count2].lo)*180/PI/jd[count2].R+jd[count2].lo*180/2/PI/jd[count2].R;
doubleqx=jd[count2].R*sin(Qalfa*PI/180)+jd[count2].m;
doubleqy;
if(jd[count2].zyp=='L')
{
qy=jd[count2].R*(1-cos(Qalfa*PI/180))+jd[count2].p;
}
else
{
qy=-(jd[count2].R*(1-cos(Qalfa*PI/180))+jd[count2].p);
}
*zbx=jd[count2].ZHx+qx*sin(jd[count2-1].fwj*PI/180)-qy*cos(jd[count2-1].fwj*PI/180);
*zby=jd[count2].ZHy+qx*cos(jd[count2-1].fwj*PI/180)+qy*sin(jd[count2-1].fwj*PI/180);
break;
}
elseif(LC>=jd[count2].KYH&&LC{
doublel=jd[count2].KHZ-LC;
doubleyhx=-(l-pow(l,5)/40/pow(jd[count2].R,2)/pow(jd[count2].lo,2));
doubleyhy;
if(jd[count2].zyp=='L')
{
yhy=pow(l,3)/6/jd[count2].R/jd[count2].lo;
}
else
{
yhy=-pow(l,3)/6/jd[count2].R/jd[count2].lo;
}
*zbx=jd[count2].HZx+yhx*sin(jd[count2].fwj*PI/180)-yhy*cos(jd[count2].fwj*PI/180);
*zby=jd[count2].HZy+yhx*cos(jd[count2].fwj*PI/180)+yhy*sin(jd[count2].fwj*PI/180);
break;
}
函数的调用如下:
intnum=jd[i-1].KZH/10;(计算每10米一个点的总点位数)
for(intj=0;j{
point[j].LC=jd[0].KZH+10*j;
JSZZZB(point[j].LC,i,&point[j].x,&point[j].y);
}
这样就把每10米一个点的坐标给求出来了。
1.1.7特征点坐标
特征点坐标的计算同逐桩坐标点坐标的计算相同,只是将任意的里程替代为特征点的里程,用到的方法都是一样的,这里也就不一一赘述了。
计算数据的输出
这里依旧是用文件流的方法,将计算得到的数据读出到"result.txt"。
output.open("result.txt");
for(intcount1=1;count1{
intk1,k3,k5,k7;
doublek2,k4,k6,k8;
k1=jd[count1].KZH/1000;
k2=jd[count1].KZH-k1*1000;
k3=jd[count1].KHY/1000;
k4=jd[count1].KHY-k3*1000;
k5=jd[count1].KYH/1000;
k6=jd[count1].KYH-k5*1000;
k7=jd[count1].KHZ/1000;
k8=jd[count1].KHZ-k7*1000;
output<<"alpha="<output<<"直缓点里程="<<"K"<output<<"缓圆点里程="<<"K"<output<<"圆缓点里程="<<"K"<output<<"缓直点里程="<<"K"<output<<"直缓点x坐标="<output<<"圆缓点x坐标="<output<}
jd[i-1].KZH=jd[i-2].KHZ+sqrt((jd[i-1].x-jd[i-2].x)*(jd[i-1].x-jd[i-2].x)+(jd[i-1].y-jd[i-2].y)*(jd[i-1].y-jd[i-2].y));
intk1;
intk2;
output<<"任意点里程"<intnum=jd[i-1].KZH/10;
for(intj=0;j{
point[j].LC=jd[0].KZH+10*j;
JSZZZB(point[j].LC,i,&point[j].x,&point[j].y);
k1=point[j].LC/1000;
k2=point[j].LC-k1*1000;
output<<"K"<}//输出逐桩里程及坐标
output.close();
如下图所示,就是程序运行后输出文件”result.txt”的结果显示
曲线要素计算程序代码
#include
#include
#include
#include
#include
usingnamespacestd;
constdoublePI=3.14159;
doubleJSFWJ(doublex1,doublex2,doubley1,doubley2);//声明计算方位角的函数
doubleJSp(doublelo,doubleR);//声明计算内移距p的函数
doubleJSm(doublelo);//声明计算切垂距m的函数
charJSZYP(doublefwj1,doublefwj2);//声明判断左右偏函数
doubleJSalpha(doublefwj1,doublefwj2);//声明计算α的函数
doubleJST(doubleR,doublep,doublem,doublealpha);//声明计算切线长的函数
doubleJSL(doubleR,doublelo,doublealpha);//声明计算曲线长的函数
doubleJSE(doubleR,doublep,doublealpha);//声明计算外矢距的函数
doubleJSKZH(doubleK,dou