Simple Adjustment Calculation Of Wires(amend)

UI的搭建(参考)

 注意其中文本框和列表需要用groupBox1框住。

在第二页放一个charts控件。

listbox的item属性如下;

由于需要导入xls文件,我们需要引用Microsoft Office 16.0 Object Library

引用方法如下;右键添加引用,搜索excel安装即可

 

 准备工作完成

接下来是主界面的字段

public List<System.Windows.Forms.TextBox> tb = new List<System.Windows.Forms.TextBox>();//输入框
public bool model=false;    //手写模式是否打开

 手写模式的判定

  private void 切换模式手写ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if(model==false)
            {
               this.groupBox1.Enabled= true;

                model= true;
                this.label7.Text = "手写模式";
            }
            else {
                    this.groupBox1.Enabled= false;
                model= false;
                this.label7.Text = "读取模式";
            }
        }

 两种读取文件方法的封装;

TXT

 public void txt(string filename)//读取txt文件
        {
            string[] data;//总数据
            data = File.ReadAllLines(filename, Encoding.Default);
            for (int i = 0; i < data.Length; i++)
            {
                if (data[i].Contains("数据"))
                {
                    this.listBox1.SelectedIndex = data[i + 1] == "1" ? 0 : 1;//导线类型
                    //读取已知点坐标
                    string[] po = data[i + 4].Split(',');
                     //给文本框赋值
                    for (int j = 0; j < po.Length - 1; j += 2)
                    {
                        tb[j].Text = po[j];
                        tb[j+1].Text = po[j+1];
                     }
                    //分别给角度,长度赋值
                    this.listBox2.SelectedIndex = data[i + 5] == "1" ? 0 : 1;//导线类型                 
                    string[] angleTemp = data[i + 6].Split(',');
                    string[] LengthTemp = data[i + 7].Split(',');
                    for (int j = 0;j<angleTemp.Length;j++)
                    {
                        dataGridView1.Rows.Add();
                        dataGridView1.Rows[j].Cells[0].Value = angleTemp[j];
                    }
                    for (int j = 0; j < LengthTemp.Length; j++)
                    { dataGridView1.Rows[j].Cells[1].Value = LengthTemp[j]; }
                }
            }
        }

        EXCEL(使用相对坐标的方式增加读取文件的兼容性)

  public void excel(string filename)//读取excel文件
        {
            Microsoft.Office.Interop.Excel.Application xlsApp = new Microsoft.Office.Interop.Excel.Application(); // Excel程序对象
            Microsoft.Office.Interop.Excel.Workbook Wb = null; // Exce 工作簿对象
            Microsoft.Office.Interop.Excel.Worksheet WSheet = null; // Exce工作表对象
            xlsApp.Visible = false; // Excel程序对象界面不可见
            xlsApp.DisplayAlerts = true; // 不显示系统提示
            Wb = xlsApp.Workbooks.Open(filename); // 打开Excel文件
            WSheet = Wb.Sheets[1]; // 指定工作表
            int XStart = 0;
            int XEnd = 0;
            //遍历所有有效行获取数据
            for(int i=1;i<=WSheet.UsedRange.Rows.Count;i++)
            {
               //获取当前遍历行的值
               string value =(string) WSheet.Cells[i,1].Value;
                if(value== "已知点信息")//
                {                  
                    //获取坐标起始行
                    XStart= i;
                }
                if (value == "夹角类型")//
                {
                    //获取坐标结束行
                    XEnd= i;
                    break;
                }       
            }
            //开始给控件赋值
            this.listBox1.SelectedIndex= WSheet.Cells[XStart - 1, 2].Value=="附和导线"?0:1;//导线类型
            this.listBox2.SelectedIndex = WSheet.Cells[XEnd, 2].Value == "左角" ? 0:1 ;//观测角类型
            //坐标获取
            //获取坐标有效行数
            int hang = XEnd - XStart - 2;
            for (int i = 0; i < hang; i++)
            {
                tb[i].Text = (string)WSheet.Cells[XStart+2+i,2].Value;
                tb[i].Text = (string)WSheet.Cells[XStart + 2+i, 3].Value;
            }
            //获取角度有效行数
            int hang_angle = WSheet.UsedRange.Rows.Count - XEnd -4;
            //获取未知点个数
            for (int i=0;i<hang_angle;i++)
            {
                dataGridView1.Rows.Add();
                dataGridView1.Rows[i].Cells[0].Value = WSheet.Cells[XEnd + 4 + i, 2].Value;
            }
            for (int i = 0; i < hang_angle-1; i++)
            {
                dataGridView1.Rows[i].Cells[1].Value = WSheet.Cells[XEnd + 5 + i, 3].Value;
            }
        }

