diff --git a/src/ImageSharp.Drawing/Processors/FillShapeProcessor.cs b/src/ImageSharp.Drawing/Processors/FillShapeProcessor.cs index 867ca7c90..b742682a1 100644 --- a/src/ImageSharp.Drawing/Processors/FillShapeProcessor.cs +++ b/src/ImageSharp.Drawing/Processors/FillShapeProcessor.cs @@ -78,6 +78,10 @@ namespace ImageSharp.Drawing.Processors var buffer = arrayPool.Rent(maxIntersections); var left = new Vector2(startX, y); var right = new Vector2(endX, y); + if (y == 100) + { + var sdf = ""; + } // foreach line we get all the points where this line crosses the polygon var pointsFound = this.poly.FindIntersections(left, right, buffer, maxIntersections, 0); @@ -89,7 +93,7 @@ namespace ImageSharp.Drawing.Processors return; } - QuickSortX(buffer, 0, pointsFound); + QuickSortX(buffer, pointsFound); int currentIntersection = 0; float nextPoint = buffer[0].X; @@ -228,7 +232,7 @@ namespace ImageSharp.Drawing.Processors return; } - QuickSortY(buffer, 0, pointsFound); + QuickSortY(buffer, pointsFound); int currentIntersection = 0; float nextPoint = buffer[0].Y; @@ -363,89 +367,96 @@ namespace ImageSharp.Drawing.Processors } } - private static void QuickSortX(Vector2[] data, int left, int right) + private static void Swap(Vector2[] data, int left, int right) + { + Vector2 tmp = data[left]; + data[left] = data[right]; + data[right] = tmp; + } + + private static void QuickSortY(Vector2[] A, int size) + { + QuickSortY(A, 0, size - 1); + } + + private static void QuickSortY(Vector2[] A, int lo, int hi) + { + if (lo < hi) + { + int p = PartitionY(A, lo, hi); + QuickSortY(A, lo, p); + QuickSortY(A, p + 1, hi); + } + } + + private static void QuickSortX(Vector2[] A, int size) { - int i = left - 1; - int j = right; + QuickSortX(A, 0, size - 1); + } + private static void QuickSortX(Vector2[] A, int lo, int hi) + { + if (lo < hi) + { + int p = PartitionX(A, lo, hi); + QuickSortX(A, lo, p); + QuickSortX(A, p + 1, hi); + } + } + + private static int PartitionX(Vector2[] A, int lo, int hi) + { + float pivot = A[lo].X; + int i = lo - 1; + int j = hi + 1; while (true) { - float x = data[left].X; do { - i++; + i = i + 1; } - while (data[i].X < x); + while (A[i].X < pivot); do { - j--; + j = j - 1; } - while (data[j].X > x); + while (A[j].X > pivot); - if (i < j) + if (i >= j) { - Vector2 tmp = data[i]; - data[i] = data[j]; - data[j] = tmp; + return j; } - else - { - if (left < j) - { - QuickSortX(data, left, j); - } - if (++j < right) - { - QuickSortX(data, j, right); - } - - return; - } + Swap(A, i, j); } } - private static void QuickSortY(Vector2[] data, int left, int right) + private static int PartitionY(Vector2[] A, int lo, int hi) { - int i = left - 1; - int j = right; - + float pivot = A[lo].Y; + int i = lo - 1; + int j = hi + 1; while (true) { - float d = data[left].Y; do { - i++; + i = i + 1; } - while (data[i].Y < d); + while (A[i].Y < pivot); do { - j--; + j = j - 1; } - while (data[j].Y > d); + while (A[j].Y > pivot); - if (i < j) + if (i >= j) { - Vector2 tmp = data[i]; - data[i] = data[j]; - data[j] = tmp; + return j; } - else - { - if (left < j) - { - QuickSortY(data, left, j); - } - if (++j < right) - { - QuickSortY(data, j, right); - } - - return; - } + Swap(A, i, j); } } } diff --git a/src/ImageSharp.Drawing/Shapes/ComplexPolygon.cs b/src/ImageSharp.Drawing/Shapes/ComplexPolygon.cs index 32de68fb9..98ce84608 100644 --- a/src/ImageSharp.Drawing/Shapes/ComplexPolygon.cs +++ b/src/ImageSharp.Drawing/Shapes/ComplexPolygon.cs @@ -125,7 +125,16 @@ namespace ImageSharp.Drawing.Shapes /// public int FindIntersections(Vector2 start, Vector2 end, Vector2[] buffer, int count, int offset) { - throw new NotImplementedException(); + int totalAdded = 0; + for (int i = 0; i < this.shapes.Length; i++) + { + int added = this.shapes[i].FindIntersections(start, end, buffer, count, offset); + count -= added; + offset += added; + totalAdded += added; + } + + return totalAdded; } /// diff --git a/tests/ImageSharp.Tests/Drawing/SolidBezierTests.cs b/tests/ImageSharp.Tests/Drawing/SolidBezierTests.cs index 43ed13b3c..f6bcf4906 100644 --- a/tests/ImageSharp.Tests/Drawing/SolidBezierTests.cs +++ b/tests/ImageSharp.Tests/Drawing/SolidBezierTests.cs @@ -19,7 +19,6 @@ namespace ImageSharp.Tests.Drawing [Fact] public void ImageShouldBeOverlayedByFilledPolygon() { - Configuration.Default.ParallelOptions.MaxDegreeOfParallelism = 1; string path = CreateOutputDirectory("Drawing", "FilledBezier"); var simplePath = new[] { new Vector2(10, 400), diff --git a/tests/ImageSharp.Tests/Drawing/SolidComplexPolygonTests.cs b/tests/ImageSharp.Tests/Drawing/SolidComplexPolygonTests.cs index dd4cbfd2b..cbd44d7d1 100644 --- a/tests/ImageSharp.Tests/Drawing/SolidComplexPolygonTests.cs +++ b/tests/ImageSharp.Tests/Drawing/SolidComplexPolygonTests.cs @@ -48,6 +48,8 @@ namespace ImageSharp.Tests.Drawing Assert.Equal(Color.HotPink, sourcePixels[50, 50]); + Assert.Equal(Color.HotPink, sourcePixels[35, 100]); + Assert.Equal(Color.Blue, sourcePixels[2, 2]); //inside hole @@ -88,6 +90,8 @@ namespace ImageSharp.Tests.Drawing Assert.Equal(Color.HotPink, sourcePixels[50, 50]); + Assert.Equal(Color.HotPink, sourcePixels[35, 100]); + Assert.Equal(Color.Blue, sourcePixels[2, 2]); //inside hole @@ -131,6 +135,8 @@ namespace ImageSharp.Tests.Drawing Assert.Equal(mergedColor, sourcePixels[50, 50]); + Assert.Equal(mergedColor, sourcePixels[35, 100]); + Assert.Equal(Color.Blue, sourcePixels[2, 2]); //inside hole