public static List <Point> ConvexHullGrahams(List <Point> points) { if (points.Count == 1) { return(points); } List <Point> outPoints = new List <Point>(); var(minPoint, idx) = HelperMethods.GetMinPoint(points, 'y'); var minVec = new Vector2D(new Point(minPoint.X + 1234, minPoint.Y)); points.Sort((a, b) => { if (HelperMethods.CheckTurn(new Line(minPoint, a), b) == Enums.TurnType.Colinear) { return(Point.GetSqrDistance(a, minPoint).CompareTo(Point.GetSqrDistance(b, minPoint))); } return(minVec.AngleTo(new Vector2D(minPoint.VectorTo(a))).Degrees .CompareTo(minVec.AngleTo(new Vector2D(minPoint.VectorTo(b))).Degrees)); }); for (int i = 1; i < points.Count - 1; ++i) { if (HelperMethods.CheckTurn(new Line(points[0], points[i]), points[i + 1]) == Enums.TurnType.Colinear) { points.RemoveAt(i--); } } if (points.Count <= 3) { outPoints.AddRange(points); return(outPoints); } Stack <Point> st = new Stack <Point>(); st.PushRange(points.GetRange(0, 3)); for (int i = 3; i < points.Count; ++i) { while (HelperMethods.CheckTurn(new Line(st.GetSecondTop(), st.Peek()), points[i]) != Enums.TurnType.Left) { st.Pop(); } st.Push(points[i]); } outPoints.AddRange(st); outPoints.Reverse(); return(outPoints); }
public static List <Point> SortPoints(List <Point> points) { var(minPoint, idx) = HelperMethods.GetMinPoint(points, 'y'); var minVec = new Vector2D(new Point(minPoint.X + 1234, minPoint.Y)); points.Sort((a, b) => { if (HelperMethods.CheckTurn(new Line(minPoint, a), b) == Enums.TurnType.Colinear) { return(Point.GetSqrDistance(a, minPoint).CompareTo(Point.GetSqrDistance(b, minPoint))); } return(minVec.AngleTo(new Vector2D(minPoint.VectorTo(a))).Degrees .CompareTo(minVec.AngleTo(new Vector2D(minPoint.VectorTo(b))).Degrees)); }); return(points); }
public static bool IsSupportLine(Line l, List <Point> points) { int idx = 0; Enums.TurnType prevSide = Enums.TurnType.Left;//dummy value bool inside = true; foreach (Point p in points) { if (p.Equals(l.Start) || p.Equals(l.End)) { continue; } var curSide = HelperMethods.CheckTurn(l, p); if (curSide == Enums.TurnType.Colinear) { var dst1 = Point.GetSqrDistance(l.Start, l.End); var dst2 = Point.GetSqrDistance(l.Start, p); if (dst1 < dst2) { inside = false; break; } } if (idx != 0) { if (curSide != prevSide) { inside = false; break; } } prevSide = curSide; idx++; } return(inside); }