Esempio n. 1
0
 private void 散点图ToolStripMenuItem_Click(object sender, EventArgs e)
 {
     try
     {
         saveFileDialog1.Title  = "保存dxf文件";
         saveFileDialog1.Filter = "AutoCAD dxf文件(*.dxf)|*.dxf";
         if (saveFileDialog1.ShowDialog() == DialogResult.OK)
         {
             using (StreamWriter sw = new StreamWriter(saveFileDialog1.FileName))
             {
                 sw.Write(TIN.shiqian());   //设置了两个图层
                 sw.Write("0\nSECTION\n");  //第二段开始
                 sw.Write("2\nENTITIES\n"); //实体段开始
                 #region 画三维点
                 for (int i = 0; i < dataGridView1.Rows.Count; i++)
                 {
                     sw.Write("0\nPOINT\n8\nshiti\n");
                     sw.Write("10\n" + point1[i].Y + "\n");
                     sw.Write("20\n" + point1[i].X + "\n");
                     sw.Write("30\n" + point1[i].Z + "\n");
                 }
                 #endregion
                 #region 绘制注记
                 for (int i = 0; i < dataGridView1.Rows.Count; i++)
                 {
                     sw.Write(TIN.zhuji(point1[i].Y, point1[i].X, point1[i].dianhao));
                 }
                 #endregion
                 sw.Write("0\nENDSEC\n"); //第二段结束
                 sw.Write("0\nEOF\n");    //文件结束
             }
             MessageBox.Show("保存成功!");
         }
     }
     catch
     {
         MessageBox.Show("请先生成TIN再绘制dxf!");
         return;
     }
 }
