public static ScanEdgeCollection Create( IPath polygon, MemoryAllocator allocator, int subsampling) { TessellatedMultipolygon multipolygon = TessellatedMultipolygon.Create(polygon, allocator); return(Create(multipolygon, allocator, subsampling)); }
public void Create_FromStar() { var polygon = new Star(100, 100, 5, 30, 60); PointF[] points = polygon.Flatten().Single().Points.Span.ToArray(); using var multipolygon = TessellatedMultipolygon.Create(polygon, MemoryAllocator); VerifyRing(multipolygon[0], points, true, false); }
public void Create_FromRecangle() { var polygon = new RectangularPolygon(10, 20, 100, 50); PointF[] points = polygon.Flatten().Single().Points.Span.ToArray(); using var multipolygon = TessellatedMultipolygon.Create(polygon, MemoryAllocator); VerifyRing(multipolygon[0], points, true, false); Assert.Equal(4, multipolygon.TotalVertexCount); }
public void Create_FromPolygon_Case2(bool reverseOriginal) { PointF[] points = PolygonFactory.CreatePointArray((0, 0), (2, 0), (3, 1), (3, 0), (6, 0), (6, 2), (5, 2), (5, 1), (4, 1), (4, 2), (2, 2), (1, 1), (0, 2)); if (reverseOriginal) { points.AsSpan().Reverse(); } var polygon = new Polygon(new LinearLineSegment(points)); using var multipolygon = TessellatedMultipolygon.Create(polygon, MemoryAllocator); VerifyRing(multipolygon[0], points, !reverseOriginal, false); }
public void Create_FromPolygon_Case1(bool reverseOriginal) { PointF[] points = PolygonFactory.CreatePointArray((0, 3), (3, 3), (3, 0), (1, 2), (1, 1), (0, 0)); if (reverseOriginal) { points.AsSpan().Reverse(); } var polygon = new Polygon(new LinearLineSegment(points)); using var multipolygon = TessellatedMultipolygon.Create(polygon, MemoryAllocator); VerifyRing(multipolygon[0], points, reverseOriginal, false); Assert.Equal(6, multipolygon.TotalVertexCount); }
public static PolygonScanner Create( IPath polygon, int minY, int maxY, int subsampling, IntersectionRule intersectionRule, MemoryAllocator allocator) { var multipolygon = TessellatedMultipolygon.Create(polygon, allocator); var edges = ScanEdgeCollection.Create(multipolygon, allocator, subsampling); var scanner = new PolygonScanner(edges, multipolygon.TotalVertexCount * 2, minY, maxY, subsampling, intersectionRule, allocator); scanner.Init(); return(scanner); }
internal static ScanEdgeCollection Create(TessellatedMultipolygon multipolygon, MemoryAllocator allocator, int subsampling) { // We allocate more than we need, since we don't know how many horizontal edges do we have: IMemoryOwner <ScanEdge> buffer = allocator.Allocate <ScanEdge>(multipolygon.TotalVertexCount); RingWalker walker = new RingWalker(buffer.Memory.Span); using IMemoryOwner <float> roundedYBuffer = allocator.Allocate <float>(multipolygon.Max(r => r.Vertices.Length)); Span <float> roundedY = roundedYBuffer.Memory.Span; foreach (TessellatedMultipolygon.Ring ring in multipolygon) { if (ring.VertexCount < 3) { continue; } ReadOnlySpan <PointF> vertices = ring.Vertices; RoundY(vertices, roundedY, subsampling); walker.PreviousEdge = new EdgeData(vertices, roundedY, vertices.Length - 2); // Last edge walker.CurrentEdge = new EdgeData(vertices, roundedY, 0); // First edge walker.NextEdge = new EdgeData(vertices, roundedY, 1); // Second edge walker.Move(false); for (int i = 1; i < vertices.Length - 2; i++) { walker.NextEdge = new EdgeData(vertices, roundedY, i + 1); walker.Move(true); } walker.NextEdge = new EdgeData(vertices, roundedY, 0); // First edge walker.Move(true); // Emit edge before last edge walker.NextEdge = new EdgeData(vertices, roundedY, 1); // Second edge walker.Move(true); // Emit last edge }