public static double SS(sjx san) { double s; s = Math.Abs((san.p2.X - san.p1.X) * (san.p3.Y - san.p1.Y) - (san.p3.X - san.p1.X) * (san.p2.Y - san.p1.Y)) / 2; return(s); }
public static double H(sjx san, double gaocheng) { double h; h = (san.p1.Z + san.p2.Z + san.p3.Z) / 3 - gaocheng; return(h); }
private void tIN生成ToolStripMenuItem_Click(object sender, EventArgs e) { chushihua(); dataGridView1.AllowUserToAddRows = false; #region 数据导入 try { gaocheng = Convert.ToDouble(textBox1.Text.Replace(" ", "")); } catch { MessageBox.Show("请正确输入基准高程!"); return; } try { for (int i = 0; i < dataGridView1.Rows.Count; i++) { Point1 p = new Point1(); p.dianhao = dataGridView1.Rows[i].Cells[0].Value.ToString(); p.X = Convert.ToDouble(dataGridView1.Rows[i].Cells[1].Value.ToString().Replace(" ", "")); p.Y = Convert.ToDouble(dataGridView1.Rows[i].Cells[2].Value.ToString().Replace(" ", "")); p.Z = Convert.ToDouble(dataGridView1.Rows[i].Cells[3].Value.ToString().Replace(" ", "")); point1.Add(p); } } catch { MessageBox.Show("请正确输入散点信息!"); return; } #endregion try { #region 生成初始三角网 xmax = 0; ymax = 0; xmin = 100000000000; ymin = 100000000000; for (int i = 0; i < point1.Count; i++) { 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; } } Point1 p1 = new Point1(); Point1 p2 = new Point1(); Point1 p3 = new Point1(); Point1 p4 = new Point1(); p1.X = xmin - 1; p1.Y = ymin - 1; p2.X = xmin - 1; p2.Y = ymax + 1; p3.X = xmax + 1; p3.Y = ymax + 1; p4.X = xmax + 1; p4.Y = ymin - 1; sjx sjx1 = new sjx();//添加一个三角形必须实例化一个三角形,否则无法赋值 sjx1.p1 = p1; sjx1.p2 = p2; sjx1.p3 = p3; T1.Add(sjx1); sjx sjx2 = new sjx(); sjx2.p1 = p1; sjx2.p2 = p3; sjx2.p3 = p4; T1.Add(sjx2); #endregion #region 生成平面三角网 double x0, y0, r; for (int i = 0; i < point1.Count; i++)//对每个离散点进行遍历 { List <sjx> T2 = new List <sjx>(); S.Clear(); List <int> b = new List <int>(); //记录T1中要剪切的三角形索引 for (int j = 0; j < T1.Count; j++) //步骤2 { x0 = caculate.X0(T1[j].p1.X, T1[j].p1.Y, T1[j].p2.X, T1[j].p2.Y, T1[j].p3.X, T1[j].p3.Y); y0 = caculate.Y0(T1[j].p1.X, T1[j].p1.Y, T1[j].p2.X, T1[j].p2.Y, T1[j].p3.X, T1[j].p3.Y); r = caculate.R(x0, y0, T1[j].p1.X, T1[j].p1.Y); //MessageBox.Show(x0.ToString()); if ((point1[i].X - x0) * (point1[i].X - x0) + (point1[i].Y - y0) * (point1[i].Y - y0) < r * r)//在三角形内部 { Line line1 = new Line(); Line line2 = new Line(); Line line3 = new Line(); line1.Begin = T1[j].p1; line1.End = T1[j].p2; line2.Begin = T1[j].p2; line2.End = T1[j].p3; line3.Begin = T1[j].p3; line3.End = T1[j].p1; S.Add(line1); S.Add(line2); S.Add(line3); //把T2中所有三角形的边信息存储到S边列表中 T2.Add(T1[j]); //T2添加三角形 b.Add(j); } } for (int j = b.Count - 1; j >= 0; j--) //列表数据的结构决定了必须从后往前移除数据 { T1.Remove(T1[b[j]]); //T1移除三角形,实现T1向T2剪切 } //MessageBox.Show(T1.Count.ToString()); //MessageBox.Show(T2.Count.ToString()); //MessageBox.Show(S.Count.ToString()); for (int j = 0; j < S.Count; j++)//步骤4 { for (int k = 0; k < S.Count; k++) { if (j != k) //不同边相互比较 { if (S[j].Begin == S[k].Begin && S[j].End == S[k].End || S[j].Begin == S[k].End && S[j].End == S[k].Begin) //判断两条边是否重合 { S.Remove(S[k]); //j < k S.Remove(S[j]); if (j == 0) //为了减少循环次数 { j = 0; } else { j--; } } } } } //MessageBox.Show(S.Count.ToString()); for (int j = 0; j < S.Count; j++)//步骤5 { sjx sjx3 = new sjx(); sjx3.p1 = point1[i]; sjx3.p2 = S[j].Begin; sjx3.p3 = S[j].End; T1.Add(sjx3); } } #endregion #region 构成不规则三角网 List <int> a = new List <int>();//存储要删除的三角形的索引信息 for (int i = 0; i < T1.Count; i++) { if (T1[i].p1 == p1 || T1[i].p1 == p2 || T1[i].p1 == p3 || T1[i].p1 == p4 || T1[i].p2 == p1 || T1[i].p2 == p2 || T1[i].p2 == p3 || T1[i].p2 == p4 || T1[i].p3 == p1 || T1[i].p3 == p2 || T1[i].p3 == p3 || T1[i].p3 == p4) { a.Add(i); } } for (int j = a.Count - 1; j >= 0; j--) { T1.Remove(T1[a[j]]); } #endregion //MessageBox.Show(T1.Count.ToString()); #region 绘制不规则三角网 image = new Bitmap((int)(ymax - ymin + 20) * 20, (int)(xmax - xmin + 20) * 20);//放大整个绘图区域20倍,为了弥补位图分辨率低的缺点 Graphics g = Graphics.FromImage(image); Pen pen = new Pen(Color.Black, 2f); SolidBrush brush = new SolidBrush(Color.Red); //定义填充 for (int i = 0; i < T1.Count; i++) //对所有三角形进行绘制 { #region 绘制三角形 //PointF[] pp = new PointF[3]; //pp[0].X = (float)(T1[i].p1.Y - (int)ymin + 5) * 20; //pp[0].Y = -(float)(T1[i].p1.X - (int)xmax - 5) * 20; //pp[1].X = (float)(T1[i].p2.Y - (int)ymin + 5) * 20; //pp[1].Y = -(float)(T1[i].p2.X - (int)xmax - 5) * 20; //pp[2].X = (float)(T1[i].p3.Y - (int)ymin + 5) * 20; //pp[2].Y = -(float)(T1[i].p3.X - (int)xmax - 5) * 20; //pp[0].X = (float)(T1[i].p1.Y - (int)ymin + 5) * 20; //pp[0].Y = -(float)(T1[i].p1.X - (int)xmax - 5) * 20; //g.DrawLines(pen, pp); #endregion #region 绘制直线 PointF begion = new PointF(); PointF end = new PointF(); //任意点的X和Y减去最小值归化到原点,再乘以20倍以适应位图大小 for (int j = 0; j < 3; j++) { if (j == 0) //p1-p2 { begion.X = (float)(T1[i].p1.Y - (int)ymin + 10) * 20; //X和Y调换,(数学坐标系转换到测量坐标系) begion.Y = -(float)(T1[i].p1.X - (int)xmax - 10) * 20; //X减去max再变成正数(像素坐标系转换数学坐标系) end.X = (float)(T1[i].p2.Y - (int)ymin + 10) * 20; end.Y = -(float)(T1[i].p2.X - (int)xmax - 10) * 20; } if (j == 1)//p2-p3 { begion.X = (float)(T1[i].p2.Y - (int)ymin + 10) * 20; begion.Y = -(float)(T1[i].p2.X - (int)xmax - 10) * 20; end.X = (float)(T1[i].p3.Y - (int)ymin + 10) * 20; end.Y = -(float)(T1[i].p3.X - (int)xmax - 10) * 20; } if (j == 2)//p3-p1 { begion.X = (float)(T1[i].p3.Y - (int)ymin + 10) * 20; begion.Y = -(float)(T1[i].p3.X - (int)xmax - 10) * 20; end.X = (float)(T1[i].p1.Y - (int)ymin + 10) * 20; end.Y = -(float)(T1[i].p1.X - (int)xmax - 10) * 20; } g.DrawLine(pen, begion, end); g.FillEllipse(brush, begion.X - 10, begion.Y - 10, 20, 20); } #endregion } #region 绘制点 for (int i = 0; i < point1.Count; i++) { g.DrawString(point1[i].dianhao, new Font("宋体", 20), Brushes.Blue, (float)(point1[i].Y - (int)ymin + 10) * 20 + 10f, -(float)(point1[i].X - (int)xmax - 10) * 20 + 10f); } #endregion pictureBox1.Image = image; #endregion } catch (Exception ex) { MessageBox.Show(ex.Message); } }