Browse Source

code cleanup and comments

pull/71/head
Scott Williams 9 years ago
parent
commit
086115fd78
  1. 72
      src/ImageSharp.Drawing/Paths/InternalPath.cs
  2. 2
      src/ImageSharp.Drawing/Processors/FillProcessor.cs
  3. 368
      src/ImageSharp.Drawing/Processors/FillShapeProcessor.cs
  4. 3
      src/ImageSharp.Drawing/Shapes/BezierPolygon.cs
  5. 28
      src/ImageSharp.Drawing/Shapes/ComplexPolygon.cs
  6. 3
      src/ImageSharp.Drawing/Shapes/IShape.cs
  7. 3
      src/ImageSharp.Drawing/Shapes/LinearPolygon.cs
  8. 5
      src/ImageSharp.Drawing/Shapes/Polygon.cs
  9. 8
      src/ImageSharp.Drawing/Shapes/RectangularPolygon.cs

72
src/ImageSharp.Drawing/Paths/InternalPath.cs

@ -169,7 +169,8 @@ namespace ImageSharp.Drawing.Paths
} }
/// <summary> /// <summary>
/// Finds the intersections. /// Based on a line described by <paramref name="start" /> and <paramref name="end" />
/// populate a buffer for all points on the path that the line intersects.
/// </summary> /// </summary>
/// <param name="start">The start.</param> /// <param name="start">The start.</param>
/// <param name="end">The end.</param> /// <param name="end">The end.</param>
@ -195,7 +196,7 @@ namespace ImageSharp.Drawing.Paths
next = 0; next = 0;
} }
var point = FindIntersection(this.points[i], this.points[next], start, end); Vector2 point = FindIntersection(this.points[i], this.points[next], start, end);
if (point != MaxVector) if (point != MaxVector)
{ {
buffer[position + offset] = point; buffer[position + offset] = point;
@ -208,7 +209,7 @@ namespace ImageSharp.Drawing.Paths
} }
/// <summary> /// <summary>
/// Points the in polygon. /// Determines if the specified point is inside or outside the path.
/// </summary> /// </summary>
/// <param name="point">The point.</param> /// <param name="point">The point.</param>
/// <returns>Returns true if the point is inside the closed path.</returns> /// <returns>Returns true if the point is inside the closed path.</returns>
@ -247,47 +248,67 @@ namespace ImageSharp.Drawing.Paths
return oddNodes; return oddNodes;
} }
/// <summary>
/// Determins if the bounding box for 2 lines
/// described by <paramref name="line1Start" /> and <paramref name="line1End" />
/// and <paramref name="line2Start" /> and <paramref name="line2End" /> overlap.
/// </summary>
/// <param name="line1Start">The line1 start.</param>
/// <param name="line1End">The line1 end.</param>
/// <param name="line2Start">The line2 start.</param>
/// <param name="line2End">The line2 end.</param>
/// <returns></returns>
private static bool BoundingBoxesIntersect(Vector2 line1Start, Vector2 line1End, Vector2 line2Start, Vector2 line2End) private static bool BoundingBoxesIntersect(Vector2 line1Start, Vector2 line1End, Vector2 line2Start, Vector2 line2End)
{ {
var topLeft1 = Vector2.Min(line1Start, line1End); Vector2 topLeft1 = Vector2.Min(line1Start, line1End);
var bottomRight1 = Vector2.Max(line1Start, line1End); Vector2 bottomRight1 = Vector2.Max(line1Start, line1End);
var topLeft2 = Vector2.Min(line2Start, line2End); Vector2 topLeft2 = Vector2.Min(line2Start, line2End);
var bottomRight2 = Vector2.Max(line2Start, line2End); Vector2 bottomRight2 = Vector2.Max(line2Start, line2End);
var left1 = topLeft1.X; float left1 = topLeft1.X;
var right1 = bottomRight1.X; float right1 = bottomRight1.X;
var top1 = topLeft1.Y; float top1 = topLeft1.Y;
var bottom1 = bottomRight1.Y; float bottom1 = bottomRight1.Y;
var left2 = topLeft2.X; float left2 = topLeft2.X;
var right2 = bottomRight2.X; float right2 = bottomRight2.X;
var top2 = topLeft2.Y; float top2 = topLeft2.Y;
var bottom2 = bottomRight2.Y; float bottom2 = bottomRight2.Y;
return left1 <= right2 && right1 >= left2 return left1 <= right2 && right1 >= left2
&& &&
top1 <= bottom2 && bottom1 >= top2; top1 <= bottom2 && bottom1 >= top2;
} }
/// <summary>
/// Finds the point on line described by <paramref name="line1Start" /> and <paramref name="line1End" />
/// that intersects with line described by <paramref name="line2Start" /> and <paramref name="line2End" />
/// </summary>
/// <param name="line1Start">The line1 start.</param>
/// <param name="line1End">The line1 end.</param>
/// <param name="line2Start">The line2 start.</param>
/// <param name="line2End">The line2 end.</param>
/// <returns>
/// A <see cref="Vector2"/> describing the point that the 2 lines cross or <see cref="MaxVector"/> if they do not.
/// </returns>
private static Vector2 FindIntersection(Vector2 line1Start, Vector2 line1End, Vector2 line2Start, Vector2 line2End) private static Vector2 FindIntersection(Vector2 line1Start, Vector2 line1End, Vector2 line2Start, Vector2 line2End)
{ {
// do lines cross at all // do bounding boxes overlap, if not then the lines can't and return fast.
if (!BoundingBoxesIntersect(line1Start, line1End, line2Start, line2End)) if (!BoundingBoxesIntersect(line1Start, line1End, line2Start, line2End))
{ {
return MaxVector; return MaxVector;
} }
var line1Diff = line1End - line1Start; Vector2 line1Diff = line1End - line1Start;
var line2Diff = line2End - line2Start; Vector2 line2Diff = line2End - line2Start;
Vector2 point; Vector2 point;
if (line1Diff.X == 0) if (line1Diff.X == 0)
{ {
float slope = line2Diff.Y / line2Diff.X; float slope = line2Diff.Y / line2Diff.X;
float yinter = line2Start.Y - (slope * line2Start.X);
var yinter = line2Start.Y - (slope * line2Start.X); float y = (line1Start.X * slope) + yinter;
var y = (line1Start.X * slope) + yinter;
point = new Vector2(line1Start.X, y); point = new Vector2(line1Start.X, y);
// horizontal and vertical lines // horizontal and vertical lines
@ -295,8 +316,8 @@ namespace ImageSharp.Drawing.Paths
else if (line2Diff.X == 0) else if (line2Diff.X == 0)
{ {
float slope = line1Diff.Y / line1Diff.X; float slope = line1Diff.Y / line1Diff.X;
var yinter = line1Start.Y - (slope * line1Start.X); float yinter = line1Start.Y - (slope * line1Start.X);
var y = (line2Start.X * slope) + yinter; float y = (line2Start.X * slope) + yinter;
point = new Vector2(line2Start.X, y); point = new Vector2(line2Start.X, y);
// horizontal and vertical lines // horizontal and vertical lines
@ -306,8 +327,8 @@ namespace ImageSharp.Drawing.Paths
float slope1 = line1Diff.Y / line1Diff.X; float slope1 = line1Diff.Y / line1Diff.X;
float slope2 = line2Diff.Y / line2Diff.X; float slope2 = line2Diff.Y / line2Diff.X;
var yinter1 = line1Start.Y - (slope1 * line1Start.X); float yinter1 = line1Start.Y - (slope1 * line1Start.X);
var yinter2 = line2Start.Y - (slope2 * line2Start.X); float yinter2 = line2Start.Y - (slope2 * line2Start.X);
if (slope1 == slope2 && yinter1 != yinter2) if (slope1 == slope2 && yinter1 != yinter2)
{ {
@ -315,7 +336,6 @@ namespace ImageSharp.Drawing.Paths
} }
float x = (yinter2 - yinter1) / (slope1 - slope2); float x = (yinter2 - yinter1) / (slope1 - slope2);
float y = (slope1 * x) + yinter1; float y = (slope1 * x) + yinter1;
point = new Vector2(x, y); point = new Vector2(x, y);

2
src/ImageSharp.Drawing/Processors/FillProcessor.cs

@ -83,7 +83,7 @@ namespace ImageSharp.Drawing.Processors
Vector4 backgroundVector = sourcePixels[offsetX, offsetY].ToVector4(); Vector4 backgroundVector = sourcePixels[offsetX, offsetY].ToVector4();
Vector4 sourceVector = applicator.GetColor(currentPoint).ToVector4(); Vector4 sourceVector = applicator.GetColor(currentPoint).ToVector4();
var finalColor = Vector4BlendTransforms.PremultipliedLerp(backgroundVector, sourceVector, 1); Vector4 finalColor = Vector4BlendTransforms.PremultipliedLerp(backgroundVector, sourceVector, 1);
TColor packed = default(TColor); TColor packed = default(TColor);
packed.PackFromVector4(finalColor); packed.PackFromVector4(finalColor);

368
src/ImageSharp.Drawing/Processors/FillShapeProcessor.cs

@ -75,151 +75,15 @@ namespace ImageSharp.Drawing.Processors
this.ParallelOptions, this.ParallelOptions,
y => y =>
{ {
var buffer = arrayPool.Rent(maxIntersections); Vector2[] buffer = arrayPool.Rent(maxIntersections);
var left = new Vector2(startX, y);
var right = new Vector2(endX, y);
// foreach line we get all the points where this line crosses the polygon try
var pointsFound = this.poly.FindIntersections(left, right, buffer, maxIntersections, 0);
if (pointsFound == 0)
{ {
arrayPool.Return(buffer); Vector2 left = new Vector2(startX, y);
Vector2 right = new Vector2(endX, y);
// nothign on this line skip
return;
}
QuickSortX(buffer, pointsFound);
int currentIntersection = 0;
float nextPoint = buffer[0].X;
float lastPoint = float.MinValue;
float targetPoint = nextPoint;
bool isInside = false;
// every odd point is the start of a line
Vector2 currentPoint = default(Vector2);
for (int x = minX; x < maxX; x++)
{
currentPoint.X = x;
currentPoint.Y = y;
if (!isInside)
{
if (x < (nextPoint - DrawPadding) && x > (lastPoint + DrawPadding))
{
if (nextPoint == right.X)
{
// we are in the ends run skip it
x = maxX;
continue;
}
// lets just jump forward
x = (int)Math.Floor(nextPoint) - DrawPadding;
}
}
bool onCorner = false;
// there seems to be some issue with this switch.
if (x >= nextPoint)
{
currentIntersection++;
lastPoint = nextPoint;
if (currentIntersection == pointsFound)
{
nextPoint = right.X;
}
else
{
nextPoint = buffer[currentIntersection].X;
// double point from a corner flip the bit back and move on again
if (nextPoint == lastPoint)
{
onCorner = true;
isInside ^= true;
currentIntersection++;
if (currentIntersection == pointsFound)
{
nextPoint = right.X;
}
else
{
nextPoint = buffer[currentIntersection].X;
}
}
}
isInside ^= true;
}
float opacity = 1;
if (!isInside && !onCorner)
{
if (this.options.Antialias)
{
float distance = float.MaxValue;
if (x == lastPoint || x == nextPoint)
{
// we are to far away from the line
distance = 0;
}
else if (nextPoint - AntialiasFactor < x)
{
// we are near the left of the line
distance = nextPoint - x;
}
else if (lastPoint + AntialiasFactor > x)
{
// we are near the right of the line
distance = x - lastPoint;
}
else
{
// we are to far away from the line
continue;
}
opacity = 1 - (distance / AntialiasFactor);
}
else
{
continue;
}
}
if (opacity > Constants.Epsilon)
{
Vector4 backgroundVector = sourcePixels[x, y].ToVector4();
Vector4 sourceVector = applicator.GetColor(currentPoint).ToVector4();
Vector4 finalColor = Vector4BlendTransforms.PremultipliedLerp(backgroundVector, sourceVector, opacity);
finalColor.W = backgroundVector.W;
TColor packed = default(TColor);
packed.PackFromVector4(finalColor);
sourcePixels[x, y] = packed;
}
}
arrayPool.Return(buffer);
});
if (this.options.Antialias)
{
// we only need to do the X can for antialiasing purposes
Parallel.For(
minX,
maxX,
this.ParallelOptions,
x =>
{
var buffer = arrayPool.Rent(maxIntersections);
var left = new Vector2(x, polyStartY);
var right = new Vector2(x, polyEndY);
// foreach line we get all the points where this line crosses the polygon // foreach line we get all the points where this line crosses the polygon
var pointsFound = this.poly.FindIntersections(left, right, buffer, maxIntersections, 0); int pointsFound = this.poly.FindIntersections(left, right, buffer, maxIntersections, 0);
if (pointsFound == 0) if (pointsFound == 0)
{ {
arrayPool.Return(buffer); arrayPool.Return(buffer);
@ -228,65 +92,50 @@ namespace ImageSharp.Drawing.Processors
return; return;
} }
QuickSortY(buffer, pointsFound); QuickSortX(buffer, pointsFound);
int currentIntersection = 0; int currentIntersection = 0;
float nextPoint = buffer[0].Y; float nextPoint = buffer[0].X;
float lastPoint = left.Y; float lastPoint = float.MinValue;
float targetPoint = nextPoint;
bool isInside = false; bool isInside = false;
// every odd point is the start of a line // every odd point is the start of a line
Vector2 currentPoint = default(Vector2); Vector2 currentPoint = default(Vector2);
for (int y = minY; y < maxY; y++) for (int x = minX; x < maxX; x++)
{ {
currentPoint.X = x; currentPoint.X = x;
currentPoint.Y = y; currentPoint.Y = y;
if (!isInside) if (!isInside)
{ {
if (y < (nextPoint - DrawPadding) && y > (lastPoint + DrawPadding)) if (x < (nextPoint - DrawPadding) && x > (lastPoint + DrawPadding))
{
if (nextPoint == right.Y)
{
// we are in the ends run skip it
y = maxY;
continue;
}
// lets just jump forward
y = (int)Math.Floor(nextPoint) - DrawPadding;
}
}
else
{
if (y < nextPoint - DrawPadding)
{ {
if (nextPoint == right.Y) if (nextPoint == right.X)
{ {
// we are in the ends run skip it // we are in the ends run skip it
y = maxY; x = maxX;
continue; continue;
} }
// lets just jump forward // lets just jump forward
y = (int)Math.Floor(nextPoint); x = (int)Math.Floor(nextPoint) - DrawPadding;
} }
} }
bool onCorner = false; bool onCorner = false;
if (y >= nextPoint) // there seems to be some issue with this switch.
if (x >= nextPoint)
{ {
currentIntersection++; currentIntersection++;
lastPoint = nextPoint; lastPoint = nextPoint;
if (currentIntersection == pointsFound) if (currentIntersection == pointsFound)
{ {
nextPoint = right.Y; nextPoint = right.X;
} }
else else
{ {
nextPoint = buffer[currentIntersection].Y; nextPoint = buffer[currentIntersection].X;
// double point from a corner flip the bit back and move on again // double point from a corner flip the bit back and move on again
if (nextPoint == lastPoint) if (nextPoint == lastPoint)
@ -296,11 +145,11 @@ namespace ImageSharp.Drawing.Processors
currentIntersection++; currentIntersection++;
if (currentIntersection == pointsFound) if (currentIntersection == pointsFound)
{ {
nextPoint = right.Y; nextPoint = right.X;
} }
else else
{ {
nextPoint = buffer[currentIntersection].Y; nextPoint = buffer[currentIntersection].X;
} }
} }
} }
@ -314,20 +163,20 @@ namespace ImageSharp.Drawing.Processors
if (this.options.Antialias) if (this.options.Antialias)
{ {
float distance = float.MaxValue; float distance = float.MaxValue;
if (y == lastPoint || y == nextPoint) if (x == lastPoint || x == nextPoint)
{ {
// we are to far away from the line // we are to far away from the line
distance = 0; distance = 0;
} }
else if (nextPoint - AntialiasFactor < y) else if (nextPoint - AntialiasFactor < x)
{ {
// we are near the left of the line // we are near the left of the line
distance = nextPoint - y; distance = nextPoint - x;
} }
else if (lastPoint + AntialiasFactor > y) else if (lastPoint + AntialiasFactor > x)
{ {
// we are near the right of the line // we are near the right of the line
distance = y - lastPoint; distance = x - lastPoint;
} }
else else
{ {
@ -342,8 +191,7 @@ namespace ImageSharp.Drawing.Processors
} }
} }
// don't set full opactiy color as it will have been gotten by the first scan if (opacity > Constants.Epsilon)
if (opacity > Constants.Epsilon && opacity < 1)
{ {
Vector4 backgroundVector = sourcePixels[x, y].ToVector4(); Vector4 backgroundVector = sourcePixels[x, y].ToVector4();
Vector4 sourceVector = applicator.GetColor(currentPoint).ToVector4(); Vector4 sourceVector = applicator.GetColor(currentPoint).ToVector4();
@ -356,8 +204,172 @@ namespace ImageSharp.Drawing.Processors
sourcePixels[x, y] = packed; sourcePixels[x, y] = packed;
} }
} }
}
finally
{
arrayPool.Return(buffer); arrayPool.Return(buffer);
}
});
if (this.options.Antialias)
{
// we only need to do the X can for antialiasing purposes
Parallel.For(
minX,
maxX,
this.ParallelOptions,
x =>
{
Vector2[] buffer = arrayPool.Rent(maxIntersections);
try
{
Vector2 left = new Vector2(x, polyStartY);
Vector2 right = new Vector2(x, polyEndY);
// foreach line we get all the points where this line crosses the polygon
int pointsFound = this.poly.FindIntersections(left, right, buffer, maxIntersections, 0);
if (pointsFound == 0)
{
arrayPool.Return(buffer);
// nothign on this line skip
return;
}
QuickSortY(buffer, pointsFound);
int currentIntersection = 0;
float nextPoint = buffer[0].Y;
float lastPoint = left.Y;
bool isInside = false;
// every odd point is the start of a line
Vector2 currentPoint = default(Vector2);
for (int y = minY; y < maxY; y++)
{
currentPoint.X = x;
currentPoint.Y = y;
if (!isInside)
{
if (y < (nextPoint - DrawPadding) && y > (lastPoint + DrawPadding))
{
if (nextPoint == right.Y)
{
// we are in the ends run skip it
y = maxY;
continue;
}
// lets just jump forward
y = (int)Math.Floor(nextPoint) - DrawPadding;
}
}
else
{
if (y < nextPoint - DrawPadding)
{
if (nextPoint == right.Y)
{
// we are in the ends run skip it
y = maxY;
continue;
}
// lets just jump forward
y = (int)Math.Floor(nextPoint);
}
}
bool onCorner = false;
if (y >= nextPoint)
{
currentIntersection++;
lastPoint = nextPoint;
if (currentIntersection == pointsFound)
{
nextPoint = right.Y;
}
else
{
nextPoint = buffer[currentIntersection].Y;
// double point from a corner flip the bit back and move on again
if (nextPoint == lastPoint)
{
onCorner = true;
isInside ^= true;
currentIntersection++;
if (currentIntersection == pointsFound)
{
nextPoint = right.Y;
}
else
{
nextPoint = buffer[currentIntersection].Y;
}
}
}
isInside ^= true;
}
float opacity = 1;
if (!isInside && !onCorner)
{
if (this.options.Antialias)
{
float distance = float.MaxValue;
if (y == lastPoint || y == nextPoint)
{
// we are to far away from the line
distance = 0;
}
else if (nextPoint - AntialiasFactor < y)
{
// we are near the left of the line
distance = nextPoint - y;
}
else if (lastPoint + AntialiasFactor > y)
{
// we are near the right of the line
distance = y - lastPoint;
}
else
{
// we are to far away from the line
continue;
}
opacity = 1 - (distance / AntialiasFactor);
}
else
{
continue;
}
}
// don't set full opactiy color as it will have been gotten by the first scan
if (opacity > Constants.Epsilon && opacity < 1)
{
Vector4 backgroundVector = sourcePixels[x, y].ToVector4();
Vector4 sourceVector = applicator.GetColor(currentPoint).ToVector4();
Vector4 finalColor = Vector4BlendTransforms.PremultipliedLerp(backgroundVector, sourceVector, opacity);
finalColor.W = backgroundVector.W;
TColor packed = default(TColor);
packed.PackFromVector4(finalColor);
sourcePixels[x, y] = packed;
}
}
}
finally
{
arrayPool.Return(buffer);
}
}); });
} }
} }

3
src/ImageSharp.Drawing/Shapes/BezierPolygon.cs

@ -52,7 +52,8 @@ namespace ImageSharp.Drawing.Shapes
public float Distance(Vector2 point) => this.innerPolygon.Distance(point); public float Distance(Vector2 point) => this.innerPolygon.Distance(point);
/// <summary> /// <summary>
/// Finds the intersections. /// Based on a line described by <paramref name="start"/> and <paramref name="end"/>
/// populate a buffer for all points on the polygon that the line intersects.
/// </summary> /// </summary>
/// <param name="start">The start point of the line.</param> /// <param name="start">The start point of the line.</param>
/// <param name="end">The end point of the line.</param> /// <param name="end">The end point of the line.</param>

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

@ -47,10 +47,10 @@ namespace ImageSharp.Drawing.Shapes
this.MaxIntersections = this.FixAndSetShapes(outlines, holes); this.MaxIntersections = this.FixAndSetShapes(outlines, holes);
var minX = this.shapes.Min(x => x.Bounds.Left); float minX = this.shapes.Min(x => x.Bounds.Left);
var maxX = this.shapes.Max(x => x.Bounds.Right); float maxX = this.shapes.Max(x => x.Bounds.Right);
var minY = this.shapes.Min(x => x.Bounds.Top); float minY = this.shapes.Min(x => x.Bounds.Top);
var maxY = this.shapes.Max(x => x.Bounds.Bottom); float maxY = this.shapes.Max(x => x.Bounds.Bottom);
this.Bounds = new RectangleF(minX, minY, maxX - minX, maxY - minY); this.Bounds = new RectangleF(minX, minY, maxX - minX, maxY - minY);
} }
@ -89,7 +89,7 @@ namespace ImageSharp.Drawing.Shapes
bool inside = false; bool inside = false;
foreach (IShape shape in this.shapes) foreach (IShape shape in this.shapes)
{ {
var d = shape.Distance(point); float d = shape.Distance(point);
if (d <= 0) if (d <= 0)
{ {
@ -113,7 +113,9 @@ namespace ImageSharp.Drawing.Shapes
} }
/// <summary> /// <summary>
/// Finds the intersections. /// Based on a line described by <paramref name="start"/> and <paramref name="end"/>
/// populate a buffer for all points on all the polygons, that make up this complex shape,
/// that the line intersects.
/// </summary> /// </summary>
/// <param name="start">The start point of the line.</param> /// <param name="start">The start point of the line.</param>
/// <param name="end">The end point of the line.</param> /// <param name="end">The end point of the line.</param>
@ -170,7 +172,7 @@ namespace ImageSharp.Drawing.Shapes
} }
else else
{ {
foreach (var path in shape) foreach (IPath path in shape)
{ {
clipper.AddPath( clipper.AddPath(
path, path,
@ -181,7 +183,7 @@ namespace ImageSharp.Drawing.Shapes
private void AddPoints(Clipper clipper, IEnumerable<IShape> shapes, PolyType polyType) private void AddPoints(Clipper clipper, IEnumerable<IShape> shapes, PolyType polyType)
{ {
foreach (var shape in shapes) foreach (IShape shape in shapes)
{ {
this.AddPoints(clipper, shape, polyType); this.AddPoints(clipper, shape, polyType);
} }
@ -201,14 +203,14 @@ namespace ImageSharp.Drawing.Shapes
else else
{ {
// convert the Clipper Contour from scaled ints back down to the origional size (this is going to be lossy but not significantly) // convert the Clipper Contour from scaled ints back down to the origional size (this is going to be lossy but not significantly)
var polygon = new Polygon(new Paths.LinearLineSegment(tree.Contour.ToArray())); Polygon polygon = new Polygon(new Paths.LinearLineSegment(tree.Contour.ToArray()));
shapes.Add(polygon); shapes.Add(polygon);
paths.Add(polygon); paths.Add(polygon);
} }
} }
foreach (var c in tree.Children) foreach (PolyNode c in tree.Children)
{ {
this.ExtractOutlines(c, shapes, paths); this.ExtractOutlines(c, shapes, paths);
} }
@ -216,13 +218,13 @@ namespace ImageSharp.Drawing.Shapes
private int FixAndSetShapes(IEnumerable<IShape> outlines, IEnumerable<IShape> holes) private int FixAndSetShapes(IEnumerable<IShape> outlines, IEnumerable<IShape> holes)
{ {
var clipper = new Clipper(); Clipper clipper = new Clipper();
// add the outlines and the holes to clipper, scaling up from the float source to the int based system clipper uses // add the outlines and the holes to clipper, scaling up from the float source to the int based system clipper uses
this.AddPoints(clipper, outlines, PolyType.Subject); this.AddPoints(clipper, outlines, PolyType.Subject);
this.AddPoints(clipper, holes, PolyType.Clip); this.AddPoints(clipper, holes, PolyType.Clip);
var tree = clipper.Execute(); PolyTree tree = clipper.Execute();
List<IShape> shapes = new List<IShape>(); List<IShape> shapes = new List<IShape>();
List<IPath> paths = new List<IPath>(); List<IPath> paths = new List<IPath>();
@ -233,7 +235,7 @@ namespace ImageSharp.Drawing.Shapes
this.paths = paths.ToArray(); this.paths = paths.ToArray();
int intersections = 0; int intersections = 0;
foreach (var s in this.shapes) foreach (IShape s in this.shapes)
{ {
intersections += s.MaxIntersections; intersections += s.MaxIntersections;
} }

3
src/ImageSharp.Drawing/Shapes/IShape.cs

@ -40,7 +40,8 @@ namespace ImageSharp.Drawing.Shapes
float Distance(Vector2 point); float Distance(Vector2 point);
/// <summary> /// <summary>
/// Finds the intersections. /// Based on a line described by <paramref name="start"/> and <paramref name="end"/>
/// populate a buffer for all points on the polygon that the line intersects.
/// </summary> /// </summary>
/// <param name="start">The start point of the line.</param> /// <param name="start">The start point of the line.</param>
/// <param name="end">The end point of the line.</param> /// <param name="end">The end point of the line.</param>

3
src/ImageSharp.Drawing/Shapes/LinearPolygon.cs

@ -58,7 +58,8 @@ namespace ImageSharp.Drawing.Shapes
public float Distance(Vector2 point) => this.innerPolygon.Distance(point); public float Distance(Vector2 point) => this.innerPolygon.Distance(point);
/// <summary> /// <summary>
/// Finds the intersections. /// Based on a line described by <paramref name="start"/> and <paramref name="end"/>
/// populate a buffer for all points on the polygon that the line intersects.
/// </summary> /// </summary>
/// <param name="start">The start point of the line.</param> /// <param name="start">The start point of the line.</param>
/// <param name="end">The end point of the line.</param> /// <param name="end">The end point of the line.</param>

5
src/ImageSharp.Drawing/Shapes/Polygon.cs

@ -82,7 +82,7 @@ namespace ImageSharp.Drawing.Shapes
{ {
bool isInside = this.innerPath.PointInPolygon(point); bool isInside = this.innerPath.PointInPolygon(point);
var distance = this.innerPath.DistanceFromPath(point).DistanceFromPath; float distance = this.innerPath.DistanceFromPath(point).DistanceFromPath;
if (isInside) if (isInside)
{ {
return -distance; return -distance;
@ -137,7 +137,8 @@ namespace ImageSharp.Drawing.Shapes
} }
/// <summary> /// <summary>
/// Finds the intersections. /// Based on a line described by <paramref name="start" /> and <paramref name="end" />
/// populate a buffer for all points on the polygon that the line intersects.
/// </summary> /// </summary>
/// <param name="start">The start point of the line.</param> /// <param name="start">The start point of the line.</param>
/// <param name="end">The end point of the line.</param> /// <param name="end">The end point of the line.</param>

8
src/ImageSharp.Drawing/Shapes/RectangularPolygon.cs

@ -110,7 +110,7 @@ namespace ImageSharp.Drawing.Shapes
public float Distance(Vector2 point) public float Distance(Vector2 point)
{ {
bool insidePoly; bool insidePoly;
var result = this.Distance(point, true, out insidePoly); PointInfo result = this.Distance(point, true, out insidePoly);
// invert the distance from path when inside // invert the distance from path when inside
return insidePoly ? -result.DistanceFromPath : result.DistanceFromPath; return insidePoly ? -result.DistanceFromPath : result.DistanceFromPath;
@ -150,7 +150,9 @@ namespace ImageSharp.Drawing.Shapes
} }
/// <summary> /// <summary>
/// Finds the intersections. /// Based on a line described by <paramref name="start"/> and <paramref name="end"/>
/// populate a buffer for all points on the edges of the <see cref="RectangularPolygon"/>
/// that the line intersects.
/// </summary> /// </summary>
/// <param name="start">The start point of the line.</param> /// <param name="start">The start point of the line.</param>
/// <param name="end">The end point of the line.</param> /// <param name="end">The end point of the line.</param>
@ -162,7 +164,7 @@ namespace ImageSharp.Drawing.Shapes
/// </returns> /// </returns>
public int FindIntersections(Vector2 start, Vector2 end, Vector2[] buffer, int count, int offset) public int FindIntersections(Vector2 start, Vector2 end, Vector2[] buffer, int count, int offset)
{ {
var discovered = 0; int discovered = 0;
Vector2 startPoint = Vector2.Clamp(start, this.topLeft, this.bottomRight); Vector2 startPoint = Vector2.Clamp(start, this.topLeft, this.bottomRight);
Vector2 endPoint = Vector2.Clamp(end, this.topLeft, this.bottomRight); Vector2 endPoint = Vector2.Clamp(end, this.topLeft, this.bottomRight);

Loading…
Cancel
Save