Exemple #1
0
        /// <summary>
        /// Searches the nearest StatusHelperElement from the given Point
        /// </summary>
        /// <param name="point">The Point to search a StatusHelperElement for</param>
        /// <returns>The nearest StatusHelperElement that is positioned left of the Poin</returns>
        internal StatusHelperElement SearchLeft(PolygonPoint point)
        {
            // The found StatusHelperElement and the Distance Variables
            StatusHelperElement result = null;
            var dist = Double.PositiveInfinity;

            var px = point.X;
            var py = point.Y;

            // Search for the right StatusHelperElement
            foreach (var she in this.EdgesHelpers)
            {
                // No need to calculate the X-Value
                if (she.MinX > px)
                {
                    continue;
                }

                // Calculate the x-Coordinate of the Intersection between
                // a horizontal Line from the Point to the Left and the Edge of the StatusHelperElement
                var xValue = she.Edge.PointOne.X + (py - she.Edge.PointOne.Y) * she.Factor;

                // If the xValue is smaller than or equal to the Point's x-Coordinate
                // (i.e. it lies on the left Side of it - allows a small Error)
                if (xValue <= (px + SweepLinePolygonTriangulator.Epsilon))
                {
                    // Calculate the Distance
                    var sheDist = px - xValue;

                    // Update, if the Distance is smaller than a previously found Result
                    if (sheDist < dist)
                    {
                        dist   = sheDist;
                        result = she;
                    }
                }
            }

            // Return the nearest found StatusHelperElement
            return(result);
        }
Exemple #2
0
 /// <summary>
 /// Adds a StatusHelperElement to the List
 /// </summary>
 /// <param name="element"></param>
 internal void Add(StatusHelperElement element)
 {
     this.EdgesHelpers.Add(element);
 }
Exemple #3
0
        /// <summary>
        /// Calculate the Diagonals to add inside the Polygon.
        /// </summary>
        /// <param name="events">The Events in sorted Form</param>
        /// <param name="sweepDown">True in the first Stage (sweeping down), false in the following Stages (sweeping up)</param>
        /// <returns></returns>
        private static List <Tuple <int, int> > CalculateDiagonals(List <PolygonPoint> events, Boolean sweepDown = true)
        {
            // Diagonals to add to the Polygon to make it monotone after the Down- and Up-Sweeps
            var diagonals = new List <Tuple <int, int> >();

            // Construct Status and Helper, a List of Edges left of every Point of the Polygon
            // by shooting a Ray from the Vertex to the left.
            // The Helper Point of that Edge will be used to create Monotone Polygons
            // by adding Diagonals from/to Split- and Merge-Points
            var statusAndHelper = new StatusHelper();

            // Sweep through the Polygon using the sorted Polygon Points
            for (int i = 0; i < events.Count; i++)
            {
                var ev = events[i];
                // Get the Class of this event (depending on the sweeping direction)
                var evClass = ev.PointClass(!sweepDown);

                // Temporary StatusHelperElement
                StatusHelperElement she = null;

                // Handle the different Point-Classes
                switch (evClass)
                {
                case PolygonPointClass.Start:
                    // Just add the left Edge (depending on the sweeping direction)
                    statusAndHelper.Add(new StatusHelperElement(sweepDown ? ev.EdgeTwo : ev.EdgeOne, ev));
                    break;

                case PolygonPointClass.Stop:
                    // Just remove the left Edge (depending on the sweeping direction)
                    statusAndHelper.Remove(sweepDown ? ev.EdgeOne : ev.EdgeTwo);
                    break;

                case PolygonPointClass.Regular:
                    // If the Polygon is positioned on the right Side of this Event
                    if (ev.Last > ev.Next)
                    {
                        // Replace the corresponding (old) StatusHelperElement with the new one
                        statusAndHelper.Remove(sweepDown ? ev.EdgeOne : ev.EdgeTwo);
                        statusAndHelper.Add(new StatusHelperElement(sweepDown ? ev.EdgeTwo : ev.EdgeOne, ev));
                    }
                    else
                    {
                        // Search Edge left of the Event and set Event as it's Helper
                        she        = statusAndHelper.SearchLeft(ev);
                        she.Helper = ev;
                    }
                    break;

                case PolygonPointClass.Merge:
                    // Just remove the left Edge (depending on the sweeping direction)
                    statusAndHelper.Remove(sweepDown ? ev.EdgeOne : ev.EdgeTwo);
                    // Search Edge left of the Event and set Event as it's Helper
                    she        = statusAndHelper.SearchLeft(ev);
                    she.Helper = ev;
                    break;

                case PolygonPointClass.Split:
                    // Search Edge left of the Event
                    she = statusAndHelper.SearchLeft(ev);
                    // Chose diagonal from Helper of Edge to Event.
                    var minP     = Math.Min(she.Helper.Index, ev.Index);
                    var maxP     = Math.Max(she.Helper.Index, ev.Index);
                    var diagonal = new Tuple <int, int>(minP, maxP);
                    diagonals.Add(diagonal);

                    // Replace the Helper of the StatusHelperElement by Event
                    she.Helper = ev;
                    // Insert the right Edge from Event
                    statusAndHelper.Add(new StatusHelperElement(sweepDown ? ev.EdgeTwo : ev.EdgeOne, ev));
                    break;
                }
            }
            return(diagonals);
        }