Browse Source

Merge branch 'refs/heads/pr/52'

af/merge-core
James Jackson-South 9 years ago
parent
commit
aafe5d2adf
  1. 4924
      src/ImageSharp/Drawing/Shapes/Clipper.cs
  2. 165
      src/ImageSharp/Drawing/Shapes/ComplexPolygon.cs
  3. 3860
      src/ImageSharp/Drawing/Shapes/PolygonClipper/Clipper.cs
  4. 31
      src/ImageSharp/Drawing/Shapes/PolygonClipper/ClipperException.cs
  5. 31
      src/ImageSharp/Drawing/Shapes/PolygonClipper/Direction.cs
  6. 31
      src/ImageSharp/Drawing/Shapes/PolygonClipper/EdgeSide.cs
  7. 38
      src/ImageSharp/Drawing/Shapes/PolygonClipper/IntersectNode.cs
  8. 48
      src/ImageSharp/Drawing/Shapes/PolygonClipper/IntersectNodeSort.cs
  9. 38
      src/ImageSharp/Drawing/Shapes/PolygonClipper/Join.cs
  10. 44
      src/ImageSharp/Drawing/Shapes/PolygonClipper/LocalMinima.cs
  11. 38
      src/ImageSharp/Drawing/Shapes/PolygonClipper/Maxima.cs
  12. 43
      src/ImageSharp/Drawing/Shapes/PolygonClipper/OutPt.cs
  13. 64
      src/ImageSharp/Drawing/Shapes/PolygonClipper/OutRec.cs
  14. 179
      src/ImageSharp/Drawing/Shapes/PolygonClipper/PolyNode.cs
  15. 81
      src/ImageSharp/Drawing/Shapes/PolygonClipper/PolyTree.cs
  16. 31
      src/ImageSharp/Drawing/Shapes/PolygonClipper/PolyType.cs
  17. 40
      src/ImageSharp/Drawing/Shapes/PolygonClipper/README.md
  18. 33
      src/ImageSharp/Drawing/Shapes/PolygonClipper/Scanbeam.cs
  19. 118
      src/ImageSharp/Drawing/Shapes/PolygonClipper/TEdge.cs

4924
src/ImageSharp/Drawing/Shapes/Clipper.cs

File diff suppressed because it is too large

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

