// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using System; using System.Collections; using System.Collections.Generic; namespace SixLabors.PolygonClipper { /// /// Compares two instances for sorting in the event queue. /// internal sealed class SweepEventComparer : IComparer, IComparer { /// public int Compare(SweepEvent? x, SweepEvent? y) { if (x == null) { return -1; } if (y == null) { return 1; } // Compare by x-coordinate if (x.Point.X > y.Point.X) { return 1; } if (x.Point.X < y.Point.X) { return -1; } // Compare by y-coordinate when x-coordinates are the same if (x.Point.Y != y.Point.Y) { return x.Point.Y > y.Point.Y ? 1 : -1; } // Compare left vs. right endpoint if (x.Left != y.Left) { return x.Left ? 1 : -1; } // Compare collinearity using signed area double area = PolygonUtilities.SignedArea(x.Point, x.OtherEvent.Point, y.OtherEvent.Point); if (area != 0) { return x.IsBelow(y.OtherEvent.Point) ? -1 : 1; } // Compare by polygon type: subject polygons have higher priority return x.PolygonType != PolygonType.Subject && y.PolygonType == PolygonType.Subject ? 1 : -1; } /// public int Compare(object? x, object? y) { if (x is SweepEvent a && y is SweepEvent b) { return this.Compare(a, b); } throw new ArgumentException("Both arguments must be of type SweepEvent.", nameof(x)); } } }