public static IListSource <Point> ComputeConvexHull(List <Point> points, bool sortInPlace) { if (points.Count < 2) { return(new DList <Point>((IReadOnlyList <Point>)points)); } if (!sortInPlace) { points = new List <Point>(points); } points.Sort((a, b) => a.X == b.X ? a.Y.CompareTo(b.Y) : a.X > b.X ? 1 : -1); // Importantly, DList provides O(1) insertion at beginning and end DList <Point> hull = new DList <Point>(); int L = 0, U = 0; // size of lower and upper hulls // Builds a hull such that the output polygon starts at the leftmost point. for (int i = points.Count - 1; i >= 0; i--) { // right turn (clockwise) => negative cross product (for Y-up coords) Point p = points[i], p1; // build lower hull (at end of output list) while (L >= 2 && (p1 = hull.Last).Sub(hull[hull.Count - 2]).Cross(p.Sub(p1)) >= 0) { hull.RemoveAt(hull.Count - 1); L--; } hull.PushLast(p); L++; // build upper hull (at beginning of output list) while (U >= 2 && (p1 = hull.First).Sub(hull[1]).Cross(p.Sub(p1)) <= 0) { hull.RemoveAt(0); U--; } if (U != 0) // when U == 0, share the point added above { hull.PushFirst(p); } U++; Debug.Assert(U + L == hull.Count + 1); } hull.RemoveAt(hull.Count - 1); return(hull); }
public static PointF[] ComputeConvexHull(List<PointF> points, bool sortInPlace = false) { if (!sortInPlace) points = new List<PointF>(points); points.Sort((a, b) => a.X == b.X ? a.Y.CompareTo(b.Y) : (a.X > b.X ? 1 : -1)); DList<PointF> hull = new DList<PointF>(); int L = 0, U = 0; // size of lower and upper hulls // Builds a hull such that the output polygon starts at the leftmost point. for (int i = points.Count - 1; i >= 0; i--) { PointF p = points[i], p1; // build lower hull (at end of output list) while (L >= 2 && cross((p1 = hull.Last),hull[hull.Count - 2], points[i]) >= 0) { hull.RemoveAt(hull.Count - 1); L--; } hull.PushLast(p); L++; // build upper hull (at beginning of output list) while (U >= 2 && cross((p1 = hull.First), (hull[1]), points[i]) <= 0) { hull.RemoveAt(0); U--; } if (U != 0) // when U=0, share the point added above hull.PushFirst(p); U++; } try { hull.RemoveAt(hull.Count - 1); } catch (System.Exception) { } return hull.ToArray(); }
public static IListSource <double[]> ComputeConvexHull(List <double[]> points, bool sortInPlace = false) { if (!sortInPlace) { points = new List <double[]>(points); } points.Sort((a, b) => a[0] == b[0] ? a[1].CompareTo(b[1]) : (a[0] > b[0] ? 1 : -1)); // Importantly, DList provides O(1) insertion at beginning and end DList <double[]> hull = new DList <double[]>(); int L = 0, U = 0; // size of lower and upper hulls // Builds a hull such that the output polygon starts at the leftmost point. for (int i = points.Count - 1; i >= 0; i--) { double[] p = points[i], p1; // build lower hull (at end of output list) while (L >= 2 && (p1 = hull.Last).Sub(hull[hull.Count - 2]).Cross(p.Sub(p1)) >= 0) { hull.RemoveAt(hull.Count - 1); L--; } hull.PushLast(p); L++; // build upper hull (at beginning of output list) while (U >= 2 && (p1 = hull.First).Sub(hull[1]).Cross(p.Sub(p1)) <= 0) { hull.RemoveAt(0); U--; } if (U != 0) // when U=0, share the point added above { hull.PushFirst(p); } U++; Debug.Assert(U + L == hull.Count + 1); } hull.RemoveAt(hull.Count - 1); return(hull); }
public static PointF[] ComputeConvexHull(List <PointF> points, bool sortInPlace = false) { if (!sortInPlace) { points = new List <PointF>(points); } points.Sort((a, b) => a.X == b.X ? a.Y.CompareTo(b.Y) : (a.X > b.X ? 1 : -1)); DList <PointF> hull = new DList <PointF>(); int L = 0, U = 0; // size of lower and upper hulls // Builds a hull such that the output polygon starts at the leftmost point. for (int i = points.Count - 1; i >= 0; i--) { PointF p = points[i], p1; // build lower hull (at end of output list) while (L >= 2 && cross((p1 = hull.Last), hull[hull.Count - 2], points[i]) >= 0) { hull.RemoveAt(hull.Count - 1); L--; } hull.PushLast(p); L++; // build upper hull (at beginning of output list) while (U >= 2 && cross((p1 = hull.First), (hull[1]), points[i]) <= 0) { hull.RemoveAt(0); U--; } if (U != 0) // when U=0, share the point added above { hull.PushFirst(p); } U++; } hull.RemoveAt(hull.Count - 1); return(hull.ToArray()); }
LNode Process(ref RVList <LNode> list, LNode single, bool asRoot, bool resetOpenNamespaces, bool areAttributesOrIsTarget) { if (single == null && list.Count == 0) { return(null); // no-op requested } var oldS = _s; var oldAncestors = _ancestorStack; var oldMP = MacroProcessor._current; MacroProcessor._current = _parent; bool newScope = false; try { bool reentrant = _reentrancyCounter++ != 0; if (!reentrant) { asRoot = true; } Debug.Assert(reentrant || _scopes.Count == 0); Debug.Assert(reentrant || _ancestorStack == null); if (asRoot) { _ancestorStack = new DList <LNode>(); } _s = new CurNodeState(); if (asRoot || resetOpenNamespaces) { var namespaces = !reentrant || resetOpenNamespaces?_parent.PreOpenedNamespaces.Clone() : _curScope.OpenNamespaces.Clone(); var properties = asRoot ? new MMap <object, object>() : _curScope.ScopedProperties; newScope = true; _curScope = new Scope(namespaces, properties, this, true); _scopes.Add(_curScope); } int maxExpansions = asRoot ? MaxExpansions : _s.MaxExpansions - 1; if (single != null) { return(ApplyMacros(single, maxExpansions, areAttributesOrIsTarget)); } else { int oldStackCount = _ancestorStack.Count; LNode splice = null; if (asRoot) { splice = list.AsLNode(S.Splice); _ancestorStack.PushLast(splice); } list = ApplyMacrosToList(list, maxExpansions, areAttributesOrIsTarget); _ancestorStack.PopLast(); Debug.Assert(_ancestorStack.Count == oldStackCount); return(splice); } } finally { _reentrancyCounter--; MacroProcessor._current = oldMP; _ancestorStack = oldAncestors; _s = oldS; if (newScope) { PopScope(); } } }
public static IListSource<Point> ComputeConvexHull(List<Point> points, bool sortInPlace) { if (!sortInPlace) points = new List<Point>(points); points.Sort((a, b) => a.X == b.X ? a.Y.CompareTo(b.Y) : a.X > b.X ? 1 : -1); // Importantly, DList provides O(1) insertion at beginning and end DList<Point> hull = new DList<Point>(); int L = 0, U = 0; // size of lower and upper hulls // Builds a hull such that the output polygon starts at the leftmost point. for (int i = points.Count - 1; i >= 0 ; i--) { // right turn (clockwise) => negative cross product (for Y-up coords) Point p = points[i], p1; // build lower hull (at end of output list) while (L >= 2 && (p1 = hull.Last).Sub(hull[hull.Count-2]).Cross(p.Sub(p1)) >= 0) { hull.RemoveAt(hull.Count-1); L--; } hull.PushLast(p); L++; // build upper hull (at beginning of output list) while (U >= 2 && (p1 = hull.First).Sub(hull[1]).Cross(p.Sub(p1)) <= 0) { hull.RemoveAt(0); U--; } if (U != 0) // when U == 0, share the point added above hull.PushFirst(p); U++; Debug.Assert(U + L == hull.Count + 1); } hull.RemoveAt(hull.Count - 1); return hull; }