@ -11,6 +11,7 @@ namespace ImageSharp.Drawing.Shapes
using System.Numerics;
using Paths;
using PolygonClipper;
/// <summary>
/// Represents a complex polygon made up of one or more outline
@ -124,156 +125,78 @@ namespace ImageSharp.Drawing.Shapes
return this.GetEnumerator();
}
private void AddPoints(ClipperLib.Clipper clipper, IShape shape, ClipperLib.PolyType polyType)
private void AddPoints(Clipper clipper, IShape shape, PolyType polyType)
{
foreach (var path in shape)
// if the path is already the shape use it directly and skip the path loop.
if (shape is IPath)
{
var points = path.AsSimpleLinearPath();
var clipperPoints = new List<ClipperLib.IntPoint>();
foreach (var point in points)
{
var p = point * ClipperScaleFactor;
clipperPoints.Add(new ClipperLib.IntPoint((long)p.X, (long)p.Y));
}
clipper.AddPath(
clipperPoints,
polyType,
path.IsClosed);
(IPath)shape,
polyType);
}
}
private void AddPoints(ClipperLib.Clipper clipper, IShape[] shapes, bool[] shouldInclude, ClipperLib.PolyType polyType)
{
for (var i = 0; i < shapes.Length; i++)
else
{
if (shouldInclude[i])
foreach (var path in shape)
{
this.AddPoints(clipper, shapes[i], polyType);
clipper.AddPath(
path,
polyType);
}
}
}
private void ExtractOutlines(ClipperLib.PolyNode tree, List<IShape> shapes)
private void AddPoints(Clipper clipper, IEnumerable<IShape> shapes, PolyType polyType)
{
if (tree.Contour.Any())
foreach (var shape in shapes)
{
// convert the Clipper Contour from scaled ints back down to the origional size (this is going to be lossy but not significantly)
var pointCount = tree.Contour.Count;
var vectors = new Vector2[pointCount];
for (var i = 0; i < pointCount; i++)
{
var p = tree.Contour[i];
vectors[i] = new Vector2(p.X, p.Y) / ClipperScaleFactor;
}
var polygon = new Polygon(new LinearLineSegment(vectors));
shapes.Add(polygon);
}
foreach (var c in tree.Childs)
{
this.ExtractOutlines(c, shapes);
this.AddPoints(clipper, shape, polyType);
}
}
/// <summary>
/// Determines if the <see cref="IShape"/>s bounding boxes overlap.
/// </summary>
/// <param name="source">The source.</param>
/// <param name="target">The target.</param>
/// <returns>true if the 2 shapes bounding boxes overlap.</returns>
private bool OverlappingBoundingBoxes(IShape source, IShape target)
{
return source.Bounds.Intersects(target.Bounds);
}
private void FixAndSetShapes(IShape[] outlines, IShape[] holes)
private void ExtractOutlines(PolyNode tree, List<IShape> shapes, List<IPath> paths)
{
// if any outline doesn't overlap another shape then we don't have to bother with sending them through clipper
// as sending then though clipper will turn them into generic polygons and loose thier shape specific optimisations
int outlineLength = outlines.Length;
int holesLength = holes?.Length ?? 0;
bool[] overlappingOutlines = new bool[outlineLength];
bool[] overlappingHoles = new bool[holesLength];
bool anyOutlinesOverlapping = false;
bool anyHolesOverlapping = false;
for (int i = 0; i < outlineLength; i++)
if (tree.Contour.Any())
{
for (int j = i + 1; j < outlineLength; j++)
// if the source path is set then we clipper retained the full path intact thus we can freely
// use it and get any shape optimisations that are availible.
if (tree.SourcePath != null)
{
// skip the bounds check if they are already tested
if (overlappingOutlines[i] == false || overlappingOutlines[j] == false)
{
if (this.OverlappingBoundingBoxes(outlines[i], outlines[j]))
{
overlappingOutlines[i] = true;
overlappingOutlines[j] = true;
anyOutlinesOverlapping = true;
}
}
shapes.Add((IShape)tree.SourcePath);
paths.Add(tree.SourcePath);
}
for (int k = 0; k < holesLength; k++)
else
{
if (overlappingOutlines[i] == false || overlappingHoles[k] == false)
{
if (this.OverlappingBoundingBoxes(outlines[i], holes[k]))
{
overlappingOutlines[i] = true;
overlappingHoles[k] = true;
anyOutlinesOverlapping = true;
anyHolesOverlapping = true;
}
}
// 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()));
shapes.Add(polygon);
paths.Add(polygon);
}
}
if (anyOutlinesOverlapping)
foreach (var c in tree.Children)
{
var clipper = new ClipperLib.Clipper();
// 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, overlappingOutlines, ClipperLib.PolyType.ptSubject);
if (anyHolesOverlapping)
{
this.AddPoints(clipper, holes, overlappingHoles, ClipperLib.PolyType.ptClip);
}
var tree = new ClipperLib.PolyTree();
clipper.Execute(ClipperLib.ClipType.ctDifference, tree);
List<IShape> newShapes = new List<IShape>();
this.ExtractOutlines(c, shapes, paths);
}
}
// convert the 'tree' back to shapes
this.ExtractOutlines(tree, newShapes);
private void FixAndSetShapes(IEnumerable<IShape> outlines, IEnumerable<IShape> holes)
{
var clipper = new Clipper();
// add the origional outlines that where not overlapping
for (int i = 0; i < outlineLength - 1; i++)
{
if (!overlappingOutlines[i])
{
newShapes.Add(outlines[i]);
}
}
// 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, holes, PolyType.Clip);
this.shapes = newShapes.ToArray();
}
else
{
this.shapes = outlines;
}
var tree = clipper.Execute();
var paths = new List<IPath>();
foreach (var o in this.shapes)
{
paths.AddRange(o);
}
List<IShape> shapes = new List<IShape>();
List<IPath> paths = new List<IPath>();
this.paths = paths;
// convert the 'tree' back to paths
this.ExtractOutlines(tree, shapes, paths);
this.shapes = shapes.ToArray();
this.paths = paths.ToArray();
}
}
}

3860
src/ImageSharp/Drawing/Shapes/PolygonClipper/Clipper.cs

File diff suppressed because it is too large

31
src/ImageSharp/Drawing/Shapes/PolygonClipper/ClipperException.cs

