有窗体的闭合导线计算程序(C#)

在测绘的实际操作中,我们会遇到这样的一些闭合导线的计算。闭合导线的计算比较复杂,我们如何利用计算机帮助我们快速地计算,这里我们使用C#编写一个有(好看)界面的导线计算程序

问题
在这里插入图片描述
这是我们计算的结果
在这里插入图片描述
这是答案的结果
在这里插入图片描述

可以看出答案是差不多的,当然存在误差和计算机保存小数的一些问题有关。下面来看一下如何完成这样的一个简单的程序(默认知道闭合导线是怎么计算的)

角度(弧度)的转换的

  1. 这里我们输入是按照“dd ff mm” 的格式输入的,需要通过转换将其转换为小数形式,然后在计算三角函数时要化为弧度
    这里我们用的datagridview控件展示的数据,可以利用split()函数分割里面的单元格得到度分秒,通过这个公式得到角度
angle = D + F / 60 + M / 3600;  // 度分秒转换为度 

至于计算时的弧度,高中就知道可以这样完成

radian = angle / 180 * Math.PI;  // 角度转弧度 

计算角度的闭合差并分配误差

  1. 一个n边形的内角和是(n-2)*180度,但实际在测量中,肯定得不到准确的这个数据,所以我们需要计算闭合差并将其分配,使内角和等于理论值。这里的允许误差是40√n,n是测站数,分配原则是反向平均分配。这里我肯可以通过角度误差分配来实现
// 角度误差分配
        private void btnAng_Click(object sender, EventArgs e)
        {

            double rawang = (num - 2) * 180;  // 理论值
            double nowang = 0;  // 测量值
            double exang = 0;  // 分配误差
            double error = 0;  // 允许闭合差
            int i;  // 控制变量

            error = 40 * Math.Sqrt(num) / 3600;  // 计算允许的闭合差

            try
            {
                    for (i = 0; i < num; i++)
                    {
                        nowang += double.Parse(dgvList.Rows[i].Cells[0].Value.ToString());
                    }
                    exang = nowang - rawang;
                    if (Math.Abs(exang) > error)
                    {
                        MessageBox.Show("角度闭合差大于允许闭合差");
                    }
                    else
                    {
                        exang /= (-1) * num;
                        for (i = 0; i < num; i++)
                        {
                            dgvList.Rows[i].Cells[0].Value =
                                (Convert.ToDouble(dgvList.Rows[i].Cells[0].Value.ToString()) + exang);
                        }

                        dgvList.Rows[i].Cells[0].Value = "校正";
                    }

                    angle_able = true;
                }
                
            }
            catch{ }        
        }

计算坐标方位角

  1. 在得到坐标的增量时,我们需要坐标的方位角和测站的距离,距离已知了,所以这里我们要通过一个方法实现计算坐标的方位角
public double GetAngle(double lastaziang, double turnang, bool RorL)
        {
            double aziang = 0;//坐标方位角

            if (RorL == false)//右角公式
            {
                aziang = lastaziang + 180 - turnang;//角度
            }
            else//左角公式
            {
                aziang = lastaziang - 180 + turnang;
            }

            while (aziang > 360 || aziang < 0)
            {
                if (aziang > 360)
                {
                    aziang -= 360;
                }
                else if (aziang < 0)
                {
                    aziang += 360;
                }
            }

            return aziang;
        }

计算坐标的增量

  1. 坐标的增量可以通过dertX = distance * Math.Cos(azirad)dertY = distance * Math.Sin(azirad)求得,这个azirad就是坐标方位角的弧度形式
  2. 这里的写法比较简单,其中是在datagridview的单元格中直接先计算放上去的,后面的改正将会在原来的基础数据上改正
public void GetVariateDistance(DataGridView dgvList, int num)
        {
            int i;

            for (i = 0; i < num; i++)
            {
                dgvList.Rows[i].Cells[4].Value =
                    double.Parse(dgvList.Rows[i].Cells[1].Value.ToString()) * Math.Cos(double.Parse(dgvList.Rows[i].Cells[3].Value.ToString()) / 180 * Math.PI);
                dgvList.Rows[i].Cells[5].Value =
                    double.Parse(dgvList.Rows[i].Cells[1].Value.ToString()) * Math.Sin(double.Parse(dgvList.Rows[i].Cells[3].Value.ToString()) / 180 * Math.PI);
            }
        }

坐标增量的简单平差

  1. 因为这是一个闭合导线,所以理论上坐标增量的和应该为零(又回到最初的起点),然而因为误差的存在并不是这样的,所以我们要把闭合差(√((∑dertX)^ 2)+ (∑dertY)^ 2)))按照边长的比例反其符号分配给每个坐标增量,量距导线和测距导线的闭合差一般都小于1/2000,这里我们可以使用这样处理
public void ExVariateDistance(DataGridView dgvList, int num, double xVariate, double yVariate, double distance)
        {
            int i = 0;

            for (i = 0; i < num; i++)
            {
                xVariate += double.Parse(dgvList.Rows[i].Cells[4].Value.ToString());
                yVariate += double.Parse(dgvList.Rows[i].Cells[5].Value.ToString());
                distance += double.Parse(dgvList.Rows[i].Cells[1].Value.ToString());
            }

            xVariate /= ((-1) * distance);
            yVariate /= ((-1) * distance);

            for (i = 0; i < num; i++)
            {
                dgvList.Rows[i].Cells[4].Value =
                    (Convert.ToDouble(dgvList.Rows[i].Cells[4].Value.ToString()) + (xVariate * Convert.ToDouble(dgvList.Rows[i].Cells[1].Value.ToString())));
                dgvList.Rows[i].Cells[5].Value =
                    (Convert.ToDouble(dgvList.Rows[i].Cells[5].Value.ToString()) + (yVariate * Convert.ToDouble(dgvList.Rows[i].Cells[1].Value.ToString())));
            }

            dgvList.Rows[i].Cells[4].Value = "校正";
            dgvList.Rows[i].Cells[5].Value = "校正";
        }

最后就是求坐标

  1. 这个就是从已知的那个起点坐标开始加坐标增量,得到每一个导线点的坐标,也就是第二个点的X坐标就是X = startX + dertX,Y坐标是Y = startY + dertY。后面的点依次加dert。代码如下,这里使用(x|y)这样的格式显示
public void GetPoint(double BX, double BY, DataGridView dgvList, int num)
        {
            double X;
            double Y;

            try
            {
                X = BX + double.Parse(dgvList.Rows[0].Cells[4].Value.ToString());
                Y = BY + double.Parse(dgvList.Rows[0].Cells[5].Value.ToString());
                dgvList.Rows[0].Cells[6].Value = "(" + X + "|" + Y + ")";

                for (int i = 1; i < num; i++)
                {
                    X += double.Parse(dgvList.Rows[i].Cells[4].Value.ToString());
                    Y += double.Parse(dgvList.Rows[i].Cells[5].Value.ToString());
                    dgvList.Rows[i].Cells[6].Value = "(" + X + "|" + Y + ")";
                }
            }
            catch
            { }
        }

做后就完成了,只在豆丁上找了一个题测试了一下(见开头)。完整的代码没有贴出来,界面的设计也没说了,还有一些其他的杂七杂八的功能。这是很早之前写的,中间一些细节现在也忘了,之前的代码写的不好,但能提供一些参考作用,所以还是记录下来

评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值