问一个排序算法

ayun00 2016-03-02 10:20:51
有一个list<Point> 我要从其中一个point 起依次穿过其他point画线 , 怎样排序这些点 ,让画出来的线尽可能的形成一个外多边形 也就是线不要交叉
...全文
853 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
ayun00 2016-03-02
  • 打赏
  • 举报
回复
引用 2 楼 xuzuning 的回复:
设中心点 o { (max.X+min.X)/2, (max.Y+min.Y)/2 } 计算出中心点到各定点的旋转角 按旋转角排序
用 重心算法 也有问题

 var o = new Point { X = list.Sum(xx => xx.X) / list.Count, Y = list.Sum(xx => xx.X) / list.Count };

                    var templist2 = list.OrderBy(x =>
                    {
                        double a = Math.Abs(o.Y - x.Y);
                        double b = Math.Abs(o.X - x.X);
                        double c = Math.Sqrt(a * a + b * b);
                        double s = (b * b + c * c - a * a) / (2 * b * c);
                        double degree = Math.Acos(s);
                        return degree;
                    });

结果

96,104,96,105,96,122,96,123,103,96,119,96,120,96,121,95,120,95,119,97,121,94,118,98,122,93,104,95,118,99,103,95,117,99,123,92,122,92,102,97,124,91,123,91,117,100,116,100,124,90,105,94,125,89,104,94,116,101,115,101,126,88,125,88,127,87,126,87,115,102,127,86,102,98,105,93,128,85,129,84,128,84,114,103,129,83,101,98,106,92,130,82,131,81,130,81,114,104,132,80,107,91,131,80,113,104,132,79,133,78,134,77,106,91,108,90,133,77,134,76,113,105,135,75,107,90,136,74,112,105,135,74,136,73,108,89,137,72,138,71,101,99,137,71,109,88,138,70,112,106,139,69,140,68,110,87,139,68,140,67,111,106,141,66,142,65,141,65,109,87,142,64,143,63,144,62,110,86,143,62,144,61,111,85,111,107,145,60,100,99,112,84,145,59,146,58,147,57,146,57,147,56,110,107,148,55,111,84,148,54,149,53,112,83,113,82,149,52,150,51,114,81,151,50,150,50,151,49,110,108,152,48,152,47,113,81,114,80,152,46,115,79,116,78,152,45,109,108,152,44,152,43,115,78,116,77,117,76,152,42,152,41,100,100,109,109,117,75,118,74,119,73,151,41,151,40,29,165,150,40,120,71,119,72,29,166,30,165,118,73,31,164,32,163,33,162,150,39,29,167,32,164,33,163,34,162,35,161,36,160,37,159,149,39,30,167,122,68,121,69,36,161,120,70,37,160,38,159,39,158,40,157,41,156,31,167,42,155,149,38,40,158,41,157,32,167,42,156,123,66,43,155,44,154,122,67,148,38,45,153,46,152,121,68,47,151,33,167,34,166,148,37,45,154,46,153,47,152,124,64,48,151,35,166,123,65,49,150,50,149,51,148,147,37,52,147,36,166,108,110,37,165,125,62,50,150,147,36,51,149,124,63,52,148,53,147,38,165,54,146,39,164,55,145,56,144,146,36,126,60,57,143,125,61,58,142,40,164,41,163,55,146,56,145,127,58,57,144,126,59,58,143,42,163,59,142,145,35,43,162,60,141,108,111,128,56,61,140,127,57,62,139,44,162,144,35,63,138,129,54,45,161,64,137,128,55,61,141,65,136,62,140,130,52,46,161,63,139,129,53,47,160,64,138,131,50,143,34,65,137,130,51,48,160,66,136,132,48,49,159,131,49,67,135,50,158,142,34,68,134,132,47,107,111,50,159,69,133,51,158,133,45,70,132,52,157,132,46,68,135,71,131,141,33,133,44,69,134,72,130,53,157,70,133,54,156,140,33,133,43,73,129,55,155,71,132,74,128,107,112,72,131,133,42,55,156,139,33,56,155,75,127,73,130,133,41,57,154,74,129,76,126,133,40,75,128,138,32,58,154,77,125,59,153,133,39,76,127,60,152,78,124,137,32,133,38,77,126,60,153,79,123,61,152,106,112,136,32,78,125,132,38,62,151,80,122,63,150,132,37,135,32,79,124,64,149,63,151,81,121,99,101,134,32,131,37,64,150,80,123,106,113,65,149,131,36,82,120,133,32,66,148,81,122,132,33,67,147,83,119,131,34,82,121,67,148,130,35,131,33,68,147,84,118,83,120,69,146,70,145,105,113,85,117,84,119,71,144,70,146,71,145,72,144,85,118,86,116,99,102,105,114,73,143,74,142,86,117,87,115,74,143,75,141,75,142,76,140,87,116,76,141,88,114,104,114,77,140,88,115,104,115,78,139,89,113,79,138,90,111,79,139,80,137,89,114,80,138,81,136,90,112,103,115,81,137,82,135,91,110,82,136,103,116,98,102,83,135,91,111,84,134,92,109,102,116,85,133,85,134,92,110,98,103,102,117,86,132,86,133,87,131,87,132,93,108,101,117,88,130,93,109,88,131,101,118,89,129,89,130,90,128,94,107,100,118,90,129,100,119,94,108,91,127,91,128,97,103,92,126,99,119,92,127,97,104,99,120,93,125,95,106,93,126,95,107,98,120,98,121,94,124,94,125,97,121,97,122,95,123,95,124
qbilbo 2016-03-02
  • 打赏
  • 举报
