/// <summary>
        /// A transition from one vertex to the next, where prev>id has the same direction as id>next
        /// </summary>
        /// <param name="id">the id of the current vertex</param>
        /// <param name="prev">the id of previous polygon vertex</param>
        /// <param name="next">the id of the next polygon vertex</param>
        public void HandleTransition(IPolygonVertexInfo info)
        {
            var oldEdge   = this.EdgeForVertex(info.Id, info.Unique);
            var trapezoid = oldEdge.Trapezoid;

            if (oldEdge.IsRightToLeft)
            {
                var newEdge = this.Transition(oldEdge, info.Prev, info.PrevUnique);
                trapezoid.TransitionOnLowerEdge(info.Id, newEdge, this.splitSink);
            }
            else
            {
                var newEdge = this.Transition(oldEdge, info.Next, info.NextUnique);
                trapezoid.TransitionOnUpperEdge(info.Id, newEdge, this.splitSink);
            }
        }
 /// <summary>
 /// Handle an opening cusp. i.e. starts two new edges.
 /// </summary>
 /// <param name="id">the id of the cusp vertex</param>
 /// <param name="prev">the id of previous polygon vertex</param>
 /// <param name="next">the id of the next polygon vertex</param>
 public void HandleOpeningCusp(IPolygonVertexInfo info)
 {
     var(lowerEdge, upperEdge) = this.StartNewTrapezoidEdges(
         info.Id,
         info.Prev,
         info.PrevUnique,
         info.Next,
         info.NextUnique);
     if (lowerEdge.IsRightToLeft)
     {
         Trapezoid.EnterInsideBySplit(info.Id, lowerEdge, upperEdge);
     }
     else
     {
         var belowEdge = lowerEdge.TreeNode.Prev.Data;
         var trapezoid = belowEdge.Trapezoid;
         trapezoid.LeaveInsideBySplit(info.Id, lowerEdge, upperEdge, this.splitSink);
     }
 }
        /// <summary>
        /// Handle a closing cusp. i.e. joins two edges
        /// </summary>
        /// <param name="id">the id of the cusp vertex</param>
        /// <param name="prev">the id of previous polygon vertex</param>
        /// <param name="next">the id of the next polygon vertex</param>
        public void HandleClosingCusp(IPolygonVertexInfo info)
        {
            var           lowerEdge = this.EdgeForVertex(info.Id, info.Unique);
            TrapezoidEdge upperEdge;

            var prevEdge = lowerEdge.TreeNode.Prev?.Data;

            if (prevEdge?.Right == lowerEdge.Right && (prevEdge.Left == info.Prev || prevEdge.Left == info.Next))
            {
                upperEdge = lowerEdge;
                lowerEdge = prevEdge;
            }
            else
            {
                upperEdge = lowerEdge.TreeNode.Next?.Data;
            }

            if (lowerEdge.Right != upperEdge?.Right)
            {
                throw new InvalidOperationException($"Invalid join of edges lower: {lowerEdge} and upper: {upperEdge}");
            }

            var lowerTrapezoid = lowerEdge.Trapezoid;

            if (lowerEdge.IsRightToLeft)
            {
                lowerTrapezoid.LeaveInsideByJoin(info.Id, this.splitSink);
            }
            else
            {
                var upperEdge2     = lowerEdge.TreeNode.Next.Data;
                var upperTrapezoid = upperEdge2.Trapezoid;
                Trapezoid.EnterInsideByJoin(lowerTrapezoid, upperTrapezoid, info.Id, this.splitSink);
            }

            this.JoinTrapezoidEdges(lowerEdge);
        }