@ -0,0 +1,31 @@
// <copyright file="ClipperException.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp.Drawing.Shapes.PolygonClipper
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Runtime.CompilerServices;
using Paths;
/// <summary>
/// Clipper Exception
/// </summary>
/// <seealso cref="System.Exception" />
internal class ClipperException : Exception
{
/// <summary>
/// Initializes a new instance of the <see cref="ClipperException"/> class.
/// </summary>
/// <param name="description">The description.</param>
public ClipperException(string description)
: base(description)
{
}
}
}

31
src/ImageSharp/Drawing/Shapes/PolygonClipper/Direction.cs

@ -0,0 +1,31 @@
// <copyright file="Direction.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp.Drawing.Shapes.PolygonClipper
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Runtime.CompilerServices;
using Paths;
/// <summary>
/// ???
/// </summary>
internal enum Direction
{
/// <summary>
/// The right to left
/// </summary>
RightToLeft,
/// <summary>
/// The left to right
/// </summary>
LeftToRight
}
}

31
src/ImageSharp/Drawing/Shapes/PolygonClipper/EdgeSide.cs

@ -0,0 +1,31 @@
// <copyright file="EdgeSide.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp.Drawing.Shapes.PolygonClipper
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Runtime.CompilerServices;
using Paths;
/// <summary>
/// ??
/// </summary>
internal enum EdgeSide
{
/// <summary>
/// The left
/// </summary>
Left,
/// <summary>
/// The right
/// </summary>
Right
}
}

38
src/ImageSharp/Drawing/Shapes/PolygonClipper/IntersectNode.cs

@ -0,0 +1,38 @@
// <copyright file="IntersectNode.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp.Drawing.Shapes.PolygonClipper
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Runtime.CompilerServices;
using Paths;
/// <summary>
/// ??
/// </summary>
internal class IntersectNode
{
#pragma warning disable SA1401 // Field must be private
/// <summary>
/// The edge1
/// </summary>
internal TEdge Edge1;
/// <summary>
/// The edge2
/// </summary>
internal TEdge Edge2;
/// <summary>
/// The pt
/// </summary>
internal System.Numerics.Vector2 Pt;
#pragma warning restore SA1401 // Field must be private
}
}

48
src/ImageSharp/Drawing/Shapes/PolygonClipper/IntersectNodeSort.cs

@ -0,0 +1,48 @@
// <copyright file="IntersectNodeSort.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp.Drawing.Shapes.PolygonClipper
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Runtime.CompilerServices;
using Paths;
/// <summary>
/// Compares <see cref="IntersectNode"/>s
/// </summary>
internal class IntersectNodeSort : IComparer<IntersectNode>
{
/// <summary>
/// Compares the specified node1.
/// </summary>
/// <param name="node1">The node1.</param>
/// <param name="node2">The node2.</param>
/// <returns>
/// 1 if node2 %gt; node1
/// -1 if node2 $lt; node1
/// 0 if same
/// </returns>
public int Compare(IntersectNode node1, IntersectNode node2)
{
float i = node2.Pt.Y - node1.Pt.Y;
if (i > 0)
{
return 1;
}
else if (i < 0)
{
return -1;
}
else
{
return 0;
}
}
}
}

38
src/ImageSharp/Drawing/Shapes/PolygonClipper/Join.cs

@ -0,0 +1,38 @@
// <copyright file="Join.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp.Drawing.Shapes.PolygonClipper
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Runtime.CompilerServices;
using Paths;
/// <summary>
/// ??
/// </summary>
internal class Join
{
#pragma warning disable SA1401 // Field must be private
/// <summary>
/// The out PT1
/// </summary>
internal OutPt OutPt1;
/// <summary>
/// The out PT2
/// </summary>
internal OutPt OutPt2;
/// <summary>
/// The off pt
/// </summary>
internal System.Numerics.Vector2 OffPt;
#pragma warning restore SA1401 // Field must be private
}
}

44
src/ImageSharp/Drawing/Shapes/PolygonClipper/LocalMinima.cs