回复
用2楼的算法。
ayun00 2016-03-02
  • 打赏
  • 举报
回复
我想的算法

 var point = list[0];
                    templist.Add(point.X.ToString());
                    templist.Add(point.Y.ToString());
                    list.RemoveAt(0);
                    while (list.Count > 0)
                    {
                        Point t = list.Find(x => x.X == point.X && x.Y - point.Y == 1);
                        if (t.X != 0 && t.Y != 0)
                        {
                            templist.Add(t.X.ToString());
                            templist.Add(t.Y.ToString());
                            list.Remove(t);
                        }
                        else
                        {
                            Point tt = list.OrderBy(x =>
                            {
                                int width = point.X - x.X;
                                int height = point.Y - x.Y;
                                int result = (width * width) + (height * height);
                                return Math.Sqrt(result);//根号
                            }).ElementAt(0);
                            templist.Add(tt.X.ToString());
                            templist.Add(tt.Y.ToString());
                            list.Remove(tt);
                        }
                    }
下面排序的结果 画线的话 不对

29,165,29,166,30,165,29,167,30,167,31,164,31,167,32,164,32,163,32,167,33,163,33,167,33,162,34,166,34,162,35,166,36,166,35,161,37,165,36,161,36,160,38,165,37,160,37,159,39,164,38,159,40,164,41,163,39,158,40,158,42,163,40,157,43,162,41,157,41,156,44,162,42,156,42,155,45,161,43,155,46,161,44,154,47,160,45,154,48,160,45,153,46,153,49,159,46,152,50,159,50,158,47,152,47,151,51,158,48,151,52,157,49,150,53,157,50,150,50,149,54,156,51,149,55,156,51,148,55,155,52,148,56,155,52,147,53,147,57,154,58,154,54,146,55,146,59,153,55,145,60,153,56,145,60,152,56,144,61,152,57,144,57,143,62,151,58,143,63,151,58,142,63,150,59,142,64,150,64,149,60,141,65,149,61,141,61,140,66,148,62,140,67,148,62,139,67,147,63,139,68,147,63,138,64,138,69,146,64,137,70,146,65,137,70,145,65,136,71,145,71,144,66,136,72,144,67,135,73,143,68,135,68,134,74,143,74,142,69,134,69,133,75,142,75,141,70,133,70,132,76,141,76,140,71,132,71,131,77,140,72,131,72,130,78,139,73,130,79,139,79,138,73,129,74,129,80,138,80,137,74,128,75,128,81,137,81,136,75,127,82,136,76,127,82,135,76,126,83,135,77,126,77,125,84,134,78,125,78,124,85,134,85,133,79,124,79,123,86,133,86,132,80,123,80,122,87,132,87,131,81,122,88,131,81,121,88,130,82,121,89,130,82,120,89,129,83,120,90,129,83,119,90,128,84,119,91,128,84,118,91,127,85,118,92,127,85,117,92,126,86,117,93,126,86,116,93,125,87,116,94,125,87,115,94,124,88,115,95,124,88,114,95,123,89,114,96,123,89,113,96,122,97,122,90,112,97,121,90,111,98,121,91,111,98,120,91,110,99,120,92,110,99,119,92,109,100,119,93,109,100,118,93,108,101,118,94,108,101,117,94,107,102,117,95,107,102,116,95,106,103,116,103,115,96,105,104,115,96,104,104,114,97,104,105,114,97,103,105,113,98,103,106,113,98,102,106,112,99,102,107,112,99,101,107,111,108,111,100,100,108,110,100,99,109,109,101,99,109,108,101,98,110,108,102,98,110,107,102,97,111,107,111,106,103,96,112,106,103,95,112,105,104,95,113,105,104,94,113,104,105,94,114,104,105,93,114,103,106,92,115,102,106,91,115,101,107,91,116,101,107,90,116,100,108,90,117,100,108,89,117,99,118,99,109,88,118,98,109,87,110,87,119,97,110,86,119,96,120,96,111,85,120,95,111,84,121,95,112,84,121,94,112,83,122,93,113,82,122,92,113,81,123,92,114,81,123,91,114,80,124,91,124,90,115,79,115,78,125,89,116,78,125,88,116,77,126,88,126,87,117,76,127,87,117,75,127,86,128,85,118,74,128,84,118,73,129,84,119,73,129,83,119,72,130,82,120,71,130,81,120,70,131,81,131,80,121,69,132,80,121,68,132,79,122,68,122,67,133,78,133,77,123,66,134,77,123,65,134,76,124,64,135,75,124,63,135,74,136,74,125,62,136,73,125,61,137,72,126,60,137,71,126,59,138,71,138,70,127,58,127,57,139,69,139,68,128,56,140,68,128,55,140,67,129,54,141,66,129,53,141,65,142,65,130,52,142,64,130,51,143,63,143,62,131,50,144,62,131,49,144,61,132,48,145,60,132,47,145,59,132,46,146,58,133,45,146,57,133,44,147,57,133,43,147,56,133,42,133,41,148,55,133,40,148,54,133,39,132,38,131,37,149,53,133,38,132,37,131,36,130,35,149,52,131,34,150,51,131,33,150,50,132,33,151,50,151,49,133,32,134,32,152,48,135,32,152,47,136,32,152,46,137,32,139,33,152,45,138,32,140,33,152,44,142,34,141,33,152,43,144,35,143,34,152,42,151,41,150,40,149,39,148,38,147,37,146,36,145,35,152,41,151,40,150,39,149,38,148,37,147,36
  • 打赏
  • 举报