Esempio n. 2
0
        private void 构三角网ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            chushihua();
            toolStripProgressBar1.Value      = 0;//设置进度条的值
            dataGridView1.AllowUserToAddRows = false;
            #region 数据导入
            point1 = new Pointl[dataGridView1.Rows.Count];//实例化一个点数组,用来存储散点数据
            if (dataGridView1.Rows.Count == 0)
            {
                MessageBox.Show("请输入散点数据!");
                return;
            }
            try
            {
                for (int i = 0; i < dataGridView1.Rows.Count; i++)
                {
                    point1[i]         = new Pointl();
                    point1[i].dianhao = dataGridView1.Rows[i].Cells[0].Value.ToString().Replace(" ", "");
                    point1[i].X       = Convert.ToDouble(dataGridView1.Rows[i].Cells[1].Value.ToString().Replace(" ", ""));
                    point1[i].Y       = Convert.ToDouble(dataGridView1.Rows[i].Cells[2].Value.ToString().Replace(" ", ""));
                    point1[i].Z       = Convert.ToDouble(dataGridView1.Rows[i].Cells[3].Value.ToString().Replace(" ", ""));
                }
            }
            catch
            {
                MessageBox.Show("请输入正确的散点数据!");
                return;
            }
            toolStripProgressBar1.Value = 4;//设置进度条的值
            #endregion
            #region 取第一条基线
            double dis, mindis = 10000000000; //存储两点距离和距离的最小值
            int    count = 0;                 //存储最近的点的点号
            double ang;                       //存储余弦角度值,求距离边最近点时用到
            Line   t1 = new Line();           //存储第一条基线
            for (int i = 1; i < dataGridView1.Rows.Count; i++)
            {
                dis = TIN.Distance(point1[0], point1[i]);
                if (mindis > dis)
                {
                    mindis = dis;
                    count  = i;
                }
            }
            t1.Begin = point1[0];
            t1.End   = point1[count];
            linelist.Add(t1);
            //MessageBox.Show(point1[count].X.ToString());
            //toolStripProgressBar1.Value = 8;//设置进度条的值
            #endregion
            #region 存储点线
            for (int i = 0; i < linelist.Count; i++) //对每条边都判断一次
            {
                double minang = -1;                  //最小的余弦角度值
                bool   OK     = false;               //存储是否存在左边点的信息
                Line   line1  = new Line();          //存储三角形中添加的第一条线
                Line   line2  = new Line();          //存储三角形中添加的第二条线

                #region 右边最近点
                for (int j = 0; j < dataGridView1.Rows.Count; j++)
                {
                    int yuobian;
                    yuobian = TIN.ZuoYou(point1[j], ((Line)linelist[i]).Begin, ((Line)linelist[i]).End); //linelist是列表,必须声明(line)以表示其类型,sjxlist同理
                    if (yuobian == 1)                                                                    //右边存在点
                    {
                        ang = TIN.Angle(point1[j], ((Line)linelist[i]).Begin, ((Line)linelist[i]).End);
                        if (ang > minang)//寻找右边最近的点,一定会执行一次
                        {
                            minang = ang;
                            count  = j;//右边最近点的点号
                        }
                        OK = true;
                    }
                }
                #endregion
                #region 构成三角形
                if (OK)//右边存在点
                {
                    #region 将新生成两条边添加入集合中
                    int tt1 = 0;                             //用来存储边是否重合的信息
                    int tt2 = 0;
                    line1.Begin = ((Line)linelist[i]).Begin; //由已知线的起点开始
                    line1.End   = point1[count];             //到最近点结束,作为第一条线
                    line2.Begin = point1[count];             //由最近点开始
                    line2.End   = ((Line)linelist[i]).End;   //到已知线的终点结束,作为第二条线
                    linelist.Add(line1);
                    linelist.Add(line2);

                    sjx sjx1 = new sjx();       //存储三角形的三点坐标信息
                    sjx1.firstp  = line2.Begin; //已知点作为第一个点
                    sjx1.secondp = line2.End;
                    sjx1.thirdp  = line1.Begin;
                    sjxlist.Add(sjx1);
                    #endregion
                    #region 判断三角形是否重合定点
                    for (int j = 0; j < sjxlist.Count - 1; j++) //第一个生成的三角形不用判断
                    {                                           //三个点一共6种排列组合
                        if ((sjx1.firstp == ((sjx)sjxlist[j]).firstp &&
                             sjx1.secondp == ((sjx)sjxlist[j]).secondp &&
                             sjx1.thirdp == ((sjx)sjxlist[j]).thirdp) ||
                            (sjx1.firstp == ((sjx)sjxlist[j]).firstp &&
                             sjx1.secondp == ((sjx)sjxlist[j]).thirdp &&
                             sjx1.thirdp == ((sjx)sjxlist[j]).secondp) ||
                            (sjx1.firstp == ((sjx)sjxlist[j]).secondp &&
                             sjx1.secondp == ((sjx)sjxlist[j]).thirdp &&
                             sjx1.thirdp == ((sjx)sjxlist[j]).firstp) ||
                            (sjx1.firstp == ((sjx)sjxlist[j]).secondp &&
                             sjx1.secondp == ((sjx)sjxlist[j]).firstp &&
                             sjx1.thirdp == ((sjx)sjxlist[j]).thirdp) ||
                            (sjx1.firstp == ((sjx)sjxlist[j]).thirdp &&
                             sjx1.secondp == ((sjx)sjxlist[j]).secondp &&
                             sjx1.thirdp == ((sjx)sjxlist[j]).firstp) ||
                            (sjx1.firstp == ((sjx)sjxlist[j]).thirdp &&
                             sjx1.secondp == ((sjx)sjxlist[j]).firstp &&
                             sjx1.thirdp == ((sjx)sjxlist[j]).secondp))
                        {
                            sjxlist.Remove(sjxlist[sjxlist.Count - 1]);//当前判断的三角形是列表中最后一个三角形
                        }
                    }
                    #endregion
                    #region 判断新生成的两边是否与已生成边重合
                    for (int j = 0; j < linelist.Count - 2; j++)//减去新生成的两条边进行循环
                    {
                        if ((line1.Begin == ((Line)linelist[j]).Begin &&
                             line1.End == ((Line)linelist[j]).End) ||
                            (line1.Begin == ((Line)linelist[j]).End &&
                             line1.End == ((Line)linelist[j]).Begin))  //两种组合方式
                        {
                            tt1 = 1;
                        }
                        if ((line2.Begin == ((Line)linelist[j]).Begin &&
                             line2.End == ((Line)linelist[j]).End) ||
                            (line2.Begin == ((Line)linelist[j]).End &&
                             line2.End == ((Line)linelist[j]).Begin))
                        {
                            tt2 = 1;
                        }
                    }
                    //第一条边重合
                    if (tt1 == 1)
                    {
                        linelist.Remove(linelist[linelist.Count - 2]);//line1先添加,所以-2,但是第一条边重合移去和第二条边重合移去的顺序不能反
                    }
                    //第二条边重合
                    if (tt2 == 1)
                    {
                        linelist.Remove(linelist[linelist.Count - 1]);
                    }
                    #endregion
                }
                #endregion
            }
            toolStripProgressBar1.Value = 16;//设置进度条的值
            #endregion
            #region 绘图
            double xmax = 0, ymax = 0, xmin = 10000000000000, ymin = 100000000000000;
            for (int i = 0; i < dataGridView1.Rows.Count; i++)//找X和Y坐标的最大值
            {
                if (xmax < point1[i].X)
                {
                    xmax = point1[i].X;
                }
                if (ymax < point1[i].Y)
                {
                    ymax = point1[i].Y;
                }
                if (xmin > point1[i].X)
                {
                    xmin = point1[i].X;
                }
                if (ymin > point1[i].Y)
                {
                    ymin = point1[i].Y;
                }
            }
            //MessageBox.Show(xmax.ToString());
            //MessageBox.Show(xmin.ToString());
            //MessageBox.Show(ymax.ToString());
            //MessageBox.Show(ymin.ToString());
            bitmap = new Bitmap((int)(ymax - ymin + 10) * 10, (int)(xmax - xmin + 10) * 10);//放大整个绘图区域10倍,为了弥补位图分辨率低的缺点
            Graphics g   = Graphics.FromImage(bitmap);
            Pen      pen = new Pen(Color.Red, 2f);
            //g.RotateTransform(-90);//旋转为测量坐标系
            //g.TranslateTransform(-(int)(xmax), -(int)ymin);//移动原点坐标以显示图片
            for (int i = 0; i < linelist.Count; i++)
            {
                PointF begion = new PointF();
                PointF end    = new PointF();
                //任意点的X和Y减去最小值归化到原点,再乘以10倍以适应位图大小
                begion.X = ((float)((Line)linelist[i]).Begin.Y - (int)ymin + 5) * 10;  //X和Y调换,(数学坐标系转换到测量坐标系)
                begion.Y = -((float)((Line)linelist[i]).Begin.X - (int)xmax - 5) * 10; //X减去max再变成正数(像素坐标系转换数学坐标系)
                end.X    = ((float)((Line)linelist[i]).End.Y - (int)ymin + 5) * 10;
                end.Y    = -((float)((Line)linelist[i]).End.X - (int)xmax - 5) * 10;
                g.DrawLine(pen, begion, end);
                //MessageBox.Show(begion.X.ToString());
                //MessageBox.Show(begion.Y.ToString());
                //MessageBox.Show(end.X.ToString());
                //MessageBox.Show(end.Y.ToString());
            }
            pictureBox1.Image           = bitmap;
            toolStripProgressBar1.Value = 20;//设置进度条的值
            #endregion
            #region 计算体积
            #region 数据导入
            try                                           //放这里导入是因为就算不输入平场标高也能绘制三角网
            {
                hh = Convert.ToDouble(txt_gaocheng.Text); //平场标高
            }
            catch
            {
                MessageBox.Show("请输入正确的平场标高!");
                return;
            }
            #endregion
            toolStripProgressBar1.Value = 0;
            double   s1, s2, s3, szc, aveH;          //s1,2,3 表示三角形的三条边长,scz 三角形的周长,aveH平均高程
            double[] ss = new double[sjxlist.Count]; //存储表面积
            double[] vv = new double[sjxlist.Count]; //存储体积
            tianfang = 0;
            wafang   = 0;
            #region 平均高程
            pingjunh = 0;//平均高程
            for (int i = 0; i < dataGridView1.Rows.Count; i++)
            {
                pingjunh += point1[i].Z;
            }
            pingjunh         = pingjunh / dataGridView1.Rows.Count;
            txt_pingjun.Text = Math.Round(pingjunh, 3).ToString();
            #endregion
            #region 其他计算
            for (int i = 0; i < sjxlist.Count; i++)
            {
                s1  = TIN.Distance(((sjx)sjxlist[i]).firstp, ((sjx)sjxlist[i]).secondp);
                s2  = TIN.Distance(((sjx)sjxlist[i]).thirdp, ((sjx)sjxlist[i]).secondp);
                s3  = TIN.Distance(((sjx)sjxlist[i]).firstp, ((sjx)sjxlist[i]).thirdp);
                szc = (s1 + s2 + s3) / 2;//用的是海伦公式,计算三角形面积
                //MessageBox.Show(szc.ToString() + i);
                ss[i] = Math.Sqrt(szc * (szc - s1) * (szc - s2) * (szc - s3));
                aveH  = (((sjx)sjxlist[i]).firstp.Z + ((sjx)sjxlist[i]).secondp.Z + ((sjx)sjxlist[i]).thirdp.Z) / 3;
                vv[i] = ss[i] * (aveH - hh);
                if (vv[i] > 0)
                {
                    tianfang = tianfang + vv[i];
                }
                else if (vv[i] < 0)
                {
                    wafang = wafang - vv[i];
                }
            }
            txt_tian.Text    = Math.Round(tianfang, 3).ToString();
            txt_wa.Text      = Math.Round(wafang, 3).ToString();
            txt_bian.Text    = Convert.ToString(linelist.Count); //显示三角形边的个数
            txt_sanjiao.Text = Convert.ToString(sjxlist.Count);  //显示多少个三角形
            #endregion
        }