Example #1
0
        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();
        }
Example #3
0
        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());
        }
Example #5
0
        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();
                }
            }
        }
Example #6
0
		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;
		}