@ -0,0 +1,44 @@
// <copyright file="LocalMinima.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp.Drawing.Shapes.PolygonClipper
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Runtime.CompilerServices;
using Paths;
/// <summary>
/// ??
/// </summary>
internal class LocalMinima
{
#pragma warning disable SA1401 // Field must be private
/// <summary>
/// The y
/// </summary>
internal float Y;
/// <summary>
/// The left bound
/// </summary>
internal TEdge LeftBound;
/// <summary>
/// The right bound
/// </summary>
internal TEdge RightBound;
/// <summary>
/// The next
/// </summary>
internal LocalMinima Next;
#pragma warning restore SA1401 // Field must be private
}
}

38
src/ImageSharp/Drawing/Shapes/PolygonClipper/Maxima.cs

@ -0,0 +1,38 @@
// <copyright file="Maxima.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp.Drawing.Shapes.PolygonClipper
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Runtime.CompilerServices;
using Paths;
/// <summary>
/// ??
/// </summary>
internal class Maxima
{
#pragma warning disable SA1401 // Field must be private
/// <summary>
/// The x
/// </summary>
internal float X;
/// <summary>
/// The next
/// </summary>
internal Maxima Next;
/// <summary>
/// The previous
/// </summary>
internal Maxima Prev;
#pragma warning restore SA1401 // Field must be private
}
}

43
src/ImageSharp/Drawing/Shapes/PolygonClipper/OutPt.cs

@ -0,0 +1,43 @@
// <copyright file="OutPt.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp.Drawing.Shapes.PolygonClipper
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Runtime.CompilerServices;
using Paths;
/// <summary>
/// ??
/// </summary>
internal class OutPt
{
#pragma warning disable SA1401 // Field must be private
/// <summary>
/// The index
/// </summary>
internal int Idx;
/// <summary>
/// The pt
/// </summary>
internal System.Numerics.Vector2 Pt;
/// <summary>
/// The next
/// </summary>
internal OutPt Next;
/// <summary>
/// The previous
/// </summary>
internal OutPt Prev;
#pragma warning restore SA1401 // Field must be private
}
}

64
src/ImageSharp/Drawing/Shapes/PolygonClipper/OutRec.cs

@ -0,0 +1,64 @@
// <copyright file="OutRec.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp.Drawing.Shapes.PolygonClipper
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Runtime.CompilerServices;
using Paths;
/// <summary>
/// OutRec: contains a path in the clipping solution. Edges in the AEL will
/// carry a pointer to an OutRec when they are part of the clipping solution.
/// </summary>
internal class OutRec
{
#pragma warning disable SA1401 // Field must be private
/// <summary>
/// The source path
/// </summary>
internal IPath SourcePath;
/// <summary>
/// The index
/// </summary>
internal int Idx;
/// <summary>
/// The is hole
/// </summary>
internal bool IsHole;
/// <summary>
/// The is open
/// </summary>
internal bool IsOpen;
/// <summary>
/// The first left
/// </summary>
internal OutRec FirstLeft;
/// <summary>
/// The PTS
/// </summary>
internal OutPt Pts;
/// <summary>
/// The bottom pt
/// </summary>
internal OutPt BottomPt;
/// <summary>
/// The poly node
/// </summary>
internal PolyNode PolyNode;
#pragma warning restore SA1401 // Field must be private
}
}

179
src/ImageSharp/Drawing/Shapes/PolygonClipper/PolyNode.cs

