public static ScanEdgeCollection Create(
            IPath polygon,
            MemoryAllocator allocator,
            int subsampling)
        {
            TessellatedMultipolygon multipolygon = TessellatedMultipolygon.Create(polygon, allocator);

            return(Create(multipolygon, allocator, subsampling));
        }
Esempio n. 2
0
        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);
        }
Esempio n. 3
0
        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);
        }
Esempio n. 4
0
        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);
        }
Esempio n. 5
0
        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);
        }
Esempio n. 6
0
        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
            }