后方交会
目录
第1章计算公式
如下图所示,已知A、B、C三点的坐标,通过测量三个角度α、β、γ即可求出这三个角度顶点P的坐标。此即为后方交会。
图1.1
1.1 计算公式一
1.1.1 角度取法
上述公式在形式上是十分优美的,但是实际使用一下该公式就会发现一个至关重要的问题被遗漏了——那就是A、B、C、α、β、γ这六个角度该如何取值?
下图对角度A、α的取值分四种情况进行了说明:
图1.2
上图中,角度A、α的取值遵循两条规则:
1、正方向规则:角度的增加方向(正方向),与坐标系方位角的增加方向保持一致。具体的就是数学系里角度正方向为逆时针,测量系里角度正方向为顺时针。
2、起终规则:顶点、起点、终点遵循X,X+1,X+2规则。
当X为A时,顶点、起点、终点分别为A,B,C。意味着:角A的起始边为AB,终止边为AC;角α的起始边为PB,终止边为PC;
当X为B时,顶点、起点、终点分别为B,C,A。意味着:角B的起始边为BC,终止边为BA;角β的起始边为PC,终止边为PA;
当X为C时,顶点、起点、终点分别为C,A,B。意味着:角C的起始边为CA,终止边为CB;角γ的起始边为PA,终止边为PB。
1.1.2 代码实现
下面是后方交会计算公式一的C代码实现:
/******************************************************\ 后方交会计算 x,y [in] 三个已知点的x、y坐标 HA [in] 三个已知点的水平角观测值,单位:弧度 XP,YP [out] 待求点 P 的坐标 \******************************************************/ void HJ1(double x[3],double y[3],double HA[3],double*XP,double*YP) { int i = 0; int nA = 0; int nB = 1; int nC = 2; double ctg = 0.0; double pi_2= 1.5707963267948966192313216916398; double P = 0.0; //权 double xp = 0.0; double yp = 0.0; double sp = 0.0; //权的累加值 for(i = 0;i < 3;++i) { ctg = ((x[nB]-x[nA])*(x[nC]-x[nA])+(y[nB]-y[nA])*(y[nC]-y[nA])) / ((x[nB]-x[nA])*(y[nC]-y[nA])-(x[nC]-x[nA])*(y[nB]-y[nA])); P = 1.0 / (ctg + tan(pi_2 + HA[nC] - HA[nB])); xp += x[i] * P; yp += y[i] * P; sp += P; if(++nA > 2) { nA = 0; } if(++nB > 2) { nB = 0; } if(++nC > 2) { nC = 0; } } if(XP) { *XP = xp / sp; } if(YP) { *YP = yp / sp; } } |
测试代码如下
void TestHJ1() { srand(time(NULL)); double x[3]; double y[3]; double HA[3]; double xP = rand(); double yP = rand(); double HA0 = rand(); int i; for(i = 0;i < 3;++i) { x[i] = rand(); y[i] = rand(); HA[i] = atan2(y[i] - yP,x[i] - xP) + HA0; } double XP = 0.0; double YP = 0.0; HJ1(x,y,HA,&XP,&YP); double deltaX = XP - xP; //这个数值应该接近于零 double deltaY = YP - yP; //这个数值应该接近于零 } |
1.2 计算公式二
1.2.1 公式推导
1.2.2 代码实现
下面是后方交会计算公式二的C代码实现:
void HJ2(double xA,double yA,double HAa ,double xB,double yB,double HAb ,double xC,double yC,double HAc ,double*XP,double*YP) { double pi_2= 1.5707963267948966192313216916398; double ctg = 0.0; ctg = tan(pi_2 - (HAb - HAa)); double x1 = 0.5 * (xA + xB + (yA - yB) * ctg); double y1 = 0.5 * (yA + yB + (xB - xA) * ctg); ctg = tan(pi_2 - (HAc - HAa)); double x2 = 0.5 * (xA + xC + (yA - yC) * ctg); double y2 = 0.5 * (yA + yC + (xC - xA) * ctg); double k = 2.0*(yA*(x2-x1)+xA*(y1-y2)+x1*y2-x2*y1) / ((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)); if(XP) { *XP = xA + k * (y2 - y1); } if(YP) { *YP = yA + k * (x1 - x2); } } |
测试代码如下
void TestHJ2() { srand(time(NULL)); double xA = rand(); double yA = rand(); double xB = rand(); double yB = rand(); double xC = rand(); double yC = rand(); double xP = rand(); double yP = rand(); double HA0 = rand(); double HAa = atan2(yA - yP,xA - xP) + HA0; double HAb = atan2(yB - yP,xB - xP) + HA0; double HAc = atan2(yC - yP,xC - xP) + HA0; double XP = 0.0; double YP = 0.0; HJ2(xA,yA,HAa,xB,yB,HAb,xC,yC,HAc,&XP,&YP); double deltaX = XP - xP; //这个数值应该接近于零 double deltaY = YP - yP; //这个数值应该接近于零 } |
1.3 危险圆
推导公式二时,若两个圆心O1、O2重合,会是个什么情况?
此时,这两个圆都会通过A、B、C三点,点P会在这个圆上。显然这个圆就是三角形ABC的外接圆。点P在这个圆的任何位置都能保证三个夹角为α、β、γ。
外业测量时,点P落在危险圆附近的情况一定要避免。这里介绍两种规避方法:
1、点P尽量要在三角形ABC的内部;
2、后方交会程序计算完成后,如果显示了定位精度就查看一下该数值。定位精度数值越大,说明点P离危险圆越近,定位结果越不可靠。
如何计算后方交会的定位精度,请参考下一章的内容。
第2章精度评定