@ -0,0 +1,179 @@
// <copyright file="PolyNode.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp.Drawing.Shapes.PolygonClipper
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Runtime.CompilerServices;
using Paths;
/// <summary>
/// Poly Node
/// </summary>
internal class PolyNode
{
#pragma warning disable SA1401 // Field must be private
/// <summary>
/// The polygon
/// </summary>
internal List<Vector2> Polygon = new List<Vector2>();
/// <summary>
/// The index
/// </summary>
internal int Index;
/// <summary>
/// The childs
/// </summary>
protected List<PolyNode> children = new List<PolyNode>();
private PolyNode parent;
#pragma warning restore SA1401 // Field must be private
/// <summary>
/// Gets the child count.
/// </summary>
/// <value>
/// The child count.
/// </value>
public int ChildCount
{
get { return this.children.Count; }
}
/// <summary>
/// Gets the contour.
/// </summary>
/// <value>
/// The contour.
/// </value>
public List<Vector2> Contour
{
get { return this.Polygon; }
}
/// <summary>
/// Gets the childs.
/// </summary>
/// <value>
/// The childs.
/// </value>
public List<PolyNode> Children
{
get { return this.children; }
}
/// <summary>
/// Gets or sets the parent.
/// </summary>
/// <value>
/// The parent.
/// </value>
public PolyNode Parent
{
get { return this.parent; }
internal set { this.parent = value; }
}
/// <summary>
/// Gets a value indicating whether this instance is hole.
/// </summary>
/// <value>
/// <c>true</c> if this instance is hole; otherwise, <c>false</c>.
/// </value>
public bool IsHole
{
get { return this.IsHoleNode(); }
}
/// <summary>
/// Gets or sets a value indicating whether this instance is open.
/// </summary>
/// <value>
/// <c>true</c> if this instance is open; otherwise, <c>false</c>.
/// </value>
public bool IsOpen { get; set; }
/// <summary>
/// Gets or sets the source path.
/// </summary>
/// <value>
/// The source path.
/// </value>
public IPath SourcePath { get; internal set; }
/// <summary>
/// Gets the next.
/// </summary>
/// <returns>The next node</returns>
public PolyNode GetNext()
{
if (this.children.Count > 0)
{
return this.children[0];
}
else
{
return this.GetNextSiblingUp();
}
}
/// <summary>
/// Adds the child.
/// </summary>
/// <param name="child">The child.</param>
internal void AddChild(PolyNode child)
{
int cnt = this.children.Count;
this.children.Add(child);
child.parent = this;
child.Index = cnt;
}
/// <summary>
/// Gets the next sibling up.
/// </summary>
/// <returns>The next sibling up</returns>
internal PolyNode GetNextSiblingUp()
{
if (this.parent == null)
{
return null;
}
else if (this.Index == this.parent.children.Count - 1)
{
return this.parent.GetNextSiblingUp();
}
else
{
return this.parent.Children[this.Index + 1];
}
}
/// <summary>
/// Determines whether [is hole node].
/// </summary>
/// <returns>
/// <c>true</c> if [is hole node]; otherwise, <c>false</c>.
/// </returns>
private bool IsHoleNode()
{
bool result = true;
PolyNode node = this.parent;
while (node != null)
{
result = !result;
node = node.parent;
}
return result;
}
}
}

81
src/ImageSharp/Drawing/Shapes/PolygonClipper/PolyTree.cs

@ -0,0 +1,81 @@
// <copyright file="PolyTree.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp.Drawing.Shapes.PolygonClipper
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Runtime.CompilerServices;
using Paths;
/// <summary>
/// Poly Tree
/// </summary>
/// <seealso cref="ImageSharp.Drawing.Shapes.PolygonClipper.PolyNode" />
internal class PolyTree : PolyNode
{
#pragma warning disable SA1401 // Field must be private
/// <summary>
/// All polys
/// </summary>
internal List<PolyNode> AllPolys = new List<PolyNode>();
#pragma warning restore SA1401 // Field must be private
/// <summary>
/// Gets the total.
/// </summary>
/// <value>
/// The total.
/// </value>
public int Total
{
get
{
int result = this.AllPolys.Count;
// with negative offsets, ignore the hidden outer polygon ...
if (result > 0 && this.Children[0] != this.AllPolys[0])
{
result--;
}
return result;
}
}
/// <summary>
/// Clears this instance.
/// </summary>
public void Clear()
{
for (int i = 0; i < this.AllPolys.Count; i++)
{
this.AllPolys[i] = null;
}
this.AllPolys.Clear();
this.Children.Clear();
}
/// <summary>
/// Gets the first.
/// </summary>
/// <returns>the first node</returns>
public PolyNode GetFirst()
{
if (this.Children.Count > 0)
{
return this.Children[0];
}
else
{
return null;
}
}
}
}

31
src/ImageSharp/Drawing/Shapes/PolygonClipper/PolyType.cs

@ -0,0 +1,31 @@
// <copyright file="PolyType.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp.Drawing.Shapes.PolygonClipper
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Runtime.CompilerServices;
using Paths;
/// <summary>
/// Poly Type
/// </summary>
internal enum PolyType
{
/// <summary>
/// The subject
/// </summary>
Subject,
/// <summary>
/// The clip
/// </summary>
Clip
}
}

40
src/ImageSharp/Drawing/Shapes/PolygonClipper/README.md

