【问题标题】:Sorting array of Points by the angles to the base point in c#在c#中按与基点的角度对点数组进行排序
【发布时间】:2016-09-24 15:21:26
【问题描述】:

我正在尝试实现格雷厄姆算法以在 C# 中找到凸包。它包括按与基点的角度对点进行排序的步骤。我正在尝试使用从 Comparer 继承的类通过 Array.Sort 方法来实现它。

这里是类

class ReversePolarSorter : Comparer<Point>
    {
        double e = 0.000001;
        double m_baseX;
        double m_baseY;
        public ReversePolarSorter(Point basePoint)
        {
            m_baseX = basePoint.X;
            m_baseY = basePoint.Y;
        }

        public override int Compare(Point a,  Point b)
        {


            double angleA = Math.Atan2(a.Y - m_baseY, a.X - m_baseX);
            double angleB= Math.Atan2(b.Y - m_baseY, b.X - m_baseX);
            int result;
            if (Math.Abs(angleA - angleB) < e)
                result= 0;
            else
                result= angleA.CompareTo(angleB);

            return result;
        }
    }

然后我用它来排序

Comparer<Point> sorter = new ReversePolarSorter(coords[m_pointsNumber-1]);
Array.Sort<Point>(coords, 0, m_pointsNumber - 2, sorter);

coords 是一个点数组。 m_pointsNumber 是点数。
m_pointsNumber-1 是用于计算角度的基点。

它没有按正确的顺序对其进行排序,我看不到问题所在。如果有人能指出它,我将不胜感激。

【问题讨论】:

    标签: c# arrays sorting


    【解决方案1】:

    我认为使用 epsilon 的比较实现是不正确的。

    我们知道,如果a == bb == c,那么a == c。但是这个实现可能会导致a == bb == c,但是a &lt; c,会破坏排序算法。

    由于你有一个基点,你可以使用舍入而不是 epsilon:

    class ReversePolarSorter : Comparer<Point>
    {
        const int precision = 6;
        double m_baseX;
        double m_baseY;
        public ReversePolarSorter(Point basePoint)
        {
            m_baseX = basePoint.X;
            m_baseY = basePoint.Y;
        }
    
        double GetAngle(Point p)
        {
            return Math.Round(Math.Atan2(p.Y - m_baseY, p.X - m_baseX), precision);
        }
    
        public override int Compare(Point a,  Point b)
        {
            return GetAngle(a).CompareTo(GetAngle(b));
        }
    }
    

    另外,请注意Array.Sort 的第三个参数是长度,所以如果m_pointsNumber 是点数并且指向索引m_pointsNumber - 1 的点是基点,那么你应该将m_pointsNumber - 1 传递为 length:

    Array.Sort(coords, 0, m_pointsNumber - 1, sorter);
    

    【讨论】:

    • 谢谢,在 Sort 中更改长度就可以了。我错过了它的长度不是索引
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-16
    • 1970-01-01
    • 2019-07-14
    • 2021-05-13
    • 1970-01-01
    • 2020-10-02
    • 1970-01-01
    相关资源
    最近更新 更多