//求散点子集的凸包 private IPositionSet solveHelp(IPosition p1, IPosition p2, IPositionSet ps) { //求离p1,p2最远的点 ps.InitToTraverseSet(); if (!ps.NextPosition()) { return(ps); } IPosition p3 = ps.GetPosition(); double p3_h = getH(p1, p2, p3); PositionSetEdit_ImplementByICollectionTemplate rest = new PositionSetEdit_ImplementByICollectionTemplate(); while (ps.NextPosition()) { IPosition pt = ps.GetPosition(); double pt_h = getH(p1, p2, pt); if (pt_h > p3_h) { rest.AddPosition(p3); p3 = pt; p3_h = pt_h; } else { rest.AddPosition(pt); } } //把散点分成几部分 PositionSetEdit_ImplementByICollectionTemplate leftpart = new PositionSetEdit_ImplementByICollectionTemplate(); PositionSetEdit_ImplementByICollectionTemplate rightpart = new PositionSetEdit_ImplementByICollectionTemplate(); PositionSetEdit_ImplementByICollectionTemplate p1set = new PositionSetEdit_ImplementByICollectionTemplate(); PositionSetEdit_ImplementByICollectionTemplate p2set = new PositionSetEdit_ImplementByICollectionTemplate(); ps = rest; IPosition p11 = new Position_Point(2 * p2.GetX() - p1.GetX(), 2 * p2.GetY() - p1.GetY()); //p1关于p2的对称点 double leftangle = getAngle(p1, p2, p3); double rightangle = getAngle(p2, p11, p3); ps.InitToTraverseSet(); while (ps.NextPosition()) { IPosition p = ps.GetPosition(); if (p.GetX() == p1.GetX() && p.GetY() == p1.GetY()) { p1set.AddPosition(p); } else if (p.GetX() == p2.GetX() && p.GetY() == p2.GetY()) { p2set.AddPosition(p); } else if (p.GetX() == p3.GetX() && p.GetY() == p3.GetY()) { leftpart.AddPosition(p); } else { double a = getAngle(p1, p2, p); if (a > leftangle) { leftpart.AddPosition(p); } a = getAngle(p2, p11, p); if (a < rightangle) { rightpart.AddPosition(p); } } } //对子集求解 IPositionSet subResult1 = solveHelp(p1, p3, leftpart); IPositionSet subResult2 = solveHelp(p3, p2, rightpart); //合并各部分解 PositionSetEdit_ImplementByICollectionTemplate result = new PositionSetEdit_ImplementByICollectionTemplate(); p1set.InitToTraverseSet(); while (p1set.NextPosition()) { result.AddPosition(p1set.GetPosition()); } subResult1.InitToTraverseSet(); while (subResult1.NextPosition()) { result.AddPosition(subResult1.GetPosition()); } result.AddPosition(p3); subResult2.InitToTraverseSet(); while (subResult2.NextPosition()) { result.AddPosition(subResult2.GetPosition()); } p2set.InitToTraverseSet(); while (p2set.NextPosition()) { result.AddPosition(p2set.GetPosition()); } return(result); }
private void button1_Click(object sender, EventArgs e) { IConvexHullEngine convexhull; int n; switch (comboBox1.SelectedIndex) { case 0: convexhull = new GrahamScan(); break; case 1: //convexhull = new QuickHull(); convexhull = new M2M_CH(); break; default: return; } try { n = Int32.Parse(textBox1.Text); } catch (Exception) { return; } //Point[] ps = new Point[n]; PositionSetEdit_ImplementByICollectionTemplate ps = new PositionSetEdit_ImplementByICollectionTemplate(); Random r = new Random(DateTime.Now.Millisecond); //if (true) { int minx = (int)(pb.Width * 0.05); int miny = (int)(pb.Height * 0.05); for (int i = 0; i < n; i++) { int x = r.Next(minx, pb.Width - minx); int y = r.Next(miny, pb.Height - miny); //ps[i] = new Point(x, y); ps.AddPosition(new Position_Point(x, y)); System.Console.Write(x); System.Console.Write(","); System.Console.Write(y); System.Console.WriteLine(","); } System.Console.WriteLine(); } //else //{ // ps = testData(); //} IPositionSet convexPoints = convexhull.ConvexHull(ps); pb.Image = new Bitmap(pb.Width, pb.Height); Graphics g = Graphics.FromImage(pb.Image); convexPoints.InitToTraverseSet(); g.Clear(Color.White); /* * for (int i = 0; i < ps.Length; i++) * { * g.FillEllipse(Brushes.Black, ps[i].X - 2, pb.Height - ps[i].Y - 2, 4, 4); * g.DrawString("(" + ps[i].X + "," + ps[i].Y + ")", Font, Brushes.Blue, ps[i].X, pb.Height - ps[i].Y); * } * for (int i = 0; i < convexPoints.Length; i++) * { * if (i != convexPoints.Length - 1) * g.DrawLine(new Pen(Color.Green), new PointF(convexPoints[i].X, pb.Height - convexPoints[i].Y), new PointF(convexPoints[i + 1].X, pb.Height - convexPoints[i + 1].Y)); * else * { * g.DrawLine(new Pen(Color.Green), new PointF(convexPoints[i].X, pb.Height - convexPoints[i].Y), new PointF(convexPoints[0].X, pb.Height - convexPoints[0].Y)); * } * } * */ ps.InitToTraverseSet(); IPosition p = ps.GetPosition(); while (p != null) { g.FillEllipse(Brushes.Black, p.GetX() - 2, pb.Height - p.GetY() - 2, 4, 4); g.DrawString("(" + p.GetX() + "," + p.GetY() + ")", Font, Brushes.Blue, p.GetX(), pb.Height - p.GetY()); p = ps.GetPosition(); } IPosition p1 = convexPoints.GetPosition(); IPosition p2 = convexPoints.GetPosition(); while (p2 != null) { g.DrawLine(new Pen(Color.Green), new PointF(p1.GetX(), pb.Height - p1.GetY()), new PointF(p2.GetX(), pb.Height - p2.GetY())); p1 = p2; p2 = convexPoints.GetPosition(); } convexPoints.InitToTraverseSet(); p2 = convexPoints.GetPosition(); g.DrawLine(new Pen(Color.Green), new PointF(p1.GetX(), pb.Height - p1.GetY()), new PointF(p2.GetX(), pb.Height - p2.GetY())); }