int judge_left(given_point p1, given_point p2, given_point p3) //判断点是否在线的左边 { if (p1.X * p2.Y - p2.X * p1.Y + p3.X * (p1.Y - p2.Y) + p3.Y * (p2.X - p1.X) > 0) { return(1); } return(-1); }
int judge(grid_point a, given_point b, given_point c) //判断点a是否在b—c线的左边 { double m = (c.X - b.X) / (c.Y - b.Y) * (a.y - b.Y) + b.X; if (m > a.x) { return(1); } return(0); }
private void openfile_Click(object sender, EventArgs e) //打开读取数据文件 { try // 进行错误处理 { if (datatable.Rows.Count != 1) { datatable.Rows.Clear(); g_point.Clear(); convex_hull.Clear(); report.Clear(); } //如果当前数据表格中有数据,在 //这次导入数据前清空表格。 OpenFileDialog opf = new OpenFileDialog(); //创建文件对话框 opf.Filter = "文本文件(*.txt)|*.txt"; if (opf.ShowDialog() == DialogResult.OK) { string rpath = opf.FileName; //获得文件地址 StreamReader sr = new StreamReader(rpath); //打开文件 int g_point_num = 0; //记录有多少已知点位 given_point gp = new given_point(); // 临时存放点位信息 while (!sr.EndOfStream) { string[] line = sr.ReadLine().Trim().Split(',', ','); //读取文件,并分割到字符串数组中 if (line.Length == 2) //获得基准高程 { height_datum = float.Parse(line[1]); } else if (line.Length == 4) //获得已知点信息 { gp.point_name = line[0]; gp.X = float.Parse(line[1]); gp.Y = float.Parse(line[2]); gp.H = float.Parse(line[3]); g_point.Add(gp); //把已知点放到列表中 datatable.Rows.Add(); //增加数据表格的列,并显示点位信息 datatable.Rows[g_point_num].Cells[0].Value = g_point[g_point_num].point_name; datatable.Rows[g_point_num].Cells[1].Value = g_point[g_point_num].X; datatable.Rows[g_point_num].Cells[2].Value = g_point[g_point_num].Y; datatable.Rows[g_point_num].Cells[3].Value = g_point[g_point_num].H; g_point_num++; } } 基准高程.Text = height_datum.ToString(); 网格间隔.Text = grid_spacing.ToString(); status.Text = "导入数据"; } } catch { MessageBox.Show("输入文件有误,无法正确读取!"); } datatable.BringToFront(); }
public List <given_point> get_convex_hull() { po_pn_sort(); Stack <point> c_h_point = new Stack <point>(); //建立栈 c_h_point.Push(p0); c_h_point.Push(g_point[0]); c_h_point.Push(g_point[1]); int n = g_point.Count(); for (int i = 2; i < n; i++) { point top = c_h_point.Pop(); point sec_top = c_h_point.Peek(); c_h_point.Push(top); if (judge_l_r(sec_top, top, g_point[i]) < 0) { c_h_point.Push(g_point[i]); } else { while (judge_l_r(sec_top, top, g_point[i]) > 0) { c_h_point.Pop(); top = top = c_h_point.Pop(); sec_top = c_h_point.Peek(); c_h_point.Push(top); } c_h_point.Push(g_point[i]); } } c_h_point.Push(p0); point[] c_h = c_h_point.ToArray(); List <given_point> return_point = new List <given_point>(); for (int i = c_h.Count() - 1; i >= 0; i--) { given_point point = new given_point(); point = c_h[i].p; return_point.Add(point); } return(return_point); }
void fun(List <given_point> left_point, given_point head, given_point tail) //迭代函数 { int arcmax_sub = -1; //我们用三角形面积判断点的距离 ,得到最远点的序号,如果直线(头—尾)左边无点集,则把 尾 放入凸包点集中 double arcmax = 0; for (int i = 0; i < left_point.Count; i++) { if (arc(head, tail, left_point[i]) > arcmax) { arcmax = arc(head, tail, left_point[i]); arcmax_sub = i; } } if (arcmax_sub == -1) { conver_h.Add(tail); } else { given_point mid = left_point[arcmax_sub]; left_point.Remove(mid); List <given_point> left_point1 = new List <given_point>(); //得到在直线(头—最远点)左边的点集 for (int j = 0; j < left_point.Count; j++) { if (judge_left(head, mid, left_point[j]) == 1) { left_point1.Add(left_point[j]); } } fun(left_point1, head, mid); List <given_point> left_point2 = new List <given_point>(); //得到在直线(最远点—尾)左边的点集 for (int j = 0; j < left_point.Count; j++) { if (judge_left(mid, tail, left_point[j]) == 1) { left_point2.Add(left_point[j]); } } fun(left_point2, mid, tail); } }
private void get_V_Click(object sender, EventArgs e) //得到体积,并输出报告 { if (g_point.Count == 0) { status.Text = "没有数据,无法计算"; return; } if (convex_hull.Count == 0) { this.生成凸包_Click(this, e); } given_point p0 = convex_hull[0]; //得到p0点 report.Text = ""; //计算体积信息 height_datum = float.Parse(基准高程.Text); //获得最新的基准高程和网格间隔信息 grid_spacing = float.Parse(网格间隔.Text); diff_grid_size_report(1); //不同的网格间隔大小输出不同的报告 diff_grid_size_report(5); diff_grid_size_report(10); //输出报告: report.Text = report.Text + "\r\n报告基点是:\r\n"; report.Text = report.Text + "点号 X坐标 Y坐标 H高程\r\n"; report.Text = report.Text + p0.point_name.PadRight(14) + p0.X.ToString().PadRight(14) + p0.Y.ToString().PadRight(14) + p0.H.ToString().PadRight(15) + "\r\n"; report.Text = report.Text + "--------------------------凸包点----------------------\r\n"; report.Text = report.Text + "点号 X坐标 Y坐标 H高程\r\n"; for (int i = 0; i < convex_hull.Count(); i++) { report.Text = report.Text + convex_hull[i].point_name.PadRight(14) + convex_hull[i].X.ToString().PadRight(14) + convex_hull[i].Y.ToString().PadRight(15) + convex_hull[i].H.ToString().PadRight(15) + "\r\n"; } report.BringToFront(); status.Text = "生成报告"; }
double arc(given_point p1, given_point p2, given_point p3) //三点得到面积 { return(Math.Abs((1.0 / 2) * (p1.X * (p2.Y - p3.Y) + p2.X * (p3.Y - p1.Y) + p3.X * (p1.Y - p2.Y)))); }