Browse Source

Fix complex polygon fill

pull/71/head
Scott Williams 9 years ago
parent
commit
e443a60beb
  1. 117
      src/ImageSharp.Drawing/Processors/FillShapeProcessor.cs
  2. 11
      src/ImageSharp.Drawing/Shapes/ComplexPolygon.cs
  3. 1
      tests/ImageSharp.Tests/Drawing/SolidBezierTests.cs
  4. 6
      tests/ImageSharp.Tests/Drawing/SolidComplexPolygonTests.cs

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

11
src/ImageSharp.Drawing/Shapes/ComplexPolygon.cs

@ -125,7 +125,16 @@ namespace ImageSharp.Drawing.Shapes
/// </returns>
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;
}
/// <summary>

1
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),

6
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

Loading…
Cancel
Save