回复
选取一个点为起点,然后循环其他点,跟当前这个点最近的就是要链接的下一个点,然后以找到的点为起点,继续找下一个点,这不是最短路径算法吗
ayun00 2016-03-02
  • 打赏
  • 举报
回复
引用 2 楼 xuzuning 的回复:
设中心点 o { (max.X+min.X)/2, (max.Y+min.Y)/2 } 计算出中心点到各定点的旋转角 按旋转角排序

   List<Point> list
                    Point max = list.Max();
                    Point min = list.Min();
                    var o = new Point { X = (max.X + min.X) / 2, Y = (max.Y + min.Y) / 2 };
xuzuning 2016-03-02
  • 打赏
  • 举报
回复
设中心点 o { (max.X+min.X)/2, (max.Y+min.Y)/2 } 计算出中心点到各定点的旋转角 按旋转角排序
bdmh 2016-03-02
  • 打赏
  • 举报
回复
你指定一个规则就行了,是按照x坐标还是y坐标排序,还是先按x,再按y,然后自己写一个自定义排序方法,给list用就行了
万物一半可抛 2016-03-02
  • 打赏
  • 举报
回复
...........1楼的方法很正确啊,先按x再按y排序。。。然后从头到尾连起来?
ayun00 2016-03-02
  • 打赏
  • 举报
回复
引用 17 楼 xuzuning 的回复:
是不行的! 通过旋转角排序的前提是:图形应是凸多边形
恩 现在用最短距离法 ,基本能用了 可惜的是 如果能进一步 把坐标点封闭轮廓分组就好了
ayun00 2016-03-02
  • 打赏
  • 举报
