public static IReadOnlyCollection <Point> ConvexHullGrahamScan(this IReadOnlyCollection <Point> points) { var zero = points.FindZeroPoint(); var comparer = new AngleDistanceComparer(zero); var sortedPoints = points .Where(p => p.NotEqualTo(zero)) .OrderBy(p => p, comparer) .ToArray(); var convexHull = new List <Point> { zero, sortedPoints.ElementAt(0) }; for (var i = 1; i < sortedPoints.Length; i++) { convexHull.Add(sortedPoints.ElementAt(i)); convexHull.RemoveInnerConcavePoints(); } convexHull.Add(zero); convexHull.RemoveInnerConcavePoints(); convexHull.RemoveAt(convexHull.Count - 1); return(convexHull); }
private static Tuple <Tangent, Tangent> TangentsTo(this Point point, int indexOfPoint, Polygon polygon) { var angleComparer = new AngleDistanceComparer(point); var sortedPoints = polygon .Points .Select((p, i) => new { p, i }) .OrderByDescending(o => o.p, angleComparer) .ToArray(); var first = sortedPoints.First(); var last = sortedPoints.Last(); var leftTangent = new Tangent(point, indexOfPoint, first.p, first.i); var rightTangent = new Tangent(point, indexOfPoint, last.p, last.i); return(new Tuple <Tangent, Tangent>(leftTangent, rightTangent)); }