public Vertex(Location l, VertexCategory cat) { Loc = l; Category = cat; if (cat == VertexCategory.Exit && l.HasExitCoords) { RegionId = GetRegionId(l.ExitCoords); } else { RegionId = GetRegionId(l.Coords); } }
public void Move(bool emitPreviousEdge) { VertexCategory startVertexCategory = CreateVertexCategory(this.PreviousEdge.EdgeCategory, this.CurrentEdge.EdgeCategory); VertexCategory endVertexCategory = CreateVertexCategory(this.CurrentEdge.EdgeCategory, this.NextEdge.EdgeCategory); EdgeData.ApplyVertexCategory(startVertexCategory, ref this.PreviousEdge, ref this.CurrentEdge); EdgeData.ApplyVertexCategory(endVertexCategory, ref this.CurrentEdge, ref this.NextEdge); if (emitPreviousEdge) { this.PreviousEdge.EmitScanEdge(this.output, ref this.EdgeCounter); } this.PreviousEdge = this.CurrentEdge; this.CurrentEdge = this.NextEdge; }
public static void ApplyVertexCategory( VertexCategory vertexCategory, ref EdgeData fromEdge, ref EdgeData toEdge) { // On PolygonScanner needs to handle intersections at edge connections (vertices) in a special way: // - We need to make sure we do not report ("emit") an intersection point more times than necessary because we detected the intersection at both edges. // - We need to make sure we we emit proper intersection points when scanning through a horizontal line // In practice this means that vertex intersections have to emitted: 0-2 times in total: // - Do not emit on vertex of collinear edges // - Emit 2 times if: // - One of the edges is horizontal // - The corner is concave // (The reason for tis rule is that we do not scan horizontal edges) // - Emit once otherwise // Since PolygonScanner does not process vertices, only edges, we need to define arbitrary rules // about WHERE (on which edge) do we emit the vertex intersections. // For visualization of the rules see: // PoygonScanning.MD // For an example, see: // ImageSharp.Drawing.Tests/Shapes/Scan/SimplePolygon_AllEmitCases.png switch (vertexCategory) { case VertexCategory.UpUp: // 0, 1 toEdge.emitStart = 1; break; case VertexCategory.UpDown: // 1, 1 toEdge.emitStart = 1; fromEdge.emitEnd = 1; break; case VertexCategory.UpLeft: // 2, 0 fromEdge.emitEnd = 2; break; case VertexCategory.UpRight: // 1, 0 fromEdge.emitEnd = 1; break; case VertexCategory.DownUp: // 1, 1 toEdge.emitStart = 1; fromEdge.emitEnd = 1; break; case VertexCategory.DownDown: // 0, 1 toEdge.emitStart = 1; break; case VertexCategory.DownLeft: // 1, 0 fromEdge.emitEnd = 1; break; case VertexCategory.DownRight: // 2, 0 fromEdge.emitEnd = 2; break; case VertexCategory.LeftUp: // 0, 1 toEdge.emitStart = 1; break; case VertexCategory.LeftDown: // 0, 2 toEdge.emitStart = 2; break; case VertexCategory.LeftLeft: // 0, 0 - collinear break; case VertexCategory.LeftRight: // 0, 0 - collinear break; case VertexCategory.RightUp: // 0, 2 toEdge.emitStart = 2; break; case VertexCategory.RightDown: // 0, 1 toEdge.emitStart = 1; break; case VertexCategory.RightLeft: // 0, 0 - collinear break; case VertexCategory.RightRight: // 0, 0 - collinear break; } }