/// <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); }