我有一个点(x,y)列表,我想根据它们相对于参考点的极角进行排序,我将其计算为列表中所有点的平均点。 如何设置IComparer以便我可以将参考点传递给它来计算极角?
答案 0 :(得分:3)
您可以提前计算参考点并将其传递给IComparer
的构造函数:
class PointComparer : IComparer<Point>
{
private readonly Point referencePoint;
public PointComparer(Point referencePoint)
{
this.referencePoint = referencePoint;
}
public Int32 Compare(Point x, Point y)
{
// Compare using referencePoint
}
}
用法:
var ordered = myList.OrderBy(x => x, new PointComparer(calculatedReferencePoint));
我使用了OrderyBy
而不是Sort
,因为当我们参考文档时后者被认为不是稳定的排序。
答案 1 :(得分:1)
您有两种选择。
选项A
参考点必须是Point
对象的一部分。因此,在Point
的比较方法中,您可以考虑计算角度并比较对象。
public int IComparer.Compare(Point x, Point y) {
var angleX = Utilities.CalculateAngle(x.ReferencePoint);
var angleY = Utilities.CalculateAngle(y.ReferencePoint);
if (angleX < angleY) return -1;
if (angleX == angleY) return 0;
if (angleX > angleY) return 1;
// Or simply "return angleX - angleY;"
}
选项B
Angle
应该已经计算好了。使Point
成为不可变结构,并在实例化结构时计算角度。然后只是OrderBy
那个属性。
即
public struct Point
{
public double Angle { get; private set; }
public Point(double referencePoint, double x, double y)
{
// TODO: Calculate Angle
}
}
points.OrderBy(p => p.Angle);