您的当前位置:首页正文

坐标算法

2024-04-07 来源:爱go旅游网


根据曲线要素计算坐标

一、缓和曲线部分

1、第一段缓和曲线任意点城市坐标算法

已知:Xj1=52423.114,Yj1=58247.423;Xj2=52635.217,Yj2=58398.947. 求得:交点连线及(切线)方位角D=arctan(Yj2-Yj1)/(Xj2-Xj1) 已知:JD2处曲线要素 切线长:T= 108.493 求得:ZH点坐标(X0, Y0)如下: X0=xj2-T*cos(D) Y0=yj2-T*sin(D)

以直缓点为坐标原点,切线方向为X轴,垂直于切线方向为Y轴建立坐标系如下图:

新坐标系X1-Y1的X轴(X1),相对于原城市坐标系X-Y的X轴(X)的方位角为D。

已知直缓点的里程桩号为K7+932.274,下面来求第一段缓和曲线上里程桩号为V处点(以下描述为A点)的城市坐标:

A点距直缓点的弧线距离为l=V-7932.274;

A点在X1-Y1坐标系中的坐标为(x1,y1),则:

x1= l-pow(l,5)/(40*pow(r,2)*pow(ls,2))+pow(l,9)/(3456*pow(r,4)*pow(ls,4))

y1= pow(l,3)/(6*r*ls)-pow(l,7)/(336*pow(r,3)*pow(ls,3))+pow(l,11)/(42240*pow(r*ls,10)) 注:pow(a,b)表示a的b次方

将X1-Y1坐标系中求得的坐标(x1,y1)转换为X-Y坐标系中的坐标,即可求得第一段缓和曲线上任意

点的城市坐标,设为(X,Y),计算如下:

X= X0+ x1*cos(D)- y1*sin(D) Y= Y0+ x1*sin(D)+ y1*cos(D)

同时还可根据缓和曲线旋转角公式求得HY点处切线方位角D1 D1=D+ ls/(2*r)

注:ls和r为已知曲线要素:ls=61.022,r=450

第一段缓和曲线终点坐标也可算出(令l=ls),即为缓和曲线所接圆曲线的起点(HY)处坐标。

2、第一段缓和曲线边桩坐标算法

第一段缓和曲线里程桩号为V处(A点)对应的边桩坐标计算: 1计算A点处切线方向方位角Dh ○

Dh=D+l*l/(2*r*ls)

2假定桩中心距离为dz,则可根据A点的城市坐标(X,Y)算出边桩坐标设为(X左,Y左)、(X右,Y右) ○

X左=X+(dz*sin(Dh))/2

Y左=Y-(dz*cos(Dh))/2 X右=Y-(dz*sin(Dh))/2 Y右=Y+(dz*cos(Dh))/2

二、圆曲线部分

下面同理以HY点处切线方向(顺桥向)为X轴建立坐标系,可知其X轴对应的方位角为D1(已求出),坐标原点为前一段缓和曲线终点坐标(已求得)。现在只需知道圆曲线弧长ly关于以HY点处切线为X轴建立的坐标系的坐标表达式即可同理求得圆曲线上任意点的城市坐标。计算式如下:

Xy=r*sin(ly/r); Yy=r*(1-cos(ly/r)); ly=V-7993.296

注:r为圆曲线半径,ly为圆曲线上任意点到HY点(新坐标系原点)处的弧长,v为待求点里程桩号

然后将所求坐标(Xy,Yy)和方位角D1,代入坐标转换公式即可算出圆曲线上任意点的城市坐标。

边桩坐标算法同缓和曲线部分,唯一要确定的是圆曲线上任意点处切线方向(顺桥向)对应的方位角Dy

Dy=D1+ly/r

以此类推,即可求得全长组合曲线上任意点的城市坐标。

附:边桩坐标计算公式推导方法

设桩中心距为dz且(X1,Y1)为左桩、(X2、Y2)为右桩,则X1-Y1坐标系中: X1=-dz/2;Y1=0 X2= dz/2;Y2=0

代人坐标转换公式即可求得左右边桩的城市坐标:

dzX1Xasin(Dh)

2dzY1Yacos(Dh)

2dzX2Xasin(Dh)

2dzY2Yacos(Dh)

2ll DhD2rls以上边桩坐标公式的推导是建立在边桩连线与中桩点处切线垂直的基础之上的,对于特殊路段为了避开铁路、电缆管道等设施,边桩连线与切线往往不垂直,以下说明计算方式。