回复
引用 15 楼 qbilbo 的回复:
[quote=引用 12 楼 ayun00 的回复:] [quote=引用 8 楼 qbilbo 的回复:]
public partial class Form1 : Form
    {
        List<Point> points = new List<Point>();

        public Form1()
        {
            InitializeComponent();

            Random rand = new Random ();
            for (int i = 0; i < 10; i++)
            {
                points.Add(new Point(rand.Next(300), rand.Next(300)));
            }

            this.Paint += (s, e) =>
            {
                Point[] ps = GetPorints();
                e.Graphics.DrawPolygon(new Pen(Color.Blue), ps);
                Font font = new Font ("宋体",9F);
                Brush brush = Brushes.Red;
                for (int i = 0; i < ps.Length; i++)
                {
                    e.Graphics.DrawString((i + 1).ToString(), font, brush, ps[i]);
                }
            };
        }

        private Point[] GetPorints()
        {
            //计算中心坐标
            int x1 = points.Min(x => x.X);
            int x2 = points.Max(x => x.X);
            int y1 = points.Min(x => x.Y);
            int y2 = points.Max(x => x.Y);
            Point point = new Point((x2 - x1) / 2, (y2 - y1) / 2);

            //计算各点相对于中心点的角度
            var lst = from p in points select new { X = p.X, Y = p.Y, Angle = Math.Atan2((point.Y - p.Y), (p.X - point.X)) };
            //按角度排序输出
            return (from p in lst orderby p.Angle select new Point(p.X, p.Y)).ToArray();
        }
    }
使用这个算法的结果 [/quote] Point point = new Point((x2 - x1) / 2, (y2 - y1) / 2); 换成: Point point = new Point(x1 + (x2 - x1) / 2, y1 + (y2 - y1) / 2); 试试[/quote] 换过试了 , 结果差不多
xuzuning 2016-03-02
  • 打赏
  • 举报
回复
是不行的! 通过旋转角排序的前提是:图形应是凸多边形
ayun00 2016-03-02
  • 打赏
  • 举报
回复
引用 5 楼 ayun00 的回复:
我想的算法

 var point = list[0];
                    templist.Add(point.X.ToString());
                    templist.Add(point.Y.ToString());
                    list.RemoveAt(0);
                    while (list.Count > 0)
                    {
                        Point t = list.Find(x => x.X == point.X && x.Y - point.Y == 1);
                        if (t.X != 0 && t.Y != 0)
                        {
                            templist.Add(t.X.ToString());
                            templist.Add(t.Y.ToString());
                            list.Remove(t);
                        }
                        else
                        {
                            Point tt = list.OrderBy(x =>
                            {
                                int width = point.X - x.X;
                                int height = point.Y - x.Y;
                                int result = (width * width) + (height * height);
                                return Math.Sqrt(result);//根号
                            }).ElementAt(0);
                            templist.Add(tt.X.ToString());
                            templist.Add(tt.Y.ToString());
                            list.Remove(tt);
                        }
                    }
下面排序的结果 画线的话 不对

