/// <summary>
 /// Constructor
 /// </summary>
 /// <param name="vertices">the coordinates of the vertices</param>
 public Trapezoidation(IReadOnlyList <Vertex> vertices, IPolygonSplitSink splitSink)
 {
     this.vertexToEdge = new Dictionary <int, TrapezoidEdge>();
     this.comparer     = new EdgeComparer(vertices);
     this.activeEdges  = new RedBlackTree <TrapezoidEdge>(this.comparer);
     this.splitSink    = splitSink;
 }
            /// <summary>
            /// Combine the right side info with the left side and evaluate if it matches a split situation.
            /// </summary>
            /// <param name="rightVertex">the vertex that defines the right side</param>
            /// <param name="neighborCount">the number of right neighbors</param>
            /// <param name="cornerValidity">the vertex position of the right vertex</param>
            private void EvaluateRight(int rightVertex, Base rightBase, IPolygonSplitSink splitter)
            {
                var combinedBase = this.leftBase | rightBase;

                if (DetectDoubleNeighbor(combinedBase) || DetectDiagonale(combinedBase))
                {
                    splitter.SplitPolygon(this.leftVertex, rightVertex);
                }
            }
            /// <summary>
            /// The lower edge transitions at vertex to a new edge
            /// </summary>
            /// <param name="vertexId">the transition vertex</param>
            /// <param name="nextEdge">the new edge</param>
            /// <param name="splitSink">the polygon splitter</param>
            public void TransitionOnLowerEdge(int vertexId, TrapezoidEdge nextEdge, IPolygonSplitSink splitSink)
            {
                this.EvaluateRight(vertexId, Base.LowerCorner, splitSink);

                new Trapezoid(vertexId, Base.LowerCorner, nextEdge, this.upperEdge);
            }
 /// <summary>
 /// Join two edges. Right of the vertex is outside.
 /// </summary>
 /// <param name="vertexId">the closing vertex id</param>
 /// <param name="splitSink">the polygon splitter</param>
 public void LeaveInsideByJoin(int vertexId, IPolygonSplitSink splitSink)
 {
     this.EvaluateRight(vertexId, Base.NoNeighbor, splitSink);
 }
            /// <summary>
            /// A cusp that transitions from inside to outside. Splits the Trapezoid by one point.
            /// </summary>
            /// <param name="vertexId">the vertex id of the start point</param>
            /// <param name="lowerEdge">the lower edge of the new split</param>
            /// <param name="upperEdge">the upper edge of the new split</param>
            /// <param name="splitSink">the polygon splitter</param>
            public void LeaveInsideBySplit(int vertexId, TrapezoidEdge lowerEdge, TrapezoidEdge upperEdge, IPolygonSplitSink splitSink)
            {
                this.EvaluateRight(vertexId, Base.TwoNeighbors, splitSink);

                new Trapezoid(vertexId, Base.LowerCorner, upperEdge, this.upperEdge);
                new Trapezoid(vertexId, Base.UpperCorner, this.lowerEdge, lowerEdge);
            }
            /// <summary>
            /// A right pointing cusp that enters the polygon space. Join the upper left and the lower left trapezoids in one.
            /// </summary>
            /// <param name="vertexId">the vertex id that joins the two edges.</param>
            /// <param name="lower">the left lower trapezoid</param>
            /// <param name="upper">the left upper trapezoid</param>
            /// <param name="splitSink">the polygon splitter</param>
            public static void EnterInsideByJoin(Trapezoid lower, Trapezoid upper, int vertexId, IPolygonSplitSink splitSink)
            {
                upper.EvaluateRight(vertexId, Base.LowerCorner, splitSink);
                lower.EvaluateRight(vertexId, Base.UpperCorner, splitSink);

                new Trapezoid(vertexId, Base.TwoNeighbors, lower.lowerEdge, upper.upperEdge);
            }