纵横断面的计算

1,页面的设计

菜单,工具栏,表格

2,主界面的代码

主界面声明以下字段

 public partial class Form1 : Form
    {
        public double H0;
        public double L;
        public double S;
        public List<PointNew> I = new List<PointNew>();
        public List<PointNew> All = new List<PointNew>();
        public List<PointNew> K = new List<PointNew>();
        public List<CenterPointcs> M = new List<CenterPointcs>();

导入数据到表格展示(在导入的时候就完成的全部计算main()

  openFileDialog1.InitialDirectory = Directory.GetCurrentDirectory();
            if (openFileDialog1.ShowDialog() == DialogResult.OK)
            {
                string[][] data = File.ReadAllLines(openFileDialog1.FileName).Select(p => p.Split(',')).ToArray();
                this.H0 = double.Parse(data[0][1]);

                for (int i = 5; i < data.Length; i++)
                {
                    if (data[i][0].Contains("K"))
                    {
                        K.Add(new PointNew(data[i]));
                    }

                    All.Add(new PointNew(data[i]));

                    this.dataGridView1.Rows.Add(data[i]);
                }
                MainC();
            }
            else
            {
                MessageBox.Show("取消");
                return;
            }
            MessageBox.Show("读取成功");
        }

总算法(这个命名其实不规范,Algorithm更规范)

public void MainC()
        {
            BasicFunction.KMileag(K);
            L = K[K.Count - 1].mileage;
            BasicFunction.Inster(All, K, ref S, ref I);
            BasicFunction.CenterPointAlgorithm(K, All, ref M, H0);
        }

 3,类

新点类

构造一个新的点类

第四种构造函数的方便读取数据的

外带静态的计算距离的函数(加权计算高程时使用)

public class PointNew
    {
        public string ID;
        public double X;
        public double Y;
        public double H;
        public double mileage;
        public PointNew()
        {


        }
        public PointNew(double x,double y)
        {
            this.X = x;
            this.Y = y;
        }
        public PointNew(double x, double y,double h)
        {
            this.X = x;
            this.Y = y;
            this.H = h;
        }
        public PointNew(string[]data)
        {
            this.ID = data[0];
            this.X = double.Parse(data[1]);
            this.Y= double.Parse(data[2]);
            this.H= double.Parse(data[3]);
        }
        /// <summary>
        /// 距离计算函数
        /// </summary>
        /// <param name="p1"></param>
        /// <param name="p2"></param>
        /// <returns></returns>
        public  double  Distance(PointNew p2)
        {
            double dx = this.X - p2.X;
            double dy = this.Y - p2.Y;
            double distance = Math.Sqrt(dx * dx + dy * dy);
            return distance;
        }

中心点类(横断面的需要)

因为每个中心点都需要计算面积,所以设置以下字段方便计算 

public class CenterPointcs:PointNew
    {
       public double S;//横断面的面积
       public  List<PointNew> points=new List<PointNew>();//断面上的点
       public double K;//横断面的斜率


        /// <summary>
        /// 将中心点转换位PointNew形式,返回一个PointNew,不破坏原来的对象
        /// </summary>
        /// <returns></returns>
        public PointNew  ConvertToPointNew()
        {
            return new PointNew(this.X, this.Y, this.H);
        }

    }

IMPORTANT 计算的函数

加权计算高程的(使用sort或者orderby这个更方便但不是就地排序)

/// <summary>
        /// 加权计算点的高程
        /// </summary>
        /// <param name="p1"></param>
        /// <param name="ALl"></param>
        public static void Hight(PointNew p1,List<PointNew>ALl)
        {
            //根据距离排序

            List<PointNew> list= ALl.OrderBy(p => p.Distance(p1)).ToList();

            //取前五个的元素的距离计算

            double sum1 = list.Take(5).Sum(p => p.H / p.Distance(p1));
            double sum2 = list.Take(5).Sum(p => 1 / p.Distance(p1));
            p1.H = (sum1 / sum2);
        }

初始化k点的里程的(后面可以直接用里程计算长度)

/// <summary>
        /// 计算k点的里程
        /// </summary>
        /// <param name="K"></param>
        public static void KMileag(List<PointNew>K)
        {
            K[0].mileage = 0;
            double mileage = 0;

            for (int i = 1; i <K.Count ; i++)
            {
                mileage+= K[i].Distance(K[i - 1]);
                K[i].mileage = mileage;
            }
        }

两种断面的面积计算(写两个是因为偷懒,不想再计算横断面内插点的里程)

 /// <summary>
        /// 接收一段断面的点并且计算面积
        /// </summary>
        /// <param name="p"></param>
        /// <returns></returns>
        public static double Square(List<PointNew>p,double H)
        {
            double S = 0;
            for (int i = 0; i < p.Count-1; i++)
            {
                S += (p[i].H + p[i + 1].H - 2 * H) * (p[i + 1].mileage - p[i].mileage) / 2;
            }
            return S;
        }
        /// <summary>
        /// 接收一段横断面的点并且计算面积
        /// </summary>
        /// <param name="p"></param>
        /// <returns></returns>
        public static double Square2(List<PointNew> p, double H)
        {
            double S = 0;
            for (int i = 0; i < p.Count - 1; i++)
            {
                S += (p[i].H + p[i + 1].H - 2 * H) * (5) / 2;
            }
            return S;
        }

纵断面的内插点的计算

 /// <summary>
        /// 计算内插点坐标和高程
        /// </summary>
        /// <param name="ALL"></param>
        /// <param name="K"></param>
        /// <param name="S"></param>
        public static void Inster(List<PointNew>ALL,List<PointNew>K,ref double S,ref List<PointNew>I )
        {

            //里程计数器

            double L = 0;
            S = 0;
            for (int i = 0; i < K.Count-1; i++)
            {
                //计算方位角

             double angle=   Math.Atan2(K[i+1].Y - K[i].Y, K[i+1].X - K[i].X);

                //计算内插个数

                int num = (int)((K[i + 1].mileage - K[i].mileage) / 10);

                //添加K点到内插点集合

                I.Add(K[i]);
                
                for (int k = 0; k < num; k++)
                {
                    L += 10;
                    double detaL = L - K[i].mileage;//用增长的里程对K点的里程相减就可以获取detaL的长度
                    double X = K[i].X + detaL * Math.Cos(angle);
                    double Y = K[i].Y + detaL * Math.Sin(angle);
                    PointNew pointNew = new PointNew(X,Y);
                    BasicFunction.Hight(pointNew, ALL);
                    pointNew.mileage = L;
                    I.Add(pointNew);
                }
            }
            I.Add(K[K.Count - 1]);
        }

横断面的总算法

 /// <summary>
        /// 横断面的总算法
        /// </summary>
        /// <param name="K"></param>
        /// <param name="ALl"></param>
        /// <param name="M"></param>
        public static void CenterPointAlgorithm(List<PointNew>K,List<PointNew>ALl,ref List<CenterPointcs>M,double H)
        {
            //计算中心点

            for (int i = 0; i < K.Count-1; i++)
            {
                double X = K[i].X / 2 + K[i + 1].X/2;
                double Y = K[i].Y / 2 + K[i + 1].Y / 2;
                double k = Math.Atan2(K[i + 1].Y - K[i].Y, K[i + 1].X - K[i].X)+Math.PI/2;
                if(k<0)//因为使用antan2可能返回负数
                {
                    k += 2 * Math.PI;
                }
                CenterPointcs centerPointcs = new CenterPointcs();
                centerPointcs.X = X;
                centerPointcs.Y = Y;
                Hight(centerPointcs, ALl);
                M.Add(centerPointcs);
            }

            //计算横断面内插点

            int L = -25;
            for (int k = 0; k < M.Count; k++)
            {
                for (int i = 0; i < 10; i++)
                {
                    if(i==5)//因为i=5时和中心点重复了
                    {
                        M[k].points.Add(M[k].ConvertToPointNew());
                        continue;
                    }
                    double detaL = L + i * 5;
                    double X = M[k].X + detaL * Math.Cos(M[k].K);
                    double Y = M[k].Y + detaL * Math.Sin(M[k].Y);
                    PointNew pointNew = new PointNew(X, Y);
                    Hight(pointNew,ALl);
                    M[k].points.Add(pointNew);
                }
            }

            //计算面积

            for (int i = 0; i < M.Count; i++)
            {
                M[i].S = Square2(M[i].points,H);
            }

        }

4,成果的展示

创建了两个窗体,需要的时候实例化显示数据

private void 纵断面内插点计算ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Report report = new Report();
            report.Text = "内插点坐标";
            report.richTextBox1.Text = "---------纵断面内插点(包含K点)----------\n";
            report.richTextBox1.Text += "点号\t\tX\t\tY\t\tH\n";
            for (int i = 0; i < I.Count; i++)
            {
                report.richTextBox1.Text += i.ToString() + "\t\t" + I[i].X.ToString("f3") + "\t\t" + I[i].Y.ToString("f3") + "\t\t" + I[i].H.ToString("f3") + "\n";
            }
            report.Show();

        }

参考如下

 

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值