美文网首页
2018-10-24凸包算法

2018-10-24凸包算法

作者: 小G仔 | 来源:发表于2018-10-24 10:04 被阅读0次

内容转载自:
https://blog.csdn.net/u010251278/article/details/50469594?utm_source=blogxgwz21
https://www.2cto.com/kf/201212/177098.html

代码实现,转自第二篇博客(添加了注释)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Drawing;

namespace pipelineSpatialAnalysis.Function.analysis
{

class ConvexAogrithm
{

    private List<PointF> nodes;

    private Stack<PointF> sortedNodes;

    public PointF[] sor_nodes;

    public ConvexAogrithm(List<PointF> points)
    {

        nodes = points;


    }

    //求两点之间的距离
    private double DistanceOfNodes(PointF p0, PointF p1)
    {

        if (p0.IsEmpty || p1.IsEmpty)

            return 0.0;

        return Math.Sqrt((p1.X - p0.X) * (p1.X - p0.X) + (p1.Y - p0.Y) * (p1.Y - p0.Y));

    }

    //获取凸包的点
    public void GetNodesByAngle(out PointF p0)
    {
        #region 先把夹角排序排出来
        LinkedList<PointF> list_node = new LinkedList<PointF>();

        p0 = GetMinYPoint();

        LinkedListNode<PointF> node = new LinkedListNode<PointF>(nodes[0]);

        list_node.AddFirst(node);

        for (int i = 1; i < nodes.Count; i++)
        {
            int direct = IsClockDirection(p0, node.Value, nodes[i]);
            if (direct == 1)
            {
                list_node.AddLast(nodes[i]);
                node = list_node.Last;              
            }
            else if (direct == -10)
            {
                list_node.Last.Value = nodes[i];
            }
            else if (direct == 10)
                continue;
            else if (direct == -1)
            {
                LinkedListNode<PointF> temp = node.Previous;
                while (temp != null && IsClockDirection(p0, temp.Value, nodes[i]) == -1)
                {
                    temp = temp.Previous;
                }
                if (temp == null)
                {
                    list_node.AddFirst(nodes[i]);
                    continue;
                }
                if (IsClockDirection(p0, temp.Value, nodes[i]) == -10)
                    temp.Value = nodes[i];
                else if (IsClockDirection(p0, temp.Value, nodes[i]) == 10)
                    continue;
                else
                    list_node.AddAfter(temp, nodes[i]);
            }

        }
        # endregion

        # region 用栈的形把点塞进去
        sor_nodes = list_node.ToArray();

        sortedNodes = new Stack<PointF>();

        sortedNodes.Push(p0);

        sortedNodes.Push(sor_nodes[0]);

        sortedNodes.Push(sor_nodes[1]);

        for (int i = 2; i < sor_nodes.Length; i++)
        {



            PointF p2 = sor_nodes[i];

            PointF p1 = sortedNodes.Pop();

            PointF p0_sec = sortedNodes.Pop();

            sortedNodes.Push(p0_sec);

            sortedNodes.Push(p1);



            if (IsClockDirection1(p0_sec, p1, p2) == 1)
            {

                sortedNodes.Push(p2);

                continue;

            }

            while (IsClockDirection1(p0_sec, p1, p2) != 1)
            {

                sortedNodes.Pop();

                p1 = sortedNodes.Pop();

                p0_sec = sortedNodes.Pop();

                sortedNodes.Push(p0_sec);

                sortedNodes.Push(p1);

            }

            sortedNodes.Push(p2);

        #endregion

        }

    }

    //是否是顺时针
    private int IsClockDirection1(PointF p0, PointF p1, PointF p2)
    {

        PointF p0_p1 = new PointF(p1.X - p0.X, p1.Y - p0.Y);

        PointF p0_p2 = new PointF(p2.X - p0.X, p2.Y - p0.Y);

        return (p0_p1.X * p0_p2.Y - p0_p2.X * p0_p1.Y) > 0 ? 1 : -1;

    }

    //获取最小的坐标Y的点
    private PointF GetMinYPoint()
    {

        PointF succNode;

        float miny = nodes.Min(r => r.Y);

        IEnumerable<PointF> pminYs = nodes.Where(r => r.Y == miny);

        PointF[] ps = pminYs.ToArray();

        if (pminYs.Count() > 1)
        {

            succNode = pminYs.Single(r => r.X == pminYs.Min(t => t.X));

            nodes.Remove(succNode);

            return succNode;

        }

        else
        {

            nodes.Remove(ps[0]);

            return ps[0];

        }



    }
    //是否是顺时针
    private int IsClockDirection(PointF p0, PointF p1, PointF p2)
    {

        PointF p0_p1 = new PointF(p1.X - p0.X, p1.Y - p0.Y);

        PointF p0_p2 = new PointF(p2.X - p0.X, p2.Y - p0.Y);

        if ((p0_p1.X * p0_p2.Y - p0_p2.X * p0_p1.Y) != 0)

            return (p0_p1.X * p0_p2.Y - p0_p2.X * p0_p1.Y) > 0 ? 1 : -1;

        else

            return DistanceOfNodes(p0, p1) > DistanceOfNodes(p0, p2) ? 10 : -10;



    }

    public Stack<PointF> SortedNodes
    {

        get { return sortedNodes; }

    }


}

}

相关文章

  • 2018-10-24凸包算法

    内容转载自:https://blog.csdn.net/u010251278/article/details/50...

  • 算法复习-geometric algo

    convex hull 凸包-video25&video26 凸包算法剖析https://cyw3.github....

  • 凸包算法

    R版本 python版本

  • 凸包算法

    凸包点集的性质 凸包点集中,取出相邻的两个点所构成的边一定能将所有点分割在一边,而另一边并无任何点。 若我们可以按...

  • Python3 趣味系列题8 ------ 凸包动态绘制

    本文介绍利用Graham Scan算法获得凸包(平面凸包),并动态展示凸包的形成过程。下面用比较通俗的语言,介绍下...

  • 凸包

    凸包最常用的凸包算法是Graham扫描法和Jarvis步进法Graham's Scan法这个算法是由数学大师葛立恒...

  • 提取平面点云的轮廓

    一. 基于凸包的凹点挖掘算法: 1. 提取点云的凸包 2. 计算凸包每条边的顶点的点密度(即该点 K 个临...

  • Jarvis步进凸包算法

    凸包算法作为计算几何的基础和核心问题足以引起重视.这里给出Jarvis步进算法的Python实现.测试环境是Ubu...

  • 《python算法教程》Day11 - 分治法求解平面凸包问题

    这是《python算法教程》的第11篇读书笔记,笔记主要内容是使用分治法求解凸包。 平面凸包问题简介 在一个平面点...

  • 算法训练营--凸包

    描述 给定n个二维平面上的点,求他们的凸包。 输入 第一行包含一个正整数n。 接下来n行,每行包含两个整数x,y,...

网友评论

      本文标题:2018-10-24凸包算法

      本文链接:https://www.haomeiwen.com/subject/znlttqtx.html