29,165,29,166,30,165,29,167,30,167,31,164,31,167,32,164,32,163,32,167,33,163,33,167,33,162,34,166,34,162,35,166,36,166,35,161,37,165,36,161,36,160,38,165,37,160,37,159,39,164,38,159,40,164,41,163,39,158,40,158,42,163,40,157,43,162,41,157,41,156,44,162,42,156,42,155,45,161,43,155,46,161,44,154,47,160,45,154,48,160,45,153,46,153,49,159,46,152,50,159,50,158,47,152,47,151,51,158,48,151,52,157,49,150,53,157,50,150,50,149,54,156,51,149,55,156,51,148,55,155,52,148,56,155,52,147,53,147,57,154,58,154,54,146,55,146,59,153,55,145,60,153,56,145,60,152,56,144,61,152,57,144,57,143,62,151,58,143,63,151,58,142,63,150,59,142,64,150,64,149,60,141,65,149,61,141,61,140,66,148,62,140,67,148,62,139,67,147,63,139,68,147,63,138,64,138,69,146,64,137,70,146,65,137,70,145,65,136,71,145,71,144,66,136,72,144,67,135,73,143,68,135,68,134,74,143,74,142,69,134,69,133,75,142,75,141,70,133,70,132,76,141,76,140,71,132,71,131,77,140,72,131,72,130,78,139,73,130,79,139,79,138,73,129,74,129,80,138,80,137,74,128,75,128,81,137,81,136,75,127,82,136,76,127,82,135,76,126,83,135,77,126,77,125,84,134,78,125,78,124,85,134,85,133,79,124,79,123,86,133,86,132,80,123,80,122,87,132,87,131,81,122,88,131,81,121,88,130,82,121,89,130,82,120,89,129,83,120,90,129,83,119,90,128,84,119,91,128,84,118,91,127,85,118,92,127,85,117,92,126,86,117,93,126,86,116,93,125,87,116,94,125,87,115,94,124,88,115,95,124,88,114,95,123,89,114,96,123,89,113,96,122,97,122,90,112,97,121,90,111,98,121,91,111,98,120,91,110,99,120,92,110,99,119,92,109,100,119,93,109,100,118,93,108,101,118,94,108,101,117,94,107,102,117,95,107,102,116,95,106,103,116,103,115,96,105,104,115,96,104,104,114,97,104,105,114,97,103,105,113,98,103,106,113,98,102,106,112,99,102,107,112,99,101,107,111,108,111,100,100,108,110,100,99,109,109,101,99,109,108,101,98,110,108,102,98,110,107,102,97,111,107,111,106,103,96,112,106,103,95,112,105,104,95,113,105,104,94,113,104,105,94,114,104,105,93,114,103,106,92,115,102,106,91,115,101,107,91,116,101,107,90,116,100,108,90,117,100,108,89,117,99,118,99,109,88,118,98,109,87,110,87,119,97,110,86,119,96,120,96,111,85,120,95,111,84,121,95,112,84,121,94,112,83,122,93,113,82,122,92,113,81,123,92,114,81,123,91,114,80,124,91,124,90,115,79,115,78,125,89,116,78,125,88,116,77,126,88,126,87,117,76,127,87,117,75,127,86,128,85,118,74,128,84,118,73,129,84,119,73,129,83,119,72,130,82,120,71,130,81,120,70,131,81,131,80,121,69,132,80,121,68,132,79,122,68,122,67,133,78,133,77,123,66,134,77,123,65,134,76,124,64,135,75,124,63,135,74,136,74,125,62,136,73,125,61,137,72,126,60,137,71,126,59,138,71,138,70,127,58,127,57,139,69,139,68,128,56,140,68,128,55,140,67,129,54,141,66,129,53,141,65,142,65,130,52,142,64,130,51,143,63,143,62,131,50,144,62,131,49,144,61,132,48,145,60,132,47,145,59,132,46,146,58,133,45,146,57,133,44,147,57,133,43,147,56,133,42,133,41,148,55,133,40,148,54,133,39,132,38,131,37,149,53,133,38,132,37,131,36,130,35,149,52,131,34,150,51,131,33,150,50,132,33,151,50,151,49,133,32,134,32,152,48,135,32,152,47,136,32,152,46,137,32,139,33,152,45,138,32,140,33,152,44,142,34,141,33,152,43,144,35,143,34,152,42,151,41,150,40,149,39,148,38,147,37,146,36,145,35,152,41,151,40,150,39,149,38,148,37,147,36
最短距离算法对了, 我开始的程序有bug
qbilbo 2016-03-02
  • 打赏
  • 举报
回复
引用 12 楼 ayun00 的回复:
[quote=引用 8 楼 qbilbo 的回复:]
public partial class Form1 : Form
    {
        List<Point> points = new List<Point>();

        public Form1()
        {
            InitializeComponent();

            Random rand = new Random ();
            for (int i = 0; i < 10; i++)
            {
                points.Add(new Point(rand.Next(300), rand.Next(300)));
            }

            this.Paint += (s, e) =>
            {
                Point[] ps = GetPorints();
                e.Graphics.DrawPolygon(new Pen(Color.Blue), ps);
                Font font = new Font ("宋体",9F);
                Brush brush = Brushes.Red;
                for (int i = 0; i < ps.Length; i++)
                {
                    e.Graphics.DrawString((i + 1).ToString(), font, brush, ps[i]);
                }
            };
        }

        private Point[] GetPorints()
        {
            //计算中心坐标
            int x1 = points.Min(x => x.X);
            int x2 = points.Max(x => x.X);
            int y1 = points.Min(x => x.Y);
            int y2 = points.Max(x => x.Y);
            Point point = new Point((x2 - x1) / 2, (y2 - y1) / 2);

            //计算各点相对于中心点的角度
            var lst = from p in points select new { X = p.X, Y = p.Y, Angle = Math.Atan2((point.Y - p.Y), (p.X - point.X)) };
            //按角度排序输出
            return (from p in lst orderby p.Angle select new Point(p.X, p.Y)).ToArray();
        }
    }
使用这个算法的结果 [/quote] Point point = new Point((x2 - x1) / 2, (y2 - y1) / 2); 换成: Point point = new Point(x1 + (x2 - x1) / 2, y1 + (y2 - y1) / 2); 试试
ayun00 2016-03-02
  • 打赏
  • 举报
