亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

凸包的c#實現算法

發布時間:2020-05-02 07:22:50 來源:網絡 閱讀:5045 作者:張吉踉 欄目:編程語言
 
            前段時間看到生成凸包的Graham算法,查了一些資料,沒看到c#版的,于是想動手寫一個,該程序草草完成,其中有值得優化的地方,諸位可自行改正。
             Graham算法的原理:
    (1)給定一個點集P={P0,P1,.....Pn),找出點集中Y值最小的點,如果Y值最小的點有多個,可選擇其中X值最小的
    (2)假設上一步找出的點位P0,現在對剩下的點進行極角排序,按逆時針(本程序是這樣,其他的方式是一樣的)極角從小到大排序,假定排序結果集為{p1,p2,p3,p4,....pn}。注意,這里不一定有N個點,因為可能存在幾個點的極角相同,這時取據P0距最遠的點,也或者你設定了一個極角閾值,當兩個點的極角差小于該閾值時,取據P0距離遠的點,這時生成的凸包有一點點誤差,誤差的大小取決于你設置的閾值。本程序沒采用閾值,所以生成的凸包理論上不存在誤差。
      在進行極角排序時,不需要真的算法每個點的極角(注意,這里的極角是該點與P0相對于X軸的夾角),只需要使用向量叉積來判斷即可,這個過程我使用了鏈表來存儲排序結果,因為這個過程會進行頻繁的插入。
   (3)將p0,p1,p3入棧,p0,p1這兩個點肯定在凸包上(原因很簡單,p0不用解釋了吧,p1因為它是極角最小的且為第一個點),p2則不一定在凸包上,然后進行循環(for(int i=2;i<n;i++),判定棧頂的下一個點,棧頂點,及p[i]點這三點組成的折線段是否向左轉,如果是的話,則p[i]入棧;否則,當前位于棧頂的點不在凸包上,彈棧(該過程進行回朔,確保之前的所有點轉向正確,這個步驟很重要,不然不能生成凸多邊形),最后返回棧即可。
  下面是整個代碼:
     算法部分:
   
凸包的c#實現算法class ConvexAogrithm
凸包的c#實現算法        {
凸包的c#實現算法                private List<PointF> nodes;
凸包的c#實現算法                private Stack<PointF> sortedNodes;
凸包的c#實現算法                public PointF[] sor_nodes;
凸包的c#實現算法                public ConvexAogrithm(List<PointF> points)
凸包的c#實現算法                {
凸包的c#實現算法                        nodes = points;
凸包的c#實現算法                }
凸包的c#實現算法                private double DistanceOfNodes(PointF p0, PointF p1)
凸包的c#實現算法                {
凸包的c#實現算法                        if (p0.IsEmpty || p1.IsEmpty)
凸包的c#實現算法                                return 0.0;
凸包的c#實現算法                        return Math.Sqrt((p1.X - p0.X) * (p1.X - p0.X) + (p1.Y - p0.Y) * (p1.Y - p0.Y));
凸包的c#實現算法                }
凸包的c#實現算法                public void GetNodesByAngle( out PointF p0)
凸包的c#實現算法                {
凸包的c#實現算法                        LinkedList<PointF> list_node = new LinkedList<PointF>();
凸包的c#實現算法                        p0 = GetMinYPoint();
凸包的c#實現算法                        LinkedListNode<PointF> node = new LinkedListNode<PointF>(nodes[0]);
凸包的c#實現算法                        list_node.AddFirst(node);
凸包的c#實現算法                        for (int i = 1; i < nodes.Count; i++)
凸包的c#實現算法                        {
凸包的c#實現算法                                int direct = IsClockDirection(p0, node.Value, nodes[i]);
凸包的c#實現算法                                if (direct == 1)
凸包的c#實現算法                                {
凸包的c#實現算法                                         list_node.AddLast(nodes[i]);
凸包的c#實現算法                                         node = list_node.Last;
凸包的c#實現算法                                         //node.Value = nodes[i];
凸包的c#實現算法                                        
凸包的c#實現算法                                }
凸包的c#實現算法                                else if (direct == -10)
凸包的c#實現算法                                {
凸包的c#實現算法                                        list_node.Last.Value = nodes[i];
凸包的c#實現算法                                        //node = list_node.Last
凸包的c#實現算法                                        //node.Value = nodes[i];
凸包的c#實現算法                                }
凸包的c#實現算法                                else if (direct == 10)
凸包的c#實現算法                                        continue;
凸包的c#實現算法                                else if (direct == -1)
凸包的c#實現算法                                {
凸包的c#實現算法                                        LinkedListNode<PointF> temp = node.Previous;
凸包的c#實現算法                                        while (temp != null && IsClockDirection(p0, temp.Value, nodes[i]) == -1)
凸包的c#實現算法                                        {
凸包的c#實現算法                                                temp = temp.Previous;
凸包的c#實現算法                                        }
凸包的c#實現算法                                        if (temp == null)
凸包的c#實現算法                                        {
凸包的c#實現算法                                                list_node.AddFirst(nodes[i]);
凸包的c#實現算法                                                continue;
凸包的c#實現算法                                        }
凸包的c#實現算法                                        if (IsClockDirection(p0, temp.Value, nodes[i]) == -10)
凸包的c#實現算法                                                temp.Value = nodes[i];
凸包的c#實現算法                                        else if (IsClockDirection(p0, temp.Value, nodes[i]) == 10)
凸包的c#實現算法                                                continue;
凸包的c#實現算法                                        else
凸包的c#實現算法                                                list_node.AddAfter(temp, nodes[i]);
凸包的c#實現算法                                }
凸包的c#實現算法                        }
凸包的c#實現算法                        sor_nodes = list_node.ToArray();
凸包的c#實現算法                        sortedNodes = new Stack<PointF>();
凸包的c#實現算法                        sortedNodes.Push(p0);
凸包的c#實現算法                        sortedNodes.Push(sor_nodes[0]);
凸包的c#實現算法                        sortedNodes.Push(sor_nodes[1]);
凸包的c#實現算法                        for (int i = 2; i<sor_nodes.Length; i++)
凸包的c#實現算法                        {
凸包的c#實現算法
凸包的c#實現算法                                PointF p2 = sor_nodes[i];
凸包的c#實現算法                                PointF p1 = sortedNodes.Pop();
凸包的c#實現算法                                PointF p0_sec = sortedNodes.Pop();
凸包的c#實現算法                                sortedNodes.Push(p0_sec);
凸包的c#實現算法                                sortedNodes.Push(p1);
凸包的c#實現算法
凸包的c#實現算法                                if (IsClockDirection1(p0_sec, p1, p2) == 1)
凸包的c#實現算法                                {
凸包的c#實現算法                                        sortedNodes.Push(p2);
凸包的c#實現算法                                        continue;
凸包的c#實現算法                                }
凸包的c#實現算法                                while (IsClockDirection1(p0_sec, p1, p2) != 1)
凸包的c#實現算法                                {
凸包的c#實現算法                                        sortedNodes.Pop();
凸包的c#實現算法                                        p1 = sortedNodes.Pop();
凸包的c#實現算法                                        p0_sec = sortedNodes.Pop();
凸包的c#實現算法                                        sortedNodes.Push(p0_sec);
凸包的c#實現算法                                        sortedNodes.Push(p1);
凸包的c#實現算法                                }
凸包的c#實現算法                                sortedNodes.Push(p2);
凸包的c#實現算法                            
凸包的c#實現算法                                    
凸包的c#實現算法                                
凸包的c#實現算法
凸包的c#實現算法
凸包的c#實現算法
凸包的c#實現算法                        }
凸包的c#實現算法
凸包的c#實現算法                    
凸包的c#實現算法                }
凸包的c#實現算法                private int IsClockDirection1(PointF p0, PointF p1, PointF p2)
凸包的c#實現算法                {
凸包的c#實現算法                        PointF p0_p1 = new PointF(p1.X - p0.X, p1.Y - p0.Y);
凸包的c#實現算法                        PointF p0_p2 = new PointF(p2.X - p0.X, p2.Y - p0.Y);
凸包的c#實現算法                        return (p0_p1.X * p0_p2.Y - p0_p2.X * p0_p1.Y) > 0 ? 1 : -1;
凸包的c#實現算法                }
凸包的c#實現算法                private PointF GetMinYPoint()
凸包的c#實現算法                {
凸包的c#實現算法                        PointF succNode;
凸包的c#實現算法                        float miny=nodes.Min(r=>r.Y);
凸包的c#實現算法                        IEnumerable<PointF> pminYs = nodes.Where(r => r.Y == miny);
凸包的c#實現算法                        PointF[] ps = pminYs.ToArray();
凸包的c#實現算法                        if (pminYs.Count() > 1)
凸包的c#實現算法                        {
凸包的c#實現算法                                succNode = pminYs.Single(r => r.X == pminYs.Min(t => t.X));
凸包的c#實現算法                                nodes.Remove(succNode);
凸包的c#實現算法                                return succNode;
凸包的c#實現算法                        }
凸包的c#實現算法                        else
凸包的c#實現算法                        {
凸包的c#實現算法                                nodes.Remove(ps[0]);
凸包的c#實現算法                                return ps[0];
凸包的c#實現算法                        }
凸包的c#實現算法
凸包的c#實現算法                }
凸包的c#實現算法                private int IsClockDirection(PointF p0, PointF p1, PointF p2)
凸包的c#實現算法                {
凸包的c#實現算法                        PointF p0_p1 = new PointF(p1.X-p0.X,p1.Y-p0.Y) ;
凸包的c#實現算法                        PointF p0_p2 = new PointF(p2.X - p0.X, p2.Y - p0.Y);
凸包的c#實現算法                        if ((p0_p1.X * p0_p2.Y - p0_p2.X * p0_p1.Y) != 0)
凸包的c#實現算法                                return (p0_p1.X * p0_p2.Y - p0_p2.X * p0_p1.Y) > 0 ? 1 : -1;
凸包的c#實現算法                        else
凸包的c#實現算法                                return DistanceOfNodes(p0, p1) > DistanceOfNodes(p0, p2) ? 10 : -10;
凸包的c#實現算法                                
凸包的c#實現算法                }
凸包的c#實現算法                public Stack<PointF> SortedNodes
凸包的c#實現算法                {
凸包的c#實現算法                        get { return sortedNodes; }
凸包的c#實現算法                }
凸包的c#實現算法
凸包的c#實現算法        }
 
界面部分,供測試使用:
凸包的c#實現算法
凸包的c#實現算法        public partial class Form1 : Form
凸包的c#實現算法        {
凸包的c#實現算法                private List<PointF> nodes;
凸包的c#實現算法                private Graphics g;
凸包的c#實現算法                private Pen pen;
凸包的c#實現算法                public Form1()
凸包的c#實現算法                {
凸包的c#實現算法                        InitializeComponent();
凸包的c#實現算法                        g=this.panel1.CreateGraphics();
凸包的c#實現算法                        g.TranslateTransform(0f,this.panel1.Height);
凸包的c#實現算法                        g.ScaleTransform(1f,-1f);
凸包的c#實現算法                        pen = new Pen(Color.Blue);
凸包的c#實現算法                }
凸包的c#實現算法
凸包的c#實現算法                private void button2_Click(object sender, EventArgs e)
凸包的c#實現算法                {
凸包的c#實現算法                        g.Clear(panel1.BackColor);
凸包的c#實現算法                        nodes = new List<PointF>();
凸包的c#實現算法                        nodes.Clear();
凸包的c#實現算法                        Random rand = new Random();
凸包的c#實現算法                        Point p = new Point(); ;
凸包的c#實現算法                        for (int i = 0; i < 1000; i++)
凸包的c#實現算法                        {
凸包的c#實現算法                                p.X = rand.Next(10, panel1.Width - 9);
凸包的c#實現算法                                p.Y = rand.Next(10, panel1.Height - 9);
凸包的c#實現算法                                nodes.Add(p);
凸包的c#實現算法                                DrawCircle(p);
凸包的c#實現算法                        }
凸包的c#實現算法                    
凸包的c#實現算法                }
凸包的c#實現算法                private void DrawCircle(Point p)
凸包的c#實現算法                {
凸包的c#實現算法                        g.DrawEllipse(pen, p.X - 4, p.Y - 4, 8, 8);
凸包的c#實現算法                        g.FillEllipse(Brushes.Blue, p.X - 4, p.Y - 4, 8, 8);
凸包的c#實現算法                }
凸包的c#實現算法
凸包的c#實現算法                private void button1_Click(object sender, EventArgs e)
凸包的c#實現算法                {
凸包的c#實現算法                        ConvexAogrithm ca = new ConvexAogrithm(nodes);
凸包的c#實現算法                        PointF p;
凸包的c#實現算法                        ca.GetNodesByAngle(out p);
凸包的c#實現算法                        //PointF[] ps = ca.sor_nodes;
凸包的c#實現算法                        //float[] psangle=new float[ps.Length];
凸包的c#實現算法                        //for (int i = 0; i < psangle.Length; i++)
凸包的c#實現算法                             // psangle[i] = CalcAngle(p, ps[i]);
凸包的c#實現算法                        g.DrawEllipse(pen, p.X - 8, p.Y - 8, 16,16);
凸包的c#實現算法                        g.FillEllipse(Brushes.Blue, p.X - 8, p.Y - 8, 16, 16);
凸包的c#實現算法                        Stack<PointF> p_nodes = ca.SortedNodes;
凸包的c#實現算法                        pen = new Pen(Color.Black, 2.0f);
凸包的c#實現算法                        g.SmoothingMode = SmoothingMode.HighQuality;
凸包的c#實現算法                        pen.LineJoin = LineJoin.Round;
凸包的c#實現算法                        g.DrawPolygon(pen, p_nodes.ToArray());
凸包的c#實現算法                }
凸包的c#實現算法                private float CalcAngle(PointF p1,PointF p2)
凸包的c#實現算法                {
凸包的c#實現算法                        float angle = (float)(Math.Atan(Math.Abs(p2.Y - p1.Y + 0.0) / Math.Abs(p2.X - p1.X + 0.0)) * 180 / Math.PI);
凸包的c#實現算法                        if ((p2.Y - p1.Y + 0.0) / (p2.X - p1.X + 0.0) < 0)
凸包的c#實現算法                                angle = 180 - angle;
凸包的c#實現算法                        return angle;
凸包的c#實現算法                }
凸包的c#實現算法        }
上面注釋的為我當初測試排序極角的結果使用的,psangle是排序的結果,調試可看到角度從小到大。1000個點凸包如下(那個大圓點是P0,我為標記使用,無其他含義):
凸包的c#實現算法
200個點的凸包如下:
凸包的c#實現算法
 
 
向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

福贡县| 开封市| 江阴市| 阿拉善右旗| 兰溪市| 郓城县| 库尔勒市| 会同县| 林口县| 临漳县| 玉林市| 临夏县| 二连浩特市| 久治县| 石景山区| 光山县| 丁青县| 拉萨市| 宜君县| 胶州市| 商河县| 枝江市| 惠州市| 陆川县| 潮安县| 东台市| 建平县| 高阳县| 墨竹工卡县| 弥渡县| 钟祥市| 东丰县| 庄浪县| 长葛市| 乌拉特前旗| 青阳县| 曲沃县| 沂源县| 泾源县| 克什克腾旗| 于田县|