@ -0,0 +1,40 @@
# Clipper
License details for code in this folder, this is code original written by **Angus Johnson**
The license header onthe original file which has now be split across multiple files in this folder.
```
/*******************************************************************************
* *
* Author : Angus Johnson *
* Version : 6.4.0 *
* Date : 2 July 2015 *
* Website : http://www.angusj.com *
* Copyright : Angus Johnson 2010-2015 *
* *
* License: *
* Use, modification & distribution is subject to Boost Software License Ver 1. *
* http://www.boost.org/LICENSE_1_0.txt *
* *
* Attributions: *
* The code in this library is an extension of Bala Vatti's clipping algorithm: *
* "A generic solution to polygon clipping" *
* Communications of the ACM, Vol 35, Issue 7 (July 1992) pp 56-63. *
* http://portal.acm.org/citation.cfm?id=129906 *
* *
* Computer graphics and geometric modeling: implementation and algorithms *
* By Max K. Agoston *
* Springer; 1 edition (January 4, 2005) *
* http://books.google.com/books?q=vatti+clipping+agoston *
* *
* See also: *
* "Polygon Offsetting by Computing Winding Numbers" *
* Paper no. DETC2005-85513 pp. 565-575 *
* ASME 2005 International Design Engineering Technical Conferences *
* and Computers and Information in Engineering Conference (IDETC/CIE2005) *
* September 24-28, 2005 , Long Beach, California, USA *
* http://www.me.berkeley.edu/~mcmains/pubs/DAC05OffsetPolygon.pdf *
* *
*******************************************************************************/
```

33
src/ImageSharp/Drawing/Shapes/PolygonClipper/Scanbeam.cs

@ -0,0 +1,33 @@
// <copyright file="Scanbeam.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp.Drawing.Shapes.PolygonClipper
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Runtime.CompilerServices;
using Paths;
/// <summary>
/// Scanbeam
/// </summary>
internal class Scanbeam // would this work as a struct?
{
#pragma warning disable SA1401 // Field must be private
/// <summary>
/// The y
/// </summary>
internal float Y;
/// <summary>
/// The next
/// </summary>
internal Scanbeam Next;
#pragma warning restore SA1401 // Field must be private
}
}

118
src/ImageSharp/Drawing/Shapes/PolygonClipper/TEdge.cs

@ -0,0 +1,118 @@
// <copyright file="TEdge.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp.Drawing.Shapes.PolygonClipper
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Runtime.CompilerServices;
using Paths;
/// <summary>
/// TEdge
/// </summary>
internal class TEdge
{
#pragma warning disable SA1401 // Field must be private
/// <summary>
/// The source path, see if we can link this back later
/// </summary>
internal IPath SourcePath;
/// <summary>
/// The bot
/// </summary>
internal System.Numerics.Vector2 Bot;
/// <summary>
/// The current (updated for every new scanbeam)
/// </summary>
internal System.Numerics.Vector2 Curr;
/// <summary>
/// The top
/// </summary>
internal System.Numerics.Vector2 Top;
/// <summary>
/// The delta
/// </summary>
internal System.Numerics.Vector2 Delta;
/// <summary>
/// The dx
/// </summary>
internal double Dx;
/// <summary>
/// The poly type
/// </summary>
internal PolyType PolyTyp;
/// <summary>
/// Side only refers to current side of solution poly
/// </summary>
internal EdgeSide Side;
/// <summary>
/// 1 or -1 depending on winding direction
/// </summary>
internal int WindDelta;
/// <summary>
/// The winding count
/// </summary>
internal int WindCnt;
/// <summary>
/// The winding count of the opposite polytype
/// </summary>
internal int WindCnt2;
/// <summary>
/// The out index
/// </summary>
internal int OutIdx;
/// <summary>
/// The next
/// </summary>
internal TEdge Next;
/// <summary>
/// The previous
/// </summary>
internal TEdge Prev;
/// <summary>
/// The next in LML
/// </summary>
internal TEdge NextInLML;
/// <summary>
/// The next in ael
/// </summary>
internal TEdge NextInAEL;
/// <summary>
/// The previous in ael
/// </summary>
internal TEdge PrevInAEL;
/// <summary>
/// The next in sel
/// </summary>
internal TEdge NextInSEL;
/// <summary>
/// The previous in sel
/// </summary>
internal TEdge PrevInSEL;
#pragma warning restore SA1401 // Field must be
}
}
Loading…
Cancel
Save