回复
引用 11 楼 qbilbo 的回复:
中心坐标换不太正确。 int x1 = points.Min(x => x.X); int x2 = points.Max(x => x.X); int y1 = points.Min(x => x.Y); int y2 = points.Max(x => x.Y); Point point = new Point(x1 + (x2 - x1) / 2, y1 + (y2 - y1) / 2); 这样应该就行。
试了 还是不行
xuzuning 2016-03-02
  • 打赏
  • 举报
回复
噢,我还以为你是直接读取 楷体 字库的呢 观察了你的数据,虽然你示例的数据是 一撇 丿 但绘图是从左下往右上的 如果直接描点的话,可以发现是沿轮廓线,两路同时进行的
ayun00 2016-03-02
  • 打赏
  • 举报
回复
引用 8 楼 qbilbo 的回复:
public partial class Form1 : Form
{
List<Point> points = new List<Point>();

public Form1()
{
InitializeComponent();

Random rand = new Random ();
for (int i = 0; i < 10; i++)
{
points.Add(new Point(rand.Next(300), rand.Next(300)));
}

this.Paint += (s, e) =>
{
Point[] ps = GetPorints();
e.Graphics.DrawPolygon(new Pen(Color.Blue), ps);
Font font = new Font ("宋体",9F);
Brush brush = Brushes.Red;
for (int i = 0; i < ps.Length; i++)
{
e.Graphics.DrawString((i + 1).ToString(), font, brush, ps[i]);
}
};
}

private Point[] GetPorints()
{
//计算中心坐标
int x1 = points.Min(x => x.X);
int x2 = points.Max(x => x.X);
int y1 = points.Min(x => x.Y);
int y2 = points.Max(x => x.Y);
Point point = new Point((x2 - x1) / 2, (y2 - y1) / 2);

//计算各点相对于中心点的角度
var lst = from p in points select new { X = p.X, Y = p.Y, Angle = Math.Atan2((point.Y - p.Y), (p.X - point.X)) };
//按角度排序输出
return (from p in lst orderby p.Angle select new Point(p.X, p.Y)).ToArray();
}
}

使用这个算法的结果


qbilbo 2016-03-02
  • 打赏
  • 举报
回复
中心坐标换不太正确。 int x1 = points.Min(x => x.X); int x2 = points.Max(x => x.X); int y1 = points.Min(x => x.Y); int y2 = points.Max(x => x.Y); Point point = new Point(x1 + (x2 - x1) / 2, y1 + (y2 - y1) / 2); 这样应该就行。
ayun00 2016-03-02
  • 打赏
  • 举报
回复
引用 9 楼 xuzuning 的回复:
测试了一下,我的方法不能适应你的图形 请教一下,你的这个笔画数据是怎么得到的?谢谢!
用 opencv 读出轮廓, 然后一个点一个点的读出来的, 我找了很多资料 找不到直接获取轮廓线坐标的方法 ,只好自己来算了
xuzuning 2016-03-02
  • 打赏
  • 举报
回复
测试了一下,我的方法不能适应你的图形 请教一下,你的这个笔画数据是怎么得到的?谢谢!
qbilbo 2016-03-02
  • 打赏
  • 举报
回复
public partial class Form1 : Form
    {
        List<Point> points = new List<Point>();

        public Form1()
        {
            InitializeComponent();

            Random rand = new Random ();
            for (int i = 0; i < 10; i++)
            {
                points.Add(new Point(rand.Next(300), rand.Next(300)));
            }

            this.Paint += (s, e) =>
            {
                Point[] ps = GetPorints();
                e.Graphics.DrawPolygon(new Pen(Color.Blue), ps);
                Font font = new Font ("宋体",9F);
                Brush brush = Brushes.Red;
                for (int i = 0; i < ps.Length; i++)
                {
                    e.Graphics.DrawString((i + 1).ToString(), font, brush, ps[i]);
                }
            };
        }

        private Point[] GetPorints()
        {
            //计算中心坐标
            int x1 = points.Min(x => x.X);
            int x2 = points.Max(x => x.X);
            int y1 = points.Min(x => x.Y);
            int y2 = points.Max(x => x.Y);
            Point point = new Point((x2 - x1) / 2, (y2 - y1) / 2);

            //计算各点相对于中心点的角度
            var lst = from p in points select new { X = p.X, Y = p.Y, Angle = Math.Atan2((point.Y - p.Y), (p.X - point.X)) };
            //按角度排序输出
            return (from p in lst orderby p.Angle select new Point(p.X, p.Y)).ToArray();
        }
    }

111,129

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Creator Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