设切线绕切点(A)顺时针旋转角度(α)即为边桩连线,一般情况下α=π/2,计算方式不变

当α≠π/2时,只需将上述公式中的Dh换成Dh+α-π/2即可,显而易见此种情况下的公式仍适用于α=π/2的一般情况。所以,边桩坐标计算的通用公式为:

dzsin(Dh-/2) 2dzY1Yacos(Dh-/2)

2dzX2Xasin(Dh-/2)

2dzY2Yacos(Dh-/2)

2X1Xa三角函数转换得:

dzcos(Dh) 2dzY1Yasin(Dh)

2dzX2Xacos(Dh)

2dzY2Yasin(Dh)

2X1Xa

注:l为A点到ZH点的弧长,ls为缓和曲线全长,α要转换为弧度数后统一计算

结语:坐标转换是计算坐标的核心思想,关键在于确定所建立切线支距坐标系的坐标方程以及方位角。

另外,对于曲率半径由R变为无穷大(直线)的缓和曲线,可反向建立坐标系求解,也可直接套用不完整缓和曲线的坐标方程式求解。

对于不完整缓和曲线可将其补充为完整缓和曲线求解,也可直接套用公式求解。 不完整缓和曲线切线支距坐标系下的坐标方程及转角计算参见我的另一篇文档,链接如下: 不完整缓和曲线修正版_

C语言编程坐标算法举例(可做参考)

#include #include

void fh(double l,double r,double ls,double *p1,double *p2) /*缓和曲线坐标计算*/ {

*p1=l-pow(l,5)/(40*pow(r,2)*pow(ls,2))+pow(l,9)/(3456*pow(r,4)*pow(ls,4));

*p2=pow(l,3)/(6*r*ls)-pow(l,7)/(336*pow(r,3)*pow(ls,3))+pow(l,11)/(42240*pow(r*ls,10));

}

void fy(double r,double l,double *p1,double *p2) /*圆曲线坐标计算*/ {

*p1=r*sin(l/r); *p2=r*(1-cos(l/r));

}

void XY(double x0,double y0,double x,double y,double D,double *p1,double *p2) /*坐标转换*/ {

*p1=x0+x*cos(D)-y*sin(D); *p2=y0+x*sin(D)+y*cos(D); }

void B(double X,double Y,double D,double dz,double *x1,double *y1,double *x2,double *y2) /*计算边桩坐标*/ {

*x1=X+dz*sin(D)/2;

*y1=Y-dz*cos(D)/2; *x2=X-dz*sin(D)/2; *y2=Y+dz*cos(D)/2;

}

void Q(double x1,double y1,double x2,double y2,double T,double *D,double *x,double *y) /*计算辅助方位角及转点坐标*/ { }

void Z(double l,double r,double A,double *p,double *q) /*不完整缓和曲线坐标计算*/ {

*p=l-pow(l,3)/(6*r*r)-pow(l,4)/(8*r*A)-pow(l,5)/(40*A*A)+pow(l,5)/(120*pow(r,4))+pow(l,6)/(72*r*r*r*A)+pow(l,7)/(112*r*r*A*A)+pow(l,8)/(384*A*A*A*r)+pow(l,9)/(3456*pow(A,4));

*q=l*l/(2*r)+pow(l,3)/(6*A)-pow(l,4)/(24*r*r*r)-pow(l,5)/(20*r*r*A)-pow(l,6)/(48*r*A*A)-pow(l,7)/(336*A*A*A)+pow(l,6)/(720*pow(r,5))+pow(l,7)/(336*pow(r,4)*A)+pow(l,8)/(384*r*r*r*A*A)+pow(l,9)/(864*r*r*pow(A,3))+pow(l,10)/(3840*r*pow(A,4))+pow(l,11)/(42240*pow(A,5));

} main()