则导入文件的代码就写完了。

最后判断调用即可。

 private void 文件ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Filter = "文本文件(*.txt)|*.txt|Excel表格文件(*.xls)|*.xls";
            openFileDialog.InitialDirectory = @"C:\";
            openFileDialog.Title = "Select a Text File";

            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {            
                try
                {
                    //ToloWer是转小写的方法
                    string fileName = openFileDialog.FileName;
                    if (fileName.ToLower().Contains(".txt"))
                        txt(fileName); // 从文本文件中导入数据
                    if (fileName.ToLower().Contains(".xls"))
                        excel(fileName); // 从XLS文件中导入数据                                                                                  
                }
                catch (Exception ex)
                {
                    MessageBox.Show("An error occurred: " + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            else
            {
                MessageBox.Show("导入失败");
                return;
            }
        }

---------------------------------------------------------------------------------------------------------------------------------

MethodL类

我们新建一个类,用于计算。

它具有以下字段

 public string angle_type;
        public string length_type;
        public PointF startPointF1;//起始点坐标
        public PointF startPointF2;//起始点坐标
        public PointF endPointF1;//结束点坐标
        public PointF endPointF2;//结束点坐标
        public int n;//未知点个数
        List<double> angle = new List<double>(); //角度
        List<double> length = new List<double>(); //长度
        List<double> calculateBearing = new List<double>(); //坐标方位角
        List<double> calculateBearing_rapir = new List<double>(); //修正后坐标方位角
        List<double> X = new List<double>(); //近似坐标X
        List<double> Y = new List<double>(); //近似坐标Y
        List<double> XRapir = new List<double>(); //修正X
        List<double> YRapir = new List<double>(); //修正Y
        double angle_start;//起始方位角
        double angle_end;//结束方位角
        double f_angle;//方位角闭合差
        double f_x;
        double f_y;
        double f_s;     

写一个读取控件属性给类的字段赋值初始化的函数

代码如下;

  foreach (DataGridViewRow row in form1.dataGridView1.Rows)
            {              
                    if(row.Cells[0].Value==null)
                    { continue; }
                    angle.Add( Convert.ToDouble(row.Cells[0].Value)); // 获取第一列数据,并添加到 List 中              
            }
            for(int i=0; i<angle.Count; i++) { angle[i] =DMS2Hu( angle[i]); }
            foreach (DataGridViewRow row in form1.dataGridView1.Rows)
            {
                if (!row.IsNewRow) // 排除新行
                {
                    if (row.Cells[1].Value == null)
                    { continue; }
                    length.Add(Convert.ToDouble(row.Cells[1].Value)); // 获取第一列数据,并添加到 List 中
                }
            }
            this.n = length.Count-1;//未知点个数            
            //获取类型
           this.angle_type= form1.listBox2.SelectedItem.ToString();
            this.length_type = form1.listBox1.SelectedItem.ToString();
            //计算起终方位角
            if (length_type == "附和")
            {
                //获取已知点坐标
                this.startPointF1 = new PointF(float.Parse(form1.textBox1.Text), float.Parse(form1.textBox2.Text));
                this.startPointF2 = new PointF(float.Parse(form1.textBox3.Text), float.Parse(form1.textBox4.Text));
                this.endPointF1 = new PointF(float.Parse(form1.textBox5.Text), float.Parse(form1.textBox6.Text));
                this.endPointF1 = new PointF(float.Parse(form1.textBox7.Text), float.Parse(form1.textBox8.Text));
                angle_start = CalculateBearing(startPointF1.X, startPointF1.Y, startPointF2.X, startPointF2.Y);
                angle_end = CalculateBearing(endPointF1.X,endPointF1.Y,endPointF2.X,endPointF2.Y);
            }
            else
            {
                //获取已知点坐标
                this.startPointF1 = new PointF(float.Parse(form1.textBox1.Text), float.Parse(form1.textBox2.Text));
                this.startPointF2 = new PointF(float.Parse(form1.textBox3.Text), float.Parse(form1.textBox4.Text));
                angle_start = CalculateBearing(startPointF1.X, startPointF1.Y, startPointF2.X, startPointF2.Y);
                angle_end = Math.PI + angle_start;
            }          

它的基础计算函数如下

角度转换

public static double DMS2Hu(double dms)
        {
            int d, m;
            double s;
            d = (int)Math.Floor(dms);
            m = (int)Math.Floor((dms - d) * 100);
            s = ((dms - d) * 100 - m) * 100;
            double val;
            val = (d + m / 60.0 + s / 3600.0) * Math.PI / 180;
            return val;
        }

绘图函数

 public  void  paint (Form1 form1,System.Windows.Forms.DataVisualization.Charting.Chart chart)//绘图方法
            {
             List<PointF> list = new List<PointF>();//附和部分
         
            for (int i = 0; i < XRapir.Count;i++)
            {
                PointF pointF=new PointF((float)XRapir[i], (float)YRapir[i]);
                list.Add(pointF);            
            }
            if (length_type == "附和")
            {
                list.Insert(0, this.startPointF2);
                list.Insert(0, this.startPointF1);
                list.Add(this.endPointF2);
            }
            else
            {
                list.Insert(0, this.startPointF2);
                list.Insert(0, this.startPointF1);
            }
            //开始绘图 
            // 清空所有的数据点和系列
            chart.Series.Clear();
                chart.ChartAreas.Clear();
                // 添加一个新的 ChartArea
                System.Windows.Forms.DataVisualization.Charting.ChartArea chartArea = chart.ChartAreas.Add("ChartArea");
                chartArea.AxisX.Title = "Y";
                chartArea.AxisY.Title = "X";
            // 添加2个新的 Series 并设置其属性
            chart.Titles.Add("Closed Curve");
            chart.ChartAreas.Add(new System.Windows.Forms.DataVisualization.Charting.ChartArea("Default"));
            chart.Series.Add(new System.Windows.Forms.DataVisualization.Charting.Series("Curve"));
            chart.Series["Curve"].ChartType = SeriesChartType.Line;
            chart.Series["Curve"].BorderWidth = 3;
            chart.Series["Curve"].MarkerStyle = MarkerStyle.Circle;
            chart.Series["Curve"].MarkerSize = 8;
            chart.Series["Curve"].MarkerColor = Color.Red;
            chart.Series["Curve"].Color = Color.Blue;      
            // 添加数据点
            for (int i = 0; i < list.Count; i++)
            {
                chart.Series["Curve"].Points.AddXY(list[i].X, list[i].Y);
            }
         
                // 更新图表
                chart.Invalidate();
            }

方位角计算函数

 public static double CalculateBearing(double x1, double y1, double x2, double y2)
        {
            double dx = x2 - x1;
            double dy = y2 - y1;
            double angle = Math.Atan(dy / dx);
            if (dx < 0 && dy > 0) { angle += Math.PI; }
            else if (dx < 0 && dy < 0) { angle += Math.PI; }
            else if (dx > 0 && dy < 0) { angle += 2 * Math.PI; }
            return angle;//这是弧度
        }

1,计算近似坐标方位角的函数

闭合导线的比较特殊,首末点需要修正后用另一个公式计算。

还有注意判断两次值的大小是否为负值和大于180.

 public void angle_zhe()//遍历角度计算坐标方位角
        {
            if (length_type == "附和")

            {
                if (angle_type == "左角")//左角
                {
                    double temp = angle_start;
                    foreach (double x in angle)
                    {
                        temp = temp + x- Math.PI;
                        this.calculateBearing.Add(temp);
                    }
                }
                else//右角
                {
                    int i = 0;
                    double temp = angle_start;
                    foreach (double x in angle)
                    {
                        temp = temp - x + Math.PI;
                        temp = temp > 2 * Math.PI ? temp - 2 * Math.PI : temp;
                        temp = temp > 2 * Math.PI ? temp - 2 * Math.PI : temp;//判断是否大于360度,最多720度。判断两次    
                        this.calculateBearing.Add(temp);
                    }
                }
            }
            else
            {
                double temp = angle_start;
                if (angle_type == "左角")//左角
                {

                    //针对闭合切左角的情况需要对第一个角和最后一个进行改正
                    angle[0] = 2 * Math.PI - angle[0];
                    angle[angle.Count - 1] = angle[angle.Count - 1] + (2 * Math.PI - angle[0]);
                }
                    for (int j = 0; j < angle.Count; j++)
                    {                                        
                       temp = temp - angle[j] - Math.PI;
                        if (temp > 2 * Math.PI)
                        { temp -= 2 * Math.PI; }
                        if (temp <0)
                        { temp += 2 * Math.PI; }
                        if (temp < 0)
                        { temp += 2 * Math.PI; }
                        this.calculateBearing.Add(temp);
                    }
            }          
        }

2,计算是否超限(很简单自己加,略)

3,根据闭合差更新坐标方位角()

  public void upadat_angle()//更新方位角
        {
            int i = 1;
            double fb_ex = -this.f_angle / n;//闭合的均值
            foreach(double a in this.calculateBearing ) { calculateBearing_rapir.Add(a+i*fb_ex); i++; }
      
        }

4,计算近似坐标和改正坐标

ps,还需要检测fs是否超限!!

 public void Corrding(Form1 form1)//计算坐标增量和闭合差
        {
            //获取起始点坐标
           double x = Convert.ToDouble((form1.textBox3.Text));
           double y = Convert.ToDouble((form1.textBox4.Text));

            for (int i=0;i<length.Count;i++)
            {
                x = (x + length[i] * Math.Cos(calculateBearing_rapir[i]));
                X.Add(x);
                y = (y + length[i] * Math.Sin(calculateBearing_rapir[i]));
                Y.Add(y);           
            }
            //计算坐标闭合差
            if(length_type=="附和")
            {
                f_x = X[X.Count-1]-Convert.ToDouble( form1.textBox5.Text);
                f_y = Y[Y.Count - 1] - Convert.ToDouble(form1.textBox6.Text);
            }
            else
            {
                f_x = X[X.Count - 1] - Convert.ToDouble(form1.textBox3.Text);
                f_y = Y[Y.Count - 1] - Convert.ToDouble(form1.textBox4.Text);

            }
            double vx =0;
            double vy = 0;
            //分配并且计算坐标
            for (int i=0;i<X.Count;i++) 
            {
                vx += -f_x * length[i]  / length.Sum();
                vy += -f_y * length[i]  / length.Sum();
                double temp = X[i] + vx;
                double temp2 = Y[i] + vy;
                XRapir.Add(temp);   
                YRapir.Add(temp2);

            }
        }

Last(在主函数调用)

public   void main(Form1 form1,RichTextBox rich, System.Windows.Forms.DataVisualization.Charting.Chart chart)
        {
            //获取表格数据
            //边长
            foreach (DataGridViewRow row in form1.dataGridView1.Rows)
            {              
                    if(row.Cells[0].Value==null)
                    { continue; }
                    angle.Add( Convert.ToDouble(row.Cells[0].Value)); // 获取第一列数据,并添加到 List 中              
            }
            for(int i=0; i<angle.Count; i++) { angle[i] =DMS2Hu( angle[i]); }
            foreach (DataGridViewRow row in form1.dataGridView1.Rows)
            {
                if (!row.IsNewRow) // 排除新行
                {
                    if (row.Cells[1].Value == null)
                    { continue; }
                    length.Add(Convert.ToDouble(row.Cells[1].Value)); // 获取第一列数据,并添加到 List 中
                }
            }
            this.n = length.Count-1;//未知点个数            
            //获取类型
           this.angle_type= form1.listBox2.SelectedItem.ToString();
            this.length_type = form1.listBox1.SelectedItem.ToString();
            //计算起终方位角
            if (length_type == "附和")
            {
                //获取已知点坐标
                this.startPointF1 = new PointF(float.Parse(form1.textBox1.Text), float.Parse(form1.textBox2.Text));
                this.startPointF2 = new PointF(float.Parse(form1.textBox3.Text), float.Parse(form1.textBox4.Text));
                this.endPointF1 = new PointF(float.Parse(form1.textBox5.Text), float.Parse(form1.textBox6.Text));
                this.endPointF1 = new PointF(float.Parse(form1.textBox7.Text), float.Parse(form1.textBox8.Text));
                angle_start = CalculateBearing(startPointF1.X, startPointF1.Y, startPointF2.X, startPointF2.Y);
                angle_end = CalculateBearing(endPointF1.X,endPointF1.Y,endPointF2.X,endPointF2.Y);
            }
            else
            {
                //获取已知点坐标
                this.startPointF1 = new PointF(float.Parse(form1.textBox1.Text), float.Parse(form1.textBox2.Text));
                this.startPointF2 = new PointF(float.Parse(form1.textBox3.Text), float.Parse(form1.textBox4.Text));
                angle_start = CalculateBearing(startPointF1.X, startPointF1.Y, startPointF2.X, startPointF2.Y);
                angle_end = Math.PI + angle_start;
            }          
            angle_zhe();         
            calculateBearing.ForEach(n1 => rich.Text +=  (n1 * 180 / Math.PI).ToString("f4") + "\n");
            this.f_angle = calculateBearing[calculateBearing.Count - 1] - angle_end;
            upadat_angle();
            Corrding(form1);
            rich.Text = "未知点个数;" + n + "\n";
            rich.Text += "起始方位角是;" + angle_start * 180 / Math.PI + "\n";
            rich.Text += "终止方位角是;" + angle_end * 180 / Math.PI + "\n";
            rich.Text += "近似方位角是;" + "\n";
            for(int i=0;i<calculateBearing.Count;i++)
            { rich.Text += (calculateBearing[i] * 180 / Math.PI).ToString("f4") + "\n"; }
            rich.Text += "改正方位角是;" + "\n";
            for (int i = 0; i < calculateBearing_rapir.Count; i++)
            { rich.Text += (calculateBearing_rapir[i] * 180 / Math.PI).ToString("f4") + "\n"; }
            rich.Text += "角度闭合差是" + this.f_angle+"\n";
            rich.Text += "近似坐标是" + "\n";
            for (int i=0;i<X.Count;i++)
            {
                rich.Text += "x;" + X[i].ToString("f4") + "  "+"y;" + Y[i].ToString("f4") + "\n";
            }
            rich.Text += "改正坐标是"  + "\n";
            for (int i = 0; i < X.Count; i++)
            {
                rich.Text += "x;" + XRapir[i].ToString("f4") + "  " + "y;" + YRapir[i].ToString("f4") + "\n";
            }
            paint(form1,chart);
        }

完结

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值