纵横断面计算

基本算法

  • 坐标方位角计算
  • 内插点高程计算
  • 断面面积计算

内容

  • 道路纵断面计算
  • 道路横断面计算

步骤

1 读取散点数据、关键点数据

数据结构:

  • 散点类 DicretePoint
  • 关键点类 KeyPoint
  • 插值点类 InsertPoint
  • 中心点类 CenterPoint

在这里插入图片描述

class DiscretePoint
    {
    
    
        public double X, Y, H;
        public string id;
        public double D;//用于记录与待插点的距离
        public DiscretePoint(string id, double x, double y, double h)
        {
    
    
            this.id = id;
            X = x;
            Y = y;
            H = h;
        }
        public DiscretePoint()
        {
    
     }
    }
  class KeyPoint
    {
    
    
        public double X, Y, H;
        public string id;
        public KeyPoint(string id , double x,double y,double h)
        {
    
    
            this.id = id;
            X = x;
            Y = y;
            H = h;
        }
        public KeyPoint()
        {
    
     }
    }
   class InsertPoint
    {
    
    
        public double X, Y, H;
        KeyPoint start = new KeyPoint();//起始的点
        public List<DiscretePoint> nearpoint = new List<DiscretePoint>();//最邻近的点
        public InsertPoint(List<DiscretePoint> Qs,KeyPoint start,double L,double alpha)
        {
    
    
            //X,Y坐标计算
            this.start = start;//起始点
            this.X = start.X + L * Math.Cos(alpha);
            this.Y = start.Y + L * Math.Sin(alpha);
            //H计算
            //内插高程计算,检索最邻近的5个点进行高程计算
            List<DiscretePoint> ps = new List<DiscretePoint>();
            ps.AddRange(Qs);
            for (int i = 0; i < ps.Count; i++)
            {
    
    
                ps[i].D = Math.Sqrt(Math.Pow(ps[i].Y-this.Y,2)+Math.Pow(ps[i].X-this.X,2));
            }
            //根据距离排序进行高程插值
            ps.Sort((p1,p2)=>p1.D.CompareTo(p2.D));
            double total_h = 0;
            double total_d = 0;
            for (int i = 0; i < 5; i++)//最近的五个点
            {
    
    
                nearpoint.Add(ps[i]);
                total_d += 1.0 / ps[i].D;
                total_h += ps[i].H / ps[i].D;
            }
            this.H = total_h / total_d;
        }
        public InsertPoint()
        {
    
     }
       }
    class CenterPoint
    {
    
    
        public double X, Y;
        public string id;
        public List<InsertPoint> Ps = new List<InsertPoint>();

        public CenterPoint(string id, double Xa, double Ya, double Xb, double Yb)
        {
    
    
            this.id = id;
            X = (Xa + Xb) / 2;
            Y = (Ya + Yb) / 2;
        }
        public CenterPoint()
        {
    
     }
    }

定义变量

DiscretePoint A = new DiscretePoint();
        DiscretePoint B = new DiscretePoint();//测试点A,B
        double H0;//参考面高程
        List<string> Ks_name = new List<string>();//关键点点名
        List<DiscretePoint> Qs = new List<DiscretePoint>();//离散点点集
        List<KeyPoint> Ks = new List<KeyPoint>();//关键点点集
        List<InsertPoint> Ps = new List<InsertPoint>();//插值点集
        List<InsertPoint> KPs = new List<InsertPoint>();//加入关键点的内插点集合,用于计算面积
        List<CenterPoint> Cps = new List<CenterPoint>();//横断面中心点
        List<double> Di = new List<double>();//纵断面各段长度
        Draw draw = new Draw();

数据读取

private void toolStripButton1_Click(object sender, EventArgs e)
        {
    
    
            try
            {
    
    
                OpenFileDialog open = new OpenFileDialog();
                if (open.ShowDialog() == DialogResult.OK)
                {
    
    
                    StreamReader read = new StreamReader(open.FileName);
                    H0 = Convert.ToDouble(read.ReadLine().Split(',')[1]);
                    string[] s1 = read.ReadLine().Split(',');//关键点点名
                    string[] sa = read.ReadLine().Split(',');
                    string[] sb = read.ReadLine().Split(',');//A,B点
                    A.X = double.Parse(sa[1]); A.Y = double.Parse(sa[2]);
                    B.X = double.Parse(sb[1]); B.Y = double.Parse(sb[2]);

                    read.ReadLine();
                    while (!read.EndOfStream)
                    {
    
    
                        string[] sts = read.ReadLine().Split(',');
                        string id = sts[0];
                        double X = double.Parse(sts[1]);
                        double Y = double.Parse(sts[2]);
                        double H = double.Parse(sts[3]);
                        if (Regex.IsMatch(id, @"K\d+"))//关键点
                        {
    
    
                            KeyPoint K = new KeyPoint(id,X,Y,H);
                            Ks.Add(K);
                        }
                        else//离散点
                        {
    
    
                            DiscretePoint Q = new DiscretePoint(id,X,Y,H);
                            Qs.Add(Q);
                        }
                    }

                }

2 道路纵断面计算

2.1计算断面长度
分段计算两关键点间距离
2.2计算内插点坐标

private void insertpoint()
        {
    
    
            double L = 10;
            for (int i = 0; i < Ks.Count-1; i++)//遍历关键点对(K0,K1)(K1,K2)
            {
    
    
                InsertPoint k = new InsertPoint();//起始点,用于面积计算
                k.X = Ks[i].X;
                k.Y = Ks[i].Y;
                k.H = Ks[i].H;
                KPs.Add(k);
                double xita = CalAzimuth(Ks[i + 1].X, Ks[i + 1].Y, Ks[i].X, Ks[i].Y);
                for (int j = 0; j < Di[i] / 10-1; j++)//每一对关键点
                {
    
    
                    InsertPoint p = new InsertPoint(Qs,Ks[i],L,xita);
                    Ps.Add(p);
                    KPs.Add(p);
                    L += 10;
                }
                L -= Di[i];
            }

2.3计算面积

private double calzarea()
        {
    
    
            double area = 0;
            for (int i = 0; i < KPs.Count-1; i++)
            {
    
    
                area += (KPs[i].H+KPs[i+1].H-2*H0) / 2 * 10;
            }
            return area;
        }

3 道路横断面计算

3.1计算断面中心点

private void Calcenter()
        {
    
    
            richTextBox1.Text += "所有中心点坐标:\n";
            for (int i = 0; i < Ks.Count-1; i++)
            {
    
    
                CenterPoint cp = new CenterPoint();
                cp.X = (Ks[i].X+Ks[i+1].X) / 2;
                cp.Y = (Ks[i].Y + Ks[i + 1].Y) / 2;
                Cps.Add(cp);
                richTextBox1.Text += cp.X.ToString("0.000") + "," + cp.Y.ToString("0.000") + ";\n";
            }
            
        }

3.2根据断面中心点进行插值

        private void Insert2()
        {
    
    
            double L = 25;
            double l = 5;
            for (int i = 0; i < Cps.Count; i++)
            {
    
    
                double alpha = CalAzimuth(Ks[i].X, Ks[i].Y, Ks[i+1].X, Ks[i+1].Y) +Math.PI/2;
                KeyPoint k = new KeyPoint();
                k.X = Cps[i].X;k.Y = Cps[i].Y;
                for (int j = 0; j < 2*25/l; j++)
                {
    
    
                    InsertPoint inp = new InsertPoint(Qs, k, -L, alpha);
                    Cps[i].Ps.Add(inp);
                    L += l;
                }
            }
        }

3.3计算横断面面积

private List<double> calharea()
        {
    
    
            richTextBox1.Text += "横断面面积:\n";
            List<double> areas = new List<double>();
            for (int i = 0; i < Cps.Count; i++)
            {
    
    
                double area = 0;
                for (int j = 0; j < Cps[i].Ps.Count-1; j++)
                {
    
    
                    area += (Cps[i].Ps[j+1].H+ Cps[i].Ps[j].H-2*H0) / 2 * 5;
                }
                areas.Add(area);
                richTextBox1.Text += "第"+i+1+"个横断面:"+area.ToString("0.000")+"\n";
            }
            return areas;
        }

猜你喜欢

转载自blog.csdn.net/weixin_51205206/article/details/124747304