{double x1,x2,y1,y2,xzh,yzh,xhh,yhh,v,l,T1,T2,π=3.1415926535898; double x,y,X,Y;

double r,r2,r3,ls1,ls2,ls3,la1,la2,la3,ls4;

*D=atan((y2-y1)/(x2-x1));

*x=x2-T*cos(*D); *y=y2-T*sin(*D);

double D,dz,A,L,E;

double Xjd1,Xjd2,Yjd1,Yjd2,Xjd3,Yjd3; double I1,O1,P1; char *se,password[20]; int m,n,i; se=\"hj135\"; for(i=0;i<3;i++) {printf(\"请输入密码:\"); gets(password);

if(strcmp(password,se)==0) {printf(\"密码正确:\\n\");

while(1) { A=265.226;

r=450;r2=400;r3=255;ls1=61.022;la1=93.301;ls2=61.022;ls3=60;la2=160;ls4=100;la3=255; Xjd1=52423.114;Yjd1=58247.423;Xjd2=52635.217;Yjd2=58398.947,Xjd3=52882.522,Yjd3=58754.649; T1=108.493;T2=108.493;

/*计算第一段缓和曲线起点坐标及方位角D*/ Q(Xjd1,Yjd1,Xjd2,Yjd2,T1,&D,&xzh,&yzh); A=A*A;

printf(\"请输入待计算点里程桩号:\"); scanf(\"%lf\",&v);

printf(\"请输入桩中心距:\"); scanf(\"%lf\",&dz); system(\"cls\");

/*计算第一段缓和曲线任意点坐标*/ if(v>=7932.274&&v<=7993.296) {

m=(int)v;n=(int)v;

m=m/1000;n=n%1000; fh(l,r,ls1,&x,&y);

printf(\"桩号K%d+%d 处:\\n中桩坐标为:(%f,%f)\\n\",m,n,X,Y); /*计算边桩坐标*/ l=v-7932.274;

XY(xzh,yzh,x,y,D,&X,&Y);

D=D+l*l/(2*r*ls1);

B(X,Y,D,dz,&x1,&y1,&x2,&y2);

printf(\"左桩坐标为:(%f,%f)\\n\",x1,y1); printf(\"右桩坐标为:(%f,%f)\\n\",x2,y2); }

/*计算第一段圆曲线上点的坐标*/

else if(v>7993.296&&v<=8086.597) {

m=(int)v;n=(int)v; m=m/1000;n=n%1000;

fh(ls1,r,ls1,&x,&y); XY(xzh,yzh,x,y,D,&X,&Y);

/*计算边桩坐标*/

D=D+l/r;

B(X,Y,D,dz,&x1,&y1,&x2,&y2);

/*计算第一段圆曲线上任意点的坐标*/ l=v-7993.296; fy(r,l,&x,&y);

printf(\"桩号K%d+%d 处:\\n中桩坐标为:(%f,%f)\\n\",m,n,X,Y);

/*计算第一段圆曲线起点方位角D*/

D=D+ls1/(2*r);

XY(X,Y,x,y,D,&X,&Y);

printf(\"左桩坐标为:(%f,%f)\\n\",x1,y1); printf(\"右桩坐标为:(%f,%f)\\n\",x2,y2); }

/*镜像计算第二段缓和曲线上点的坐标*/

else if(v>8086.597&&v<=8147.619) {

m=(int)v;n=(int)v; m=m/1000;n=n%1000;

/*计算第二段缓和曲线终点坐标及方位角*/ Q(Xjd3,Yjd3,Xjd2,Yjd2,-T2,&D,&xhh,&yhh);

D=D+π/2;

/*计算第二段缓和曲线任意点坐标*/ l=8147.619-v;

fh(l,r,ls2,&y,&x);

printf(\"桩号K%d+%d 处:\\n中桩坐标为:(%f,%f)\\n\",m,n,X,Y);

XY(xhh,yhh,x,y,D,&X,&Y);

/*计算边桩坐标*/

Q(Xjd1,Yjd1,Xjd2,Yjd2,T1,&D,&xzh,&yzh); l=v-8086.597;

D=D+ls1/(2*r)+la1/r+l/r-l*l/(2*r*ls2);

if(v==8105){D=D+(1+31.0/60+23.16/3600)*π/180;}

else if(v>8147.619&&v<=8207.619) {

m=(int)v;n=(int)v; m=m/1000;n=n%1000;

Q(Xjd3,Yjd3,Xjd2,Yjd2,-T2,&D,&xhh,&yhh);

}

/*计算第三段缓和曲线上点的坐标*/

B(X,Y,D,dz,&x1,&y1,&x2,&y2);

printf(\"左桩坐标为:(%f,%f)\\n\",x1,y1); printf(\"右桩坐标为:(%f,%f)\\n\",x2,y2);

l=v-8147.619; fh(l,r2,ls3,&x,&y);

/*计算边桩坐标*/

D=D-l*l/(2*r2*ls3);

y=-y;

printf(\"桩号K%d+%d 处:\\n中桩坐标为:(%f,%f)\\n\",m,n,X,Y);

XY(xhh,yhh,x,y,D,&X,&Y);

if(v==8185){D=D-(90-89-13.0/60-8.76/3600)*π/180;}

B(X,Y,D,dz,&x1,&y1,&x2,&y2);

printf(\"左桩坐标为:(%f,%f)\\n\",x1,y1); printf(\"右桩坐标为:(%f,%f)\\n\",x2,y2); }

/*计算第二段圆曲线上点的坐标*/ else if(v>8207.619&&v<=8367.619) {

/*计算第二段圆曲线任意点坐标*/

D=D-ls3/(2*r2); l=v-8207.619; y=-y;

m=(int)v;n=(int)v;

/*计算第二段圆曲线的起点坐标*/ m=m/1000;n=n%1000;

Q(Xjd3,Yjd3,Xjd2,Yjd2,-T2,&D,&xhh,&yhh);

fh(ls3,r2,ls3,&x,&y);

y=-y;

XY(xhh,yhh,x,y,D,&X,&Y);

fy(r2,l,&x,&y);

XY(X,Y,x,y,D,&X,&Y);

/*计算边桩坐标*/ D=D-l/r2;

if(v==8225)D=D+(3.0+42.0/60+50.32/3600)*π/180;

B(X,Y,D,dz,&x1,&y1,&x2,&y2);

printf(\"左桩坐标为:(%f,%f)\\n\",x1,y1); printf(\"右桩坐标为:(%f,%f)\\n\",x2,y2); }

/*计算第四段缓和曲线上点的坐标*/ else if(v>8367.619&&v<=8467.619)

/*计算边桩坐标*/

D=D-l/r2-l*l/(2*A);

l=v-8367.619; Z(l,r2,A,&x,&y); y=-y;

printf(\"桩号K%d+%d 处:\\n中桩坐标为:(%f,%f)\\n\",m,n,X,Y); {

m=(int)v;n=(int)v; m=m/1000;n=n%1000; fh(ls3,r2,ls3,&x,&y);

y=-y;

D=D-ls3/(2*r2); y=-y;

printf(\"桩号K%d+%d 处:\\n中桩坐标为:(%f,%f)\\n\",m,n,X,Y);

Q(Xjd3,Yjd3,Xjd2,Yjd2,-T2,&D,&xhh,&yhh);

XY(xhh,yhh,x,y,D,&X,&Y); fy(r2,la2,&x,&y); XY(X,Y,x,y,D,&X,&Y); D=D-la2/r2;

XY(X,Y,x,y,D,&X,&Y);

B(X,Y,D,dz,&x1,&y1,&x2,&y2);

printf(\"左桩坐标为:(%f,%f)\\n\",x1,y1); printf(\"右桩坐标为:(%f,%f)\\n\",x2,y2); }

/*计算第三段圆曲线上点的坐标*/ else if(v>8467.619&&v<=8599.2398)

{

m=(int)v;n=(int)v; m=m/1000;n=n%1000;

/*计算第三段圆曲线起点的坐标*/ fh(ls3,r2,ls3,&x,&y);

y=-y;

D=D-ls3/(2*r2); y=-y;

Q(Xjd3,Yjd3,Xjd2,Yjd2,-T2,&D,&xhh,&yhh);

XY(xhh,yhh,x,y,D,&X,&Y); fy(r2,la2,&x,&y); XY(X,Y,x,y,D,&X,&Y); D=D-la2/r2;

/*计算第三段圆曲线上任意点的坐标*/

/*计算边桩坐标*/

D=D-l/r3;

l=v-8467.619;

D=D-ls4/r2-ls4*ls4/(2*A); y=-y;

printf(\"桩号K%d+%d 处:\\n中桩坐标为:(%f,%f)\\n\",m,n,X,Y);

Z(ls4,r2,A,&x,&y); y=-y;

XY(X,Y,x,y,D,&X,&Y);

fy(r3,l,&x,&y); XY(X,Y,x,y,D,&X,&Y);

B(X,Y,D,dz,&x1,&y1,&x2,&y2);

printf(\"左桩坐标为:(%f,%f)\\n\",x1,y1); printf(\"右桩坐标为:(%f,%f)\\n\",x2,y2); } else

printf(\"\\n\"); } }}}

注:以上程序运行时要输入密码,为hj135

printf(\"桩号输入错误,请重新输入:\");

因篇幅问题不能全部显示,请点此查看更多更全内容