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