问题:给定平面中n个点所组成的集合,将它们连接起来形成一条简单的封闭路径。所谓简单路径,是指边与边无交叉。

如下图所示10个点组成的简单轮廓:

几何算法:点集合构造简单多边形

思路:取x坐标最大的点A(如果最大x坐标的点不止一个,则取Y坐标最小的点),依次计算A点与其余各点的连线与水平线之间夹角的正切值,然后按照正切值排序,依次连接排序后的各点即组成一个简单图形。

原理:其它所有点都在A点的左侧,所有夹角的范围为-Pi/2~Pi/2,单调递增函数。

几何算法:点集合构造简单多边形

举一个例子如下:

几何算法:点集合构造简单多边形

各点坐标与A点的角度斜率如下(已经排序好):

x:426.192518536091,y:30.5668629242884,slope:-2.21036105157629
x:132.904271903869,y:111.805767306036,slope:0.0233827696146631
x:209.153583263584,y:158.396180071121,slope:0.216615047225945
x:51.2625493860163,y:271.425922467106,slope:0.409713066051227
x:172.80558813494,y:320.363658168522,slope:0.754116336162768
x:174.841647802313,y:361.474091434606,slope:0.903935084923323
x:262.993097888768,y:306.679940091763,slope:1.03059799172764
x:405.520514378101,y:212.478244240618,slope:2.00680658499766
x:410.405247491042,y:324.597360433357,slope:4.49064367657446
x:459.491329337233,y:104.169257382941,slope:1.79769313486232E+308

其中A点为:x:459.491329337233,y:104.169257382941,slope:1.79769313486232E+308

下面给出具体算法(C#实现):

几何点定义,实现IComparable<T>接口,按照正切值排序要用到:

  public struct GeometryPoint : IComparable<GeometryPoint>
    {        
        public GeometryPoint(double x, double y, double slope = double.NaN)
        {
            this.x = x;
            this.y = y;
            this.slope = slope;
        }
        private double x;
        public double X
        {
            get { return x; }
            set { x = value; }
        }
        private double y;
        public double Y
        {
            get { return y; }
            set { y = value; }
        }
        private double slope;
        public double SLOPE
        {
            get { return slope; }
            set { slope = value; }
        }
      
        public int CompareTo(GeometryPoint p)
        {
            if (this.slope < p.slope)
            {
                return -1;
            }
            else if (this.slope > p.slope)
            {
                return 1;
            }
            else
            {
                if (this.x == p.x && this.SLOPE == p.SLOPE && this.SLOPE == double.MaxValue)
                {
                    if (this.y == p.y)
                    {
                        return 0;
                    }
                    else if (this.y < p.y)
                    {
                        return 1;
                    }
                    else//(this.y > p.y)
                    {
                        return -1;
                    }
                }
                return 0;
            }
        }
        public override string ToString()
        {
            return string.Format("x:{0},y:{1},slope:{2}", x, y, slope);
        }
    }
GeometryPoint 定义

相关文章:

  • 2021-11-26
  • 2022-02-10
  • 2022-12-23
  • 2022-12-23
  • 2021-10-29
  • 2022-12-23
猜你喜欢
  • 2022-02-11
  • 2021-10-07
  • 2021-10-24
  • 2021-05-22
相关资源
相似解决方案