mirror of https://github.com/SixLabors/ImageSharp
committed by
GitHub
123 changed files with 3971 additions and 7650 deletions
@ -0,0 +1,114 @@ |
|||||
|
// <copyright file="DrawBeziers.cs" company="James Jackson-South">
|
||||
|
// Copyright (c) James Jackson-South and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>
|
||||
|
|
||||
|
namespace ImageSharp |
||||
|
{ |
||||
|
using System; |
||||
|
using System.Numerics; |
||||
|
using Drawing; |
||||
|
using Drawing.Brushes; |
||||
|
using Drawing.Pens; |
||||
|
using Drawing.Processors; |
||||
|
using SixLabors.Shapes; |
||||
|
|
||||
|
using Path = SixLabors.Shapes.Path; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Extension methods for the <see cref="Image{TColor}"/> type.
|
||||
|
/// </summary>
|
||||
|
public static partial class ImageExtensions |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Draws the provided Points as an open Bezier path at the provided thickness with the supplied brush
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TColor">The type of the color.</typeparam>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="brush">The brush.</param>
|
||||
|
/// <param name="thickness">The thickness.</param>
|
||||
|
/// <param name="points">The points.</param>
|
||||
|
/// <param name="options">The options.</param>
|
||||
|
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
||||
|
public static Image<TColor> DrawBeziers<TColor>(this Image<TColor> source, IBrush<TColor> brush, float thickness, Vector2[] points, GraphicsOptions options) |
||||
|
where TColor : struct, IPackedPixel, IEquatable<TColor> |
||||
|
{ |
||||
|
return source.Draw(new Pen<TColor>(brush, thickness), new Path(new BezierLineSegment(points)), options); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Draws the provided Points as an open Bezier path at the provided thickness with the supplied brush
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TColor">The type of the color.</typeparam>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="brush">The brush.</param>
|
||||
|
/// <param name="thickness">The thickness.</param>
|
||||
|
/// <param name="points">The points.</param>
|
||||
|
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
||||
|
public static Image<TColor> DrawBeziers<TColor>(this Image<TColor> source, IBrush<TColor> brush, float thickness, Vector2[] points) |
||||
|
where TColor : struct, IPackedPixel, IEquatable<TColor> |
||||
|
{ |
||||
|
return source.Draw(new Pen<TColor>(brush, thickness), new Path(new BezierLineSegment(points))); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Draws the provided Points as an open Bezier path at the provided thickness with the supplied brush
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TColor">The type of the color.</typeparam>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="color">The color.</param>
|
||||
|
/// <param name="thickness">The thickness.</param>
|
||||
|
/// <param name="points">The points.</param>
|
||||
|
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
||||
|
public static Image<TColor> DrawBeziers<TColor>(this Image<TColor> source, TColor color, float thickness, Vector2[] points) |
||||
|
where TColor : struct, IPackedPixel, IEquatable<TColor> |
||||
|
{ |
||||
|
return source.DrawBeziers(new SolidBrush<TColor>(color), thickness, points); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Draws the provided Points as an open Bezier path at the provided thickness with the supplied brush
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TColor">The type of the color.</typeparam>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="color">The color.</param>
|
||||
|
/// <param name="thickness">The thickness.</param>
|
||||
|
/// <param name="points">The points.</param>
|
||||
|
/// <param name="options">The options.</param>
|
||||
|
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
||||
|
public static Image<TColor> DrawBeziers<TColor>(this Image<TColor> source, TColor color, float thickness, Vector2[] points, GraphicsOptions options) |
||||
|
where TColor : struct, IPackedPixel, IEquatable<TColor> |
||||
|
{ |
||||
|
return source.DrawBeziers(new SolidBrush<TColor>(color), thickness, points, options); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Draws the provided Points as an open Bezier path with the supplied pen
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TColor">The type of the color.</typeparam>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="pen">The pen.</param>
|
||||
|
/// <param name="points">The points.</param>
|
||||
|
/// <param name="options">The options.</param>
|
||||
|
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
||||
|
public static Image<TColor> DrawBeziers<TColor>(this Image<TColor> source, IPen<TColor> pen, Vector2[] points, GraphicsOptions options) |
||||
|
where TColor : struct, IPackedPixel, IEquatable<TColor> |
||||
|
{ |
||||
|
return source.Draw(pen, new Path(new BezierLineSegment(points)), options); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Draws the provided Points as an open Bezier path with the supplied pen
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TColor">The type of the color.</typeparam>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="pen">The pen.</param>
|
||||
|
/// <param name="points">The points.</param>
|
||||
|
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
||||
|
public static Image<TColor> DrawBeziers<TColor>(this Image<TColor> source, IPen<TColor> pen, Vector2[] points) |
||||
|
where TColor : struct, IPackedPixel, IEquatable<TColor> |
||||
|
{ |
||||
|
return source.Draw(pen, new Path(new BezierLineSegment(points))); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,112 @@ |
|||||
|
// <copyright file="DrawLines.cs" company="James Jackson-South">
|
||||
|
// Copyright (c) James Jackson-South and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>
|
||||
|
|
||||
|
namespace ImageSharp |
||||
|
{ |
||||
|
using System; |
||||
|
using System.Numerics; |
||||
|
using Drawing; |
||||
|
using Drawing.Brushes; |
||||
|
using Drawing.Pens; |
||||
|
using Drawing.Processors; |
||||
|
using SixLabors.Shapes; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Extension methods for the <see cref="Image{TColor}"/> type.
|
||||
|
/// </summary>
|
||||
|
public static partial class ImageExtensions |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Draws the provided Points as an open Linear path at the provided thickness with the supplied brush
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TColor">The type of the color.</typeparam>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="brush">The brush.</param>
|
||||
|
/// <param name="thickness">The thickness.</param>
|
||||
|
/// <param name="points">The points.</param>
|
||||
|
/// <param name="options">The options.</param>
|
||||
|
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
||||
|
public static Image<TColor> DrawLines<TColor>(this Image<TColor> source, IBrush<TColor> brush, float thickness, Vector2[] points, GraphicsOptions options) |
||||
|
where TColor : struct, IPackedPixel, IEquatable<TColor> |
||||
|
{ |
||||
|
return source.Draw(new Pen<TColor>(brush, thickness), new Path(new LinearLineSegment(points)), options); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Draws the provided Points as an open Linear path at the provided thickness with the supplied brush
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TColor">The type of the color.</typeparam>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="brush">The brush.</param>
|
||||
|
/// <param name="thickness">The thickness.</param>
|
||||
|
/// <param name="points">The points.</param>
|
||||
|
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
||||
|
public static Image<TColor> DrawLines<TColor>(this Image<TColor> source, IBrush<TColor> brush, float thickness, Vector2[] points) |
||||
|
where TColor : struct, IPackedPixel, IEquatable<TColor> |
||||
|
{ |
||||
|
return source.Draw(new Pen<TColor>(brush, thickness), new Path(new LinearLineSegment(points))); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Draws the provided Points as an open Linear path at the provided thickness with the supplied brush
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TColor">The type of the color.</typeparam>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="color">The color.</param>
|
||||
|
/// <param name="thickness">The thickness.</param>
|
||||
|
/// <param name="points">The points.</param>
|
||||
|
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
||||
|
public static Image<TColor> DrawLines<TColor>(this Image<TColor> source, TColor color, float thickness, Vector2[] points) |
||||
|
where TColor : struct, IPackedPixel, IEquatable<TColor> |
||||
|
{ |
||||
|
return source.DrawLines(new SolidBrush<TColor>(color), thickness, points); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Draws the provided Points as an open Linear path at the provided thickness with the supplied brush
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TColor">The type of the color.</typeparam>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="color">The color.</param>
|
||||
|
/// <param name="thickness">The thickness.</param>
|
||||
|
/// <param name="points">The points.</param>
|
||||
|
/// <param name="options">The options.</param>
|
||||
|
/// <returns>The <see cref="Image{TColor}"/>.</returns>>
|
||||
|
public static Image<TColor> DrawLines<TColor>(this Image<TColor> source, TColor color, float thickness, Vector2[] points, GraphicsOptions options) |
||||
|
where TColor : struct, IPackedPixel, IEquatable<TColor> |
||||
|
{ |
||||
|
return source.DrawLines(new SolidBrush<TColor>(color), thickness, points, options); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Draws the provided Points as an open Linear path with the supplied pen
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TColor">The type of the color.</typeparam>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="pen">The pen.</param>
|
||||
|
/// <param name="points">The points.</param>
|
||||
|
/// <param name="options">The options.</param>
|
||||
|
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
||||
|
public static Image<TColor> DrawLines<TColor>(this Image<TColor> source, IPen<TColor> pen, Vector2[] points, GraphicsOptions options) |
||||
|
where TColor : struct, IPackedPixel, IEquatable<TColor> |
||||
|
{ |
||||
|
return source.Draw(pen, new Path(new LinearLineSegment(points)), options); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Draws the provided Points as an open Linear path with the supplied pen
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TColor">The type of the color.</typeparam>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="pen">The pen.</param>
|
||||
|
/// <param name="points">The points.</param>
|
||||
|
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
||||
|
public static Image<TColor> DrawLines<TColor>(this Image<TColor> source, IPen<TColor> pen, Vector2[] points) |
||||
|
where TColor : struct, IPackedPixel, IEquatable<TColor> |
||||
|
{ |
||||
|
return source.Draw(pen, new Path(new LinearLineSegment(points))); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,112 @@ |
|||||
|
// <copyright file="DrawPath.cs" company="James Jackson-South">
|
||||
|
// Copyright (c) James Jackson-South and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>
|
||||
|
|
||||
|
namespace ImageSharp |
||||
|
{ |
||||
|
using System; |
||||
|
using System.Numerics; |
||||
|
using Drawing; |
||||
|
using Drawing.Brushes; |
||||
|
using Drawing.Pens; |
||||
|
using Drawing.Processors; |
||||
|
using SixLabors.Shapes; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Extension methods for the <see cref="Image{TColor}"/> type.
|
||||
|
/// </summary>
|
||||
|
public static partial class ImageExtensions |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Draws the outline of the polygon with the provided pen.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TColor">The type of the color.</typeparam>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="pen">The pen.</param>
|
||||
|
/// <param name="path">The path.</param>
|
||||
|
/// <param name="options">The options.</param>
|
||||
|
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
||||
|
public static Image<TColor> Draw<TColor>(this Image<TColor> source, IPen<TColor> pen, IPath path, GraphicsOptions options) |
||||
|
where TColor : struct, IPackedPixel, IEquatable<TColor> |
||||
|
{ |
||||
|
return source.Draw(pen, new ShapePath(path), options); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Draws the outline of the polygon with the provided pen.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TColor">The type of the color.</typeparam>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="pen">The pen.</param>
|
||||
|
/// <param name="path">The path.</param>
|
||||
|
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
||||
|
public static Image<TColor> Draw<TColor>(this Image<TColor> source, IPen<TColor> pen, IPath path) |
||||
|
where TColor : struct, IPackedPixel, IEquatable<TColor> |
||||
|
{ |
||||
|
return source.Draw(pen, path, GraphicsOptions.Default); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Draws the outline of the polygon with the provided brush at the provided thickness.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TColor">The type of the color.</typeparam>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="brush">The brush.</param>
|
||||
|
/// <param name="thickness">The thickness.</param>
|
||||
|
/// <param name="path">The shape.</param>
|
||||
|
/// <param name="options">The options.</param>
|
||||
|
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
||||
|
public static Image<TColor> Draw<TColor>(this Image<TColor> source, IBrush<TColor> brush, float thickness, IPath path, GraphicsOptions options) |
||||
|
where TColor : struct, IPackedPixel, IEquatable<TColor> |
||||
|
{ |
||||
|
return source.Draw(new Pen<TColor>(brush, thickness), path, options); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Draws the outline of the polygon with the provided brush at the provided thickness.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TColor">The type of the color.</typeparam>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="brush">The brush.</param>
|
||||
|
/// <param name="thickness">The thickness.</param>
|
||||
|
/// <param name="path">The path.</param>
|
||||
|
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
||||
|
public static Image<TColor> Draw<TColor>(this Image<TColor> source, IBrush<TColor> brush, float thickness, IPath path) |
||||
|
where TColor : struct, IPackedPixel, IEquatable<TColor> |
||||
|
{ |
||||
|
return source.Draw(new Pen<TColor>(brush, thickness), path); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Draws the outline of the polygon with the provided brush at the provided thickness.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TColor">The type of the color.</typeparam>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="color">The color.</param>
|
||||
|
/// <param name="thickness">The thickness.</param>
|
||||
|
/// <param name="path">The path.</param>
|
||||
|
/// <param name="options">The options.</param>
|
||||
|
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
||||
|
public static Image<TColor> Draw<TColor>(this Image<TColor> source, TColor color, float thickness, IPath path, GraphicsOptions options) |
||||
|
where TColor : struct, IPackedPixel, IEquatable<TColor> |
||||
|
{ |
||||
|
return source.Draw(new SolidBrush<TColor>(color), thickness, path, options); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Draws the outline of the polygon with the provided brush at the provided thickness.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TColor">The type of the color.</typeparam>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="color">The color.</param>
|
||||
|
/// <param name="thickness">The thickness.</param>
|
||||
|
/// <param name="path">The path.</param>
|
||||
|
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
||||
|
public static Image<TColor> Draw<TColor>(this Image<TColor> source, TColor color, float thickness, IPath path) |
||||
|
where TColor : struct, IPackedPixel, IEquatable<TColor> |
||||
|
{ |
||||
|
return source.Draw(new SolidBrush<TColor>(color), thickness, path); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,112 @@ |
|||||
|
// <copyright file="DrawPolygon.cs" company="James Jackson-South">
|
||||
|
// Copyright (c) James Jackson-South and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>
|
||||
|
|
||||
|
namespace ImageSharp |
||||
|
{ |
||||
|
using System; |
||||
|
using System.Numerics; |
||||
|
using Drawing; |
||||
|
using Drawing.Brushes; |
||||
|
using Drawing.Pens; |
||||
|
using Drawing.Processors; |
||||
|
using SixLabors.Shapes; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Extension methods for the <see cref="Image{TColor}"/> type.
|
||||
|
/// </summary>
|
||||
|
public static partial class ImageExtensions |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Draws the provided Points as a closed Linear Polygon with the provided brush at the provided thickness.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TColor">The type of the color.</typeparam>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="brush">The brush.</param>
|
||||
|
/// <param name="thickness">The thickness.</param>
|
||||
|
/// <param name="points">The points.</param>
|
||||
|
/// <param name="options">The options.</param>
|
||||
|
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
||||
|
public static Image<TColor> DrawPolygon<TColor>(this Image<TColor> source, IBrush<TColor> brush, float thickness, Vector2[] points, GraphicsOptions options) |
||||
|
where TColor : struct, IPackedPixel, IEquatable<TColor> |
||||
|
{ |
||||
|
return source.Draw(new Pen<TColor>(brush, thickness), new Polygon(new LinearLineSegment(points)), options); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Draws the provided Points as a closed Linear Polygon with the provided brush at the provided thickness.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TColor">The type of the color.</typeparam>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="brush">The brush.</param>
|
||||
|
/// <param name="thickness">The thickness.</param>
|
||||
|
/// <param name="points">The points.</param>
|
||||
|
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
||||
|
public static Image<TColor> DrawPolygon<TColor>(this Image<TColor> source, IBrush<TColor> brush, float thickness, Vector2[] points) |
||||
|
where TColor : struct, IPackedPixel, IEquatable<TColor> |
||||
|
{ |
||||
|
return source.Draw(new Pen<TColor>(brush, thickness), new Polygon(new LinearLineSegment(points))); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Draws the provided Points as a closed Linear Polygon with the provided brush at the provided thickness.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TColor">The type of the color.</typeparam>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="color">The color.</param>
|
||||
|
/// <param name="thickness">The thickness.</param>
|
||||
|
/// <param name="points">The points.</param>
|
||||
|
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
||||
|
public static Image<TColor> DrawPolygon<TColor>(this Image<TColor> source, TColor color, float thickness, Vector2[] points) |
||||
|
where TColor : struct, IPackedPixel, IEquatable<TColor> |
||||
|
{ |
||||
|
return source.DrawPolygon(new SolidBrush<TColor>(color), thickness, points); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Draws the provided Points as a closed Linear Polygon with the provided brush at the provided thickness.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TColor">The type of the color.</typeparam>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="color">The color.</param>
|
||||
|
/// <param name="thickness">The thickness.</param>
|
||||
|
/// <param name="points">The points.</param>
|
||||
|
/// <param name="options">The options.</param>
|
||||
|
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
||||
|
public static Image<TColor> DrawPolygon<TColor>(this Image<TColor> source, TColor color, float thickness, Vector2[] points, GraphicsOptions options) |
||||
|
where TColor : struct, IPackedPixel, IEquatable<TColor> |
||||
|
{ |
||||
|
return source.DrawPolygon(new SolidBrush<TColor>(color), thickness, points, options); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Draws the provided Points as a closed Linear Polygon with the provided Pen.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TColor">The type of the color.</typeparam>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="pen">The pen.</param>
|
||||
|
/// <param name="points">The points.</param>
|
||||
|
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
||||
|
public static Image<TColor> DrawPolygon<TColor>(this Image<TColor> source, IPen<TColor> pen, Vector2[] points) |
||||
|
where TColor : struct, IPackedPixel, IEquatable<TColor> |
||||
|
{ |
||||
|
return source.Draw(pen, new Polygon(new LinearLineSegment(points)), GraphicsOptions.Default); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Draws the provided Points as a closed Linear Polygon with the provided Pen.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TColor">The type of the color.</typeparam>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="pen">The pen.</param>
|
||||
|
/// <param name="points">The points.</param>
|
||||
|
/// <param name="options">The options.</param>
|
||||
|
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
||||
|
public static Image<TColor> DrawPolygon<TColor>(this Image<TColor> source, IPen<TColor> pen, Vector2[] points, GraphicsOptions options) |
||||
|
where TColor : struct, IPackedPixel, IEquatable<TColor> |
||||
|
{ |
||||
|
return source.Draw(pen, new Polygon(new LinearLineSegment(points)), options); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,112 @@ |
|||||
|
// <copyright file="DrawShape.cs" company="James Jackson-South">
|
||||
|
// Copyright (c) James Jackson-South and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>
|
||||
|
|
||||
|
namespace ImageSharp |
||||
|
{ |
||||
|
using System; |
||||
|
using System.Numerics; |
||||
|
using Drawing; |
||||
|
using Drawing.Brushes; |
||||
|
using Drawing.Pens; |
||||
|
using Drawing.Processors; |
||||
|
using SixLabors.Shapes; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Extension methods for the <see cref="Image{TColor}"/> type.
|
||||
|
/// </summary>
|
||||
|
public static partial class ImageExtensions |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Draws the outline of the polygon with the provided pen.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TColor">The type of the color.</typeparam>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="pen">The pen.</param>
|
||||
|
/// <param name="shape">The shape.</param>
|
||||
|
/// <param name="options">The options.</param>
|
||||
|
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
||||
|
public static Image<TColor> Draw<TColor>(this Image<TColor> source, IPen<TColor> pen, IShape shape, GraphicsOptions options) |
||||
|
where TColor : struct, IPackedPixel, IEquatable<TColor> |
||||
|
{ |
||||
|
return source.Draw(pen, new ShapePath(shape), options); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Draws the outline of the polygon with the provided pen.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TColor">The type of the color.</typeparam>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="pen">The pen.</param>
|
||||
|
/// <param name="shape">The shape.</param>
|
||||
|
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
||||
|
public static Image<TColor> Draw<TColor>(this Image<TColor> source, IPen<TColor> pen, IShape shape) |
||||
|
where TColor : struct, IPackedPixel, IEquatable<TColor> |
||||
|
{ |
||||
|
return source.Draw(pen, shape, GraphicsOptions.Default); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Draws the outline of the polygon with the provided brush at the provided thickness.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TColor">The type of the color.</typeparam>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="brush">The brush.</param>
|
||||
|
/// <param name="thickness">The thickness.</param>
|
||||
|
/// <param name="shape">The shape.</param>
|
||||
|
/// <param name="options">The options.</param>
|
||||
|
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
||||
|
public static Image<TColor> Draw<TColor>(this Image<TColor> source, IBrush<TColor> brush, float thickness, IShape shape, GraphicsOptions options) |
||||
|
where TColor : struct, IPackedPixel, IEquatable<TColor> |
||||
|
{ |
||||
|
return source.Draw(new Pen<TColor>(brush, thickness), shape, options); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Draws the outline of the polygon with the provided brush at the provided thickness.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TColor">The type of the color.</typeparam>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="brush">The brush.</param>
|
||||
|
/// <param name="thickness">The thickness.</param>
|
||||
|
/// <param name="shape">The shape.</param>
|
||||
|
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
||||
|
public static Image<TColor> Draw<TColor>(this Image<TColor> source, IBrush<TColor> brush, float thickness, IShape shape) |
||||
|
where TColor : struct, IPackedPixel, IEquatable<TColor> |
||||
|
{ |
||||
|
return source.Draw(new Pen<TColor>(brush, thickness), shape); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Draws the outline of the polygon with the provided brush at the provided thickness.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TColor">The type of the color.</typeparam>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="color">The color.</param>
|
||||
|
/// <param name="thickness">The thickness.</param>
|
||||
|
/// <param name="shape">The shape.</param>
|
||||
|
/// <param name="options">The options.</param>
|
||||
|
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
||||
|
public static Image<TColor> Draw<TColor>(this Image<TColor> source, TColor color, float thickness, IShape shape, GraphicsOptions options) |
||||
|
where TColor : struct, IPackedPixel, IEquatable<TColor> |
||||
|
{ |
||||
|
return source.Draw(new SolidBrush<TColor>(color), thickness, shape, options); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Draws the outline of the polygon with the provided brush at the provided thickness.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TColor">The type of the color.</typeparam>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="color">The color.</param>
|
||||
|
/// <param name="thickness">The thickness.</param>
|
||||
|
/// <param name="shape">The shape.</param>
|
||||
|
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
||||
|
public static Image<TColor> Draw<TColor>(this Image<TColor> source, TColor color, float thickness, IShape shape) |
||||
|
where TColor : struct, IPackedPixel, IEquatable<TColor> |
||||
|
{ |
||||
|
return source.Draw(new SolidBrush<TColor>(color), thickness, shape); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,79 @@ |
|||||
|
// <copyright file="FillPaths.cs" company="James Jackson-South">
|
||||
|
// Copyright (c) James Jackson-South and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>
|
||||
|
|
||||
|
namespace ImageSharp |
||||
|
{ |
||||
|
using System; |
||||
|
using System.Numerics; |
||||
|
using Drawing; |
||||
|
using Drawing.Brushes; |
||||
|
using Drawing.Processors; |
||||
|
|
||||
|
using SixLabors.Shapes; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Extension methods for the <see cref="Image{TColor}"/> type.
|
||||
|
/// </summary>
|
||||
|
public static partial class ImageExtensions |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Flood fills the image in the shape of the provided polygon with the specified brush..
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TColor">The type of the color.</typeparam>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="brush">The brush.</param>
|
||||
|
/// <param name="path">The shape.</param>
|
||||
|
/// <param name="options">The graphics options.</param>
|
||||
|
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
||||
|
public static Image<TColor> Fill<TColor>(this Image<TColor> source, IBrush<TColor> brush, IPath path, GraphicsOptions options) |
||||
|
where TColor : struct, IPackedPixel, IEquatable<TColor> |
||||
|
{ |
||||
|
return source.Fill(brush, new ShapeRegion(path), options); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Flood fills the image in the shape of the provided polygon with the specified brush.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TColor">The type of the color.</typeparam>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="brush">The brush.</param>
|
||||
|
/// <param name="path">The path.</param>
|
||||
|
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
||||
|
public static Image<TColor> Fill<TColor>(this Image<TColor> source, IBrush<TColor> brush, IPath path) |
||||
|
where TColor : struct, IPackedPixel, IEquatable<TColor> |
||||
|
{ |
||||
|
return source.Fill(brush, new ShapeRegion(path), GraphicsOptions.Default); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Flood fills the image in the shape of the provided polygon with the specified brush..
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TColor">The type of the color.</typeparam>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="color">The color.</param>
|
||||
|
/// <param name="path">The path.</param>
|
||||
|
/// <param name="options">The options.</param>
|
||||
|
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
||||
|
public static Image<TColor> Fill<TColor>(this Image<TColor> source, TColor color, IPath path, GraphicsOptions options) |
||||
|
where TColor : struct, IPackedPixel, IEquatable<TColor> |
||||
|
{ |
||||
|
return source.Fill(new SolidBrush<TColor>(color), path, options); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Flood fills the image in the shape of the provided polygon with the specified brush..
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TColor">The type of the color.</typeparam>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="color">The color.</param>
|
||||
|
/// <param name="path">The path.</param>
|
||||
|
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
||||
|
public static Image<TColor> Fill<TColor>(this Image<TColor> source, TColor color, IPath path) |
||||
|
where TColor : struct, IPackedPixel, IEquatable<TColor> |
||||
|
{ |
||||
|
return source.Fill(new SolidBrush<TColor>(color), path); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,79 @@ |
|||||
|
// <copyright file="FillPolygon.cs" company="James Jackson-South">
|
||||
|
// Copyright (c) James Jackson-South and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>
|
||||
|
|
||||
|
namespace ImageSharp |
||||
|
{ |
||||
|
using System; |
||||
|
using System.Numerics; |
||||
|
using Drawing; |
||||
|
using Drawing.Brushes; |
||||
|
using Drawing.Processors; |
||||
|
|
||||
|
using SixLabors.Shapes; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Extension methods for the <see cref="Image{TColor}"/> type.
|
||||
|
/// </summary>
|
||||
|
public static partial class ImageExtensions |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Flood fills the image in the shape of a Linear polygon described by the points
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TColor">The type of the color.</typeparam>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="brush">The brush.</param>
|
||||
|
/// <param name="points">The points.</param>
|
||||
|
/// <param name="options">The options.</param>
|
||||
|
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
||||
|
public static Image<TColor> FillPolygon<TColor>(this Image<TColor> source, IBrush<TColor> brush, Vector2[] points, GraphicsOptions options) |
||||
|
where TColor : struct, IPackedPixel, IEquatable<TColor> |
||||
|
{ |
||||
|
return source.Fill(brush, new Polygon(new LinearLineSegment(points)), options); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Flood fills the image in the shape of a Linear polygon described by the points
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TColor">The type of the color.</typeparam>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="brush">The brush.</param>
|
||||
|
/// <param name="points">The points.</param>
|
||||
|
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
||||
|
public static Image<TColor> FillPolygon<TColor>(this Image<TColor> source, IBrush<TColor> brush, Vector2[] points) |
||||
|
where TColor : struct, IPackedPixel, IEquatable<TColor> |
||||
|
{ |
||||
|
return source.Fill(brush, new Polygon(new LinearLineSegment(points))); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Flood fills the image in the shape of a Linear polygon described by the points
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TColor">The type of the color.</typeparam>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="color">The color.</param>
|
||||
|
/// <param name="points">The points.</param>
|
||||
|
/// <param name="options">The options.</param>
|
||||
|
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
||||
|
public static Image<TColor> FillPolygon<TColor>(this Image<TColor> source, TColor color, Vector2[] points, GraphicsOptions options) |
||||
|
where TColor : struct, IPackedPixel, IEquatable<TColor> |
||||
|
{ |
||||
|
return source.Fill(new SolidBrush<TColor>(color), new Polygon(new LinearLineSegment(points)), options); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Flood fills the image in the shape of a Linear polygon described by the points
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TColor">The type of the color.</typeparam>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="color">The color.</param>
|
||||
|
/// <param name="points">The points.</param>
|
||||
|
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
||||
|
public static Image<TColor> FillPolygon<TColor>(this Image<TColor> source, TColor color, Vector2[] points) |
||||
|
where TColor : struct, IPackedPixel, IEquatable<TColor> |
||||
|
{ |
||||
|
return source.Fill(new SolidBrush<TColor>(color), new Polygon(new LinearLineSegment(points))); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,79 @@ |
|||||
|
// <copyright file="FillShape.cs" company="James Jackson-South">
|
||||
|
// Copyright (c) James Jackson-South and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>
|
||||
|
|
||||
|
namespace ImageSharp |
||||
|
{ |
||||
|
using System; |
||||
|
using System.Numerics; |
||||
|
using Drawing; |
||||
|
using Drawing.Brushes; |
||||
|
using Drawing.Processors; |
||||
|
|
||||
|
using SixLabors.Shapes; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Extension methods for the <see cref="Image{TColor}"/> type.
|
||||
|
/// </summary>
|
||||
|
public static partial class ImageExtensions |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Flood fills the image in the shape of the provided polygon with the specified brush..
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TColor">The type of the color.</typeparam>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="brush">The brush.</param>
|
||||
|
/// <param name="shape">The shape.</param>
|
||||
|
/// <param name="options">The graphics options.</param>
|
||||
|
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
||||
|
public static Image<TColor> Fill<TColor>(this Image<TColor> source, IBrush<TColor> brush, IShape shape, GraphicsOptions options) |
||||
|
where TColor : struct, IPackedPixel, IEquatable<TColor> |
||||
|
{ |
||||
|
return source.Fill(brush, new ShapeRegion(shape), options); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Flood fills the image in the shape of the provided polygon with the specified brush.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TColor">The type of the color.</typeparam>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="brush">The brush.</param>
|
||||
|
/// <param name="shape">The shape.</param>
|
||||
|
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
||||
|
public static Image<TColor> Fill<TColor>(this Image<TColor> source, IBrush<TColor> brush, IShape shape) |
||||
|
where TColor : struct, IPackedPixel, IEquatable<TColor> |
||||
|
{ |
||||
|
return source.Fill(brush, new ShapeRegion(shape), GraphicsOptions.Default); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Flood fills the image in the shape of the provided polygon with the specified brush..
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TColor">The type of the color.</typeparam>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="color">The color.</param>
|
||||
|
/// <param name="shape">The shape.</param>
|
||||
|
/// <param name="options">The options.</param>
|
||||
|
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
||||
|
public static Image<TColor> Fill<TColor>(this Image<TColor> source, TColor color, IShape shape, GraphicsOptions options) |
||||
|
where TColor : struct, IPackedPixel, IEquatable<TColor> |
||||
|
{ |
||||
|
return source.Fill(new SolidBrush<TColor>(color), shape, options); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Flood fills the image in the shape of the provided polygon with the specified brush..
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TColor">The type of the color.</typeparam>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="color">The color.</param>
|
||||
|
/// <param name="shape">The shape.</param>
|
||||
|
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
||||
|
public static Image<TColor> Fill<TColor>(this Image<TColor> source, TColor color, IShape shape) |
||||
|
where TColor : struct, IPackedPixel, IEquatable<TColor> |
||||
|
{ |
||||
|
return source.Fill(new SolidBrush<TColor>(color), shape); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,25 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
||||
|
<PropertyGroup> |
||||
|
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion> |
||||
|
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath> |
||||
|
</PropertyGroup> |
||||
|
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" /> |
||||
|
<PropertyGroup Label="Globals"> |
||||
|
<ProjectGuid>e5bd4f96-28a8-410c-8b63-1c5731948549</ProjectGuid> |
||||
|
<RootNamespace>ImageSharp.Drawing</RootNamespace> |
||||
|
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath> |
||||
|
<OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath> |
||||
|
<TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion> |
||||
|
</PropertyGroup> |
||||
|
<PropertyGroup> |
||||
|
<SchemaVersion>2.0</SchemaVersion> |
||||
|
</PropertyGroup> |
||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> |
||||
|
<ProduceOutputsOnBuild>True</ProduceOutputsOnBuild> |
||||
|
</PropertyGroup> |
||||
|
<ItemGroup> |
||||
|
<Service Include="{508349b6-6b84-4df5-91f0-309beebad82d}" /> |
||||
|
</ItemGroup> |
||||
|
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" /> |
||||
|
</Project> |
||||
@ -0,0 +1,6 @@ |
|||||
|
// <copyright file="AssemblyInfo.cs" company="James Jackson-South">
|
||||
|
// Copyright (c) James Jackson-South and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>
|
||||
|
|
||||
|
// Common values read from `AssemblyInfo.Common.cs`
|
||||
@ -0,0 +1,36 @@ |
|||||
|
// <copyright file="RectangleExtensions.cs" company="James Jackson-South">
|
||||
|
// Copyright (c) James Jackson-South and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>
|
||||
|
|
||||
|
namespace ImageSharp.Drawing.Processors |
||||
|
{ |
||||
|
using System; |
||||
|
using System.Buffers; |
||||
|
using System.Numerics; |
||||
|
using System.Threading.Tasks; |
||||
|
using Drawing; |
||||
|
using ImageSharp.Processing; |
||||
|
using SixLabors.Shapes; |
||||
|
using Rectangle = ImageSharp.Rectangle; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Extension methods for helping to bridge Shaper2D and ImageSharp primitives.
|
||||
|
/// </summary>
|
||||
|
internal static class RectangleExtensions |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Converts a Shaper2D <see cref="SixLabors.Shapes.Rectangle"/> to an ImageSharp <see cref="Rectangle"/> by creating a <see cref="Rectangle"/> the entirely surrounds the source.
|
||||
|
/// </summary>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <returns>A <see cref="Rectangle"/> representation of this <see cref="SixLabors.Shapes.Rectangle"/></returns>
|
||||
|
public static Rectangle Convert(this SixLabors.Shapes.Rectangle source) |
||||
|
{ |
||||
|
int left = (int)Math.Floor(source.Left); |
||||
|
int right = (int)Math.Ceiling(source.Right); |
||||
|
int top = (int)Math.Floor(source.Top); |
||||
|
int bottom = (int)Math.Ceiling(source.Bottom); |
||||
|
return new Rectangle(left, top, right - left, bottom - top); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,153 @@ |
|||||
|
// <copyright file="ShapePath.cs" company="James Jackson-South">
|
||||
|
// Copyright (c) James Jackson-South and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>
|
||||
|
|
||||
|
namespace ImageSharp.Drawing |
||||
|
{ |
||||
|
using System.Buffers; |
||||
|
using System.Collections.Immutable; |
||||
|
using System.Numerics; |
||||
|
|
||||
|
using ImageSharp.Drawing.Processors; |
||||
|
|
||||
|
using SixLabors.Shapes; |
||||
|
|
||||
|
using Rectangle = ImageSharp.Rectangle; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// A drawable mapping between a <see cref="SixLabors.Shapes.IShape"/>/<see cref="SixLabors.Shapes.IPath"/> and a drawable/fillable region.
|
||||
|
/// </summary>
|
||||
|
internal class ShapePath : ImageSharp.Drawing.Drawable |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// The fillable shape
|
||||
|
/// </summary>
|
||||
|
private readonly IShape shape; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="ShapePath"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="path">The path.</param>
|
||||
|
public ShapePath(IPath path) |
||||
|
: this(ImmutableArray.Create(path)) |
||||
|
{ |
||||
|
this.shape = path.AsShape(); |
||||
|
this.Bounds = RectangleF.Ceiling(path.Bounds.Convert()); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="ShapePath"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="shape">The shape.</param>
|
||||
|
public ShapePath(IShape shape) |
||||
|
: this(shape.Paths) |
||||
|
{ |
||||
|
this.shape = shape; |
||||
|
this.Bounds = RectangleF.Ceiling(shape.Bounds.Convert()); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="ShapePath" /> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="paths">The paths.</param>
|
||||
|
private ShapePath(ImmutableArray<IPath> paths) |
||||
|
{ |
||||
|
this.Paths = paths; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the drawable paths
|
||||
|
/// </summary>
|
||||
|
/// <value>
|
||||
|
/// The paths.
|
||||
|
/// </value>
|
||||
|
public ImmutableArray<IPath> Paths { get; } |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public override int MaxIntersections => this.shape.MaxIntersections; |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public override Rectangle Bounds { get; } |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public override int ScanX(int x, float[] buffer, int length, int offset) |
||||
|
{ |
||||
|
Vector2 start = new Vector2(x, this.Bounds.Top - 1); |
||||
|
Vector2 end = new Vector2(x, this.Bounds.Bottom + 1); |
||||
|
Vector2[] innerbuffer = ArrayPool<Vector2>.Shared.Rent(length); |
||||
|
try |
||||
|
{ |
||||
|
int count = this.shape.FindIntersections( |
||||
|
start, |
||||
|
end, |
||||
|
innerbuffer, |
||||
|
length, |
||||
|
0); |
||||
|
|
||||
|
for (int i = 0; i < count; i++) |
||||
|
{ |
||||
|
buffer[i + offset] = innerbuffer[i].Y; |
||||
|
} |
||||
|
|
||||
|
return count; |
||||
|
} |
||||
|
finally |
||||
|
{ |
||||
|
ArrayPool<Vector2>.Shared.Return(innerbuffer); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public override int ScanY(int y, float[] buffer, int length, int offset) |
||||
|
{ |
||||
|
Vector2 start = new Vector2(this.Bounds.Left - 1, y); |
||||
|
Vector2 end = new Vector2(this.Bounds.Right + 1, y); |
||||
|
Vector2[] innerbuffer = ArrayPool<Vector2>.Shared.Rent(length); |
||||
|
try |
||||
|
{ |
||||
|
int count = this.shape.FindIntersections( |
||||
|
start, |
||||
|
end, |
||||
|
innerbuffer, |
||||
|
length, |
||||
|
0); |
||||
|
|
||||
|
for (int i = 0; i < count; i++) |
||||
|
{ |
||||
|
buffer[i + offset] = innerbuffer[i].X; |
||||
|
} |
||||
|
|
||||
|
return count; |
||||
|
} |
||||
|
finally |
||||
|
{ |
||||
|
ArrayPool<Vector2>.Shared.Return(innerbuffer); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public override PointInfo GetPointInfo(int x, int y) |
||||
|
{ |
||||
|
Vector2 point = new Vector2(x, y); |
||||
|
float distanceFromPath = float.MaxValue; |
||||
|
float distanceAlongPath = 0; |
||||
|
|
||||
|
for (int i = 0; i < this.Paths.Length; i++) |
||||
|
{ |
||||
|
SixLabors.Shapes.PointInfo p = this.Paths[i].Distance(point); |
||||
|
if (p.DistanceFromPath < distanceFromPath) |
||||
|
{ |
||||
|
distanceFromPath = p.DistanceFromPath; |
||||
|
distanceAlongPath = p.DistanceAlongPath; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return new PointInfo |
||||
|
{ |
||||
|
DistanceAlongPath = distanceAlongPath, |
||||
|
DistanceFromPath = distanceFromPath |
||||
|
}; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,109 @@ |
|||||
|
// <copyright file="ShapeRegion.cs" company="James Jackson-South">
|
||||
|
// Copyright (c) James Jackson-South and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>
|
||||
|
|
||||
|
namespace ImageSharp.Drawing |
||||
|
{ |
||||
|
using System.Buffers; |
||||
|
using System.Collections.Immutable; |
||||
|
using System.Numerics; |
||||
|
|
||||
|
using ImageSharp.Drawing.Processors; |
||||
|
|
||||
|
using SixLabors.Shapes; |
||||
|
|
||||
|
using Rectangle = ImageSharp.Rectangle; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// A drawable mapping between a <see cref="SixLabors.Shapes.IShape"/>/<see cref="SixLabors.Shapes.IPath"/> and a drawable/fillable region.
|
||||
|
/// </summary>
|
||||
|
internal class ShapeRegion : Region |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="ShapeRegion"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="path">The path.</param>
|
||||
|
public ShapeRegion(IPath path) |
||||
|
: this(path.AsShape()) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="ShapeRegion"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="shape">The shape.</param>
|
||||
|
public ShapeRegion(IShape shape) |
||||
|
{ |
||||
|
this.Shape = shape; |
||||
|
this.Bounds = shape.Bounds.Convert(); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the fillable shape
|
||||
|
/// </summary>
|
||||
|
public IShape Shape { get; } |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public override int MaxIntersections => this.Shape.MaxIntersections; |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public override Rectangle Bounds { get; } |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public override int ScanX(int x, float[] buffer, int length, int offset) |
||||
|
{ |
||||
|
Vector2 start = new Vector2(x, this.Bounds.Top - 1); |
||||
|
Vector2 end = new Vector2(x, this.Bounds.Bottom + 1); |
||||
|
Vector2[] innerbuffer = ArrayPool<Vector2>.Shared.Rent(length); |
||||
|
try |
||||
|
{ |
||||
|
int count = this.Shape.FindIntersections( |
||||
|
start, |
||||
|
end, |
||||
|
innerbuffer, |
||||
|
length, |
||||
|
0); |
||||
|
|
||||
|
for (int i = 0; i < count; i++) |
||||
|
{ |
||||
|
buffer[i + offset] = innerbuffer[i].Y; |
||||
|
} |
||||
|
|
||||
|
return count; |
||||
|
} |
||||
|
finally |
||||
|
{ |
||||
|
ArrayPool<Vector2>.Shared.Return(innerbuffer); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public override int ScanY(int y, float[] buffer, int length, int offset) |
||||
|
{ |
||||
|
Vector2 start = new Vector2(this.Bounds.Left - 1, y); |
||||
|
Vector2 end = new Vector2(this.Bounds.Right + 1, y); |
||||
|
Vector2[] innerbuffer = ArrayPool<Vector2>.Shared.Rent(length); |
||||
|
try |
||||
|
{ |
||||
|
int count = this.Shape.FindIntersections( |
||||
|
start, |
||||
|
end, |
||||
|
innerbuffer, |
||||
|
length, |
||||
|
0); |
||||
|
|
||||
|
for (int i = 0; i < count; i++) |
||||
|
{ |
||||
|
buffer[i + offset] = innerbuffer[i].X; |
||||
|
} |
||||
|
|
||||
|
return count; |
||||
|
} |
||||
|
finally |
||||
|
{ |
||||
|
ArrayPool<Vector2>.Shared.Return(innerbuffer); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,96 @@ |
|||||
|
{ |
||||
|
"version": "1.0.0-alpha1-*", |
||||
|
"title": "ImageSharp.Drawing.Paths", |
||||
|
"description": "A cross-platform library for the processing of image files; written in C#", |
||||
|
"authors": [ |
||||
|
"James Jackson-South and contributors" |
||||
|
], |
||||
|
"packOptions": { |
||||
|
"owners": [ |
||||
|
"James Jackson-South and contributors" |
||||
|
], |
||||
|
"projectUrl": "https://github.com/JimBobSquarePants/ImageSharp", |
||||
|
"licenseUrl": "http://www.apache.org/licenses/LICENSE-2.0", |
||||
|
"iconUrl": "https://raw.githubusercontent.com/JimBobSquarePants/ImageSharp/master/build/icons/imagesharp-logo-128.png", |
||||
|
"requireLicenseAcceptance": false, |
||||
|
"repository": { |
||||
|
"type": "git", |
||||
|
"url": "https://github.com/JimBobSquarePants/ImageSharp" |
||||
|
}, |
||||
|
"tags": [ |
||||
|
"Image Resize Crop Gif Jpg Jpeg Bitmap Png Core" |
||||
|
] |
||||
|
}, |
||||
|
"buildOptions": { |
||||
|
"allowUnsafe": true, |
||||
|
"xmlDoc": true, |
||||
|
"additionalArguments": [ "/additionalfile:../Shared/stylecop.json", "/ruleset:../../ImageSharp.ruleset" ], |
||||
|
"compile": [ |
||||
|
"../Shared/*.cs" |
||||
|
] |
||||
|
}, |
||||
|
"configurations": { |
||||
|
"Release": { |
||||
|
"buildOptions": { |
||||
|
"warningsAsErrors": true, |
||||
|
"optimize": true |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
"dependencies": { |
||||
|
"ImageSharp": { |
||||
|
"target": "project" |
||||
|
}, |
||||
|
"ImageSharp.Drawing": { |
||||
|
"target": "project" |
||||
|
}, |
||||
|
"SixLabors.Shapes": "0.1.0-alpha0003", |
||||
|
"StyleCop.Analyzers": { |
||||
|
"version": "1.0.0", |
||||
|
"type": "build" |
||||
|
}, |
||||
|
"System.Buffers": "4.0.0", |
||||
|
"System.Runtime.CompilerServices.Unsafe": "4.0.0" |
||||
|
}, |
||||
|
"frameworks": { |
||||
|
"netstandard1.1": { |
||||
|
"dependencies": { |
||||
|
"System.Collections": "4.0.11", |
||||
|
"System.Diagnostics.Debug": "4.0.11", |
||||
|
"System.Diagnostics.Tools": "4.0.1", |
||||
|
"System.IO": "4.1.0", |
||||
|
"System.IO.Compression": "4.1.0", |
||||
|
"System.Linq": "4.1.0", |
||||
|
"System.Numerics.Vectors": "4.1.1", |
||||
|
"System.ObjectModel": "4.0.12", |
||||
|
"System.Resources.ResourceManager": "4.0.1", |
||||
|
"System.Runtime.Extensions": "4.1.0", |
||||
|
"System.Runtime.InteropServices": "4.1.0", |
||||
|
"System.Runtime.Numerics": "4.0.1", |
||||
|
"System.Text.Encoding.Extensions": "4.0.11", |
||||
|
"System.Threading": "4.0.11", |
||||
|
"System.Threading.Tasks": "4.0.11", |
||||
|
"System.Threading.Tasks.Parallel": "4.0.1" |
||||
|
} |
||||
|
}, |
||||
|
"net45": { |
||||
|
"dependencies": { |
||||
|
"System.Numerics.Vectors": "4.1.1", |
||||
|
"System.Threading.Tasks.Parallel": "4.0.0" |
||||
|
}, |
||||
|
"frameworkAssemblies": { |
||||
|
"System.Runtime": { "type": "build" } |
||||
|
} |
||||
|
}, |
||||
|
"net461": { |
||||
|
"dependencies": { |
||||
|
"System.Threading.Tasks.Parallel": "4.0.0" |
||||
|
}, |
||||
|
"frameworkAssemblies": { |
||||
|
"System.Runtime": { "type": "build" }, |
||||
|
"System.Numerics": "4.0.0.0", |
||||
|
"System.Numerics.Vectors": "4.0.0.0" |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,507 +0,0 @@ |
|||||
// <copyright file="Draw.cs" company="James Jackson-South">
|
|
||||
// Copyright (c) James Jackson-South and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
// </copyright>
|
|
||||
|
|
||||
namespace ImageSharp |
|
||||
{ |
|
||||
using System; |
|
||||
using System.Numerics; |
|
||||
using Drawing; |
|
||||
using Drawing.Brushes; |
|
||||
using Drawing.Paths; |
|
||||
using Drawing.Pens; |
|
||||
using Drawing.Processors; |
|
||||
using Drawing.Shapes; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Extension methods for the <see cref="Image{TColor}"/> type.
|
|
||||
/// </summary>
|
|
||||
public static partial class ImageExtensions |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Draws the outline of the polygon with the provided pen.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The source.</param>
|
|
||||
/// <param name="pen">The pen.</param>
|
|
||||
/// <param name="shape">The shape.</param>
|
|
||||
/// <param name="options">The options.</param>
|
|
||||
/// <returns>
|
|
||||
/// The Image
|
|
||||
/// </returns>
|
|
||||
public static Image<TColor> DrawPolygon<TColor>(this Image<TColor> source, IPen<TColor> pen, IShape shape, GraphicsOptions options) |
|
||||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|
||||
{ |
|
||||
return source.Apply(new DrawPathProcessor<TColor>(pen, shape, options)); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the outline of the polygon with the provided pen.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The source.</param>
|
|
||||
/// <param name="pen">The pen.</param>
|
|
||||
/// <param name="shape">The shape.</param>
|
|
||||
/// <returns>The Image</returns>
|
|
||||
public static Image<TColor> DrawPolygon<TColor>(this Image<TColor> source, IPen<TColor> pen, IShape shape) |
|
||||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|
||||
{ |
|
||||
return source.DrawPolygon(pen, shape, GraphicsOptions.Default); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the outline of the polygon with the provided brush at the provided thickness.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The source.</param>
|
|
||||
/// <param name="brush">The brush.</param>
|
|
||||
/// <param name="thickness">The thickness.</param>
|
|
||||
/// <param name="shape">The shape.</param>
|
|
||||
/// <param name="options">The options.</param>
|
|
||||
/// <returns>
|
|
||||
/// The Image
|
|
||||
/// </returns>
|
|
||||
public static Image<TColor> DrawPolygon<TColor>(this Image<TColor> source, IBrush<TColor> brush, float thickness, IShape shape, GraphicsOptions options) |
|
||||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|
||||
{ |
|
||||
return source.DrawPolygon(new Pen<TColor>(brush, thickness), shape, options); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the outline of the polygon with the provided brush at the provided thickness.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The source.</param>
|
|
||||
/// <param name="brush">The brush.</param>
|
|
||||
/// <param name="thickness">The thickness.</param>
|
|
||||
/// <param name="shape">The shape.</param>
|
|
||||
/// <returns>The Image</returns>
|
|
||||
public static Image<TColor> DrawPolygon<TColor>(this Image<TColor> source, IBrush<TColor> brush, float thickness, IShape shape) |
|
||||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|
||||
{ |
|
||||
return source.DrawPolygon(new Pen<TColor>(brush, thickness), shape); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the outline of the polygon with the provided brush at the provided thickness.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The source.</param>
|
|
||||
/// <param name="color">The color.</param>
|
|
||||
/// <param name="thickness">The thickness.</param>
|
|
||||
/// <param name="shape">The shape.</param>
|
|
||||
/// <param name="options">The options.</param>
|
|
||||
/// <returns>
|
|
||||
/// The Image
|
|
||||
/// </returns>
|
|
||||
public static Image<TColor> DrawPolygon<TColor>(this Image<TColor> source, TColor color, float thickness, IShape shape, GraphicsOptions options) |
|
||||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|
||||
{ |
|
||||
return source.DrawPolygon(new SolidBrush<TColor>(color), thickness, shape, options); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the outline of the polygon with the provided brush at the provided thickness.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The source.</param>
|
|
||||
/// <param name="color">The color.</param>
|
|
||||
/// <param name="thickness">The thickness.</param>
|
|
||||
/// <param name="shape">The shape.</param>
|
|
||||
/// <returns>The Image</returns>
|
|
||||
public static Image<TColor> DrawPolygon<TColor>(this Image<TColor> source, TColor color, float thickness, IShape shape) |
|
||||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|
||||
{ |
|
||||
return source.DrawPolygon(new SolidBrush<TColor>(color), thickness, shape); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the provided Points as a closed Linear Polygon with the provided brush at the provided thickness.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The source.</param>
|
|
||||
/// <param name="brush">The brush.</param>
|
|
||||
/// <param name="thickness">The thickness.</param>
|
|
||||
/// <param name="points">The points.</param>
|
|
||||
/// <param name="options">The options.</param>
|
|
||||
/// <returns>
|
|
||||
/// The Image
|
|
||||
/// </returns>
|
|
||||
public static Image<TColor> DrawPolygon<TColor>(this Image<TColor> source, IBrush<TColor> brush, float thickness, Vector2[] points, GraphicsOptions options) |
|
||||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|
||||
{ |
|
||||
return source.DrawPolygon(new Pen<TColor>(brush, thickness), new Polygon(new LinearLineSegment(points)), options); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the provided Points as a closed Linear Polygon with the provided brush at the provided thickness.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The source.</param>
|
|
||||
/// <param name="brush">The brush.</param>
|
|
||||
/// <param name="thickness">The thickness.</param>
|
|
||||
/// <param name="points">The points.</param>
|
|
||||
/// <returns>The Image</returns>
|
|
||||
public static Image<TColor> DrawPolygon<TColor>(this Image<TColor> source, IBrush<TColor> brush, float thickness, Vector2[] points) |
|
||||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|
||||
{ |
|
||||
return source.DrawPolygon(new Pen<TColor>(brush, thickness), new Polygon(new LinearLineSegment(points))); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the provided Points as a closed Linear Polygon with the provided brush at the provided thickness.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The source.</param>
|
|
||||
/// <param name="color">The color.</param>
|
|
||||
/// <param name="thickness">The thickness.</param>
|
|
||||
/// <param name="points">The points.</param>
|
|
||||
/// <returns>The Image</returns>
|
|
||||
public static Image<TColor> DrawPolygon<TColor>(this Image<TColor> source, TColor color, float thickness, Vector2[] points) |
|
||||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|
||||
{ |
|
||||
return source.DrawPolygon(new SolidBrush<TColor>(color), thickness, points); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the provided Points as a closed Linear Polygon with the provided brush at the provided thickness.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The source.</param>
|
|
||||
/// <param name="color">The color.</param>
|
|
||||
/// <param name="thickness">The thickness.</param>
|
|
||||
/// <param name="points">The points.</param>
|
|
||||
/// <param name="options">The options.</param>
|
|
||||
/// <returns>
|
|
||||
/// The Image
|
|
||||
/// </returns>
|
|
||||
public static Image<TColor> DrawPolygon<TColor>(this Image<TColor> source, TColor color, float thickness, Vector2[] points, GraphicsOptions options) |
|
||||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|
||||
{ |
|
||||
return source.DrawPolygon(new SolidBrush<TColor>(color), thickness, points, options); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the provided Points as a closed Linear Polygon with the provided Pen.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The source.</param>
|
|
||||
/// <param name="pen">The pen.</param>
|
|
||||
/// <param name="points">The points.</param>
|
|
||||
/// <param name="options">The options.</param>
|
|
||||
/// <returns>
|
|
||||
/// The Image
|
|
||||
/// </returns>
|
|
||||
public static Image<TColor> DrawPolygon<TColor>(this Image<TColor> source, IPen<TColor> pen, Vector2[] points, GraphicsOptions options) |
|
||||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|
||||
{ |
|
||||
return source.DrawPolygon(pen, new Polygon(new LinearLineSegment(points)), options); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the provided Points as a closed Linear Polygon with the provided Pen.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The source.</param>
|
|
||||
/// <param name="pen">The pen.</param>
|
|
||||
/// <param name="points">The points.</param>
|
|
||||
/// <returns>The Image</returns>
|
|
||||
public static Image<TColor> DrawPolygon<TColor>(this Image<TColor> source, IPen<TColor> pen, Vector2[] points) |
|
||||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|
||||
{ |
|
||||
return source.DrawPolygon(pen, new Polygon(new LinearLineSegment(points))); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the path with the provided pen.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The source.</param>
|
|
||||
/// <param name="pen">The pen.</param>
|
|
||||
/// <param name="path">The path.</param>
|
|
||||
/// <param name="options">The options.</param>
|
|
||||
/// <returns>
|
|
||||
/// The Image
|
|
||||
/// </returns>
|
|
||||
public static Image<TColor> DrawPath<TColor>(this Image<TColor> source, IPen<TColor> pen, IPath path, GraphicsOptions options) |
|
||||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|
||||
{ |
|
||||
return source.Apply(new DrawPathProcessor<TColor>(pen, path, options)); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the path with the provided pen.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The source.</param>
|
|
||||
/// <param name="pen">The pen.</param>
|
|
||||
/// <param name="path">The path.</param>
|
|
||||
/// <returns>The Image</returns>
|
|
||||
public static Image<TColor> DrawPath<TColor>(this Image<TColor> source, IPen<TColor> pen, IPath path) |
|
||||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|
||||
{ |
|
||||
return source.Apply(new DrawPathProcessor<TColor>(pen, path, GraphicsOptions.Default)); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the path with the bursh at the privdied thickness.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The source.</param>
|
|
||||
/// <param name="brush">The brush.</param>
|
|
||||
/// <param name="thickness">The thickness.</param>
|
|
||||
/// <param name="path">The path.</param>
|
|
||||
/// <param name="options">The options.</param>
|
|
||||
/// <returns>
|
|
||||
/// The Image
|
|
||||
/// </returns>
|
|
||||
public static Image<TColor> DrawPath<TColor>(this Image<TColor> source, IBrush<TColor> brush, float thickness, IPath path, GraphicsOptions options) |
|
||||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|
||||
{ |
|
||||
return source.DrawPath(new Pen<TColor>(brush, thickness), path, options); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the path with the bursh at the privdied thickness.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The source.</param>
|
|
||||
/// <param name="brush">The brush.</param>
|
|
||||
/// <param name="thickness">The thickness.</param>
|
|
||||
/// <param name="path">The path.</param>
|
|
||||
/// <returns>The Image</returns>
|
|
||||
public static Image<TColor> DrawPath<TColor>(this Image<TColor> source, IBrush<TColor> brush, float thickness, IPath path) |
|
||||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|
||||
{ |
|
||||
return source.DrawPath(new Pen<TColor>(brush, thickness), path); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the path with the bursh at the privdied thickness.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The source.</param>
|
|
||||
/// <param name="color">The color.</param>
|
|
||||
/// <param name="thickness">The thickness.</param>
|
|
||||
/// <param name="path">The path.</param>
|
|
||||
/// <param name="options">The options.</param>
|
|
||||
/// <returns>
|
|
||||
/// The Image
|
|
||||
/// </returns>
|
|
||||
public static Image<TColor> DrawPath<TColor>(this Image<TColor> source, TColor color, float thickness, IPath path, GraphicsOptions options) |
|
||||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|
||||
{ |
|
||||
return source.DrawPath(new SolidBrush<TColor>(color), thickness, path, options); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the path with the bursh at the privdied thickness.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The source.</param>
|
|
||||
/// <param name="color">The color.</param>
|
|
||||
/// <param name="thickness">The thickness.</param>
|
|
||||
/// <param name="path">The path.</param>
|
|
||||
/// <returns>The Image</returns>
|
|
||||
public static Image<TColor> DrawPath<TColor>(this Image<TColor> source, TColor color, float thickness, IPath path) |
|
||||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|
||||
{ |
|
||||
return source.DrawPath(new SolidBrush<TColor>(color), thickness, path); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the provided Points as an open Linear path at the provided thickness with the supplied brush
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The source.</param>
|
|
||||
/// <param name="brush">The brush.</param>
|
|
||||
/// <param name="thickness">The thickness.</param>
|
|
||||
/// <param name="points">The points.</param>
|
|
||||
/// <param name="options">The options.</param>
|
|
||||
/// <returns>
|
|
||||
/// The Image
|
|
||||
/// </returns>
|
|
||||
public static Image<TColor> DrawLines<TColor>(this Image<TColor> source, IBrush<TColor> brush, float thickness, Vector2[] points, GraphicsOptions options) |
|
||||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|
||||
{ |
|
||||
return source.DrawPath(new Pen<TColor>(brush, thickness), new Path(new LinearLineSegment(points)), options); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the provided Points as an open Linear path at the provided thickness with the supplied brush
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The source.</param>
|
|
||||
/// <param name="brush">The brush.</param>
|
|
||||
/// <param name="thickness">The thickness.</param>
|
|
||||
/// <param name="points">The points.</param>
|
|
||||
/// <returns>The Image</returns>
|
|
||||
public static Image<TColor> DrawLines<TColor>(this Image<TColor> source, IBrush<TColor> brush, float thickness, Vector2[] points) |
|
||||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|
||||
{ |
|
||||
return source.DrawPath(new Pen<TColor>(brush, thickness), new Path(new LinearLineSegment(points))); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the provided Points as an open Linear path at the provided thickness with the supplied brush
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The source.</param>
|
|
||||
/// <param name="color">The color.</param>
|
|
||||
/// <param name="thickness">The thickness.</param>
|
|
||||
/// <param name="points">The points.</param>
|
|
||||
/// <returns>The Image</returns>
|
|
||||
public static Image<TColor> DrawLines<TColor>(this Image<TColor> source, TColor color, float thickness, Vector2[] points) |
|
||||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|
||||
{ |
|
||||
return source.DrawLines(new SolidBrush<TColor>(color), thickness, points); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the provided Points as an open Linear path at the provided thickness with the supplied brush
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The source.</param>
|
|
||||
/// <param name="color">The color.</param>
|
|
||||
/// <param name="thickness">The thickness.</param>
|
|
||||
/// <param name="points">The points.</param>
|
|
||||
/// <param name="options">The options.</param>
|
|
||||
/// <returns>
|
|
||||
/// The Image
|
|
||||
/// </returns>
|
|
||||
public static Image<TColor> DrawLines<TColor>(this Image<TColor> source, TColor color, float thickness, Vector2[] points, GraphicsOptions options) |
|
||||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|
||||
{ |
|
||||
return source.DrawLines(new SolidBrush<TColor>(color), thickness, points, options); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the provided Points as an open Linear path with the supplied pen
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The source.</param>
|
|
||||
/// <param name="pen">The pen.</param>
|
|
||||
/// <param name="points">The points.</param>
|
|
||||
/// <param name="options">The options.</param>
|
|
||||
/// <returns>
|
|
||||
/// The Image
|
|
||||
/// </returns>
|
|
||||
public static Image<TColor> DrawLines<TColor>(this Image<TColor> source, IPen<TColor> pen, Vector2[] points, GraphicsOptions options) |
|
||||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|
||||
{ |
|
||||
return source.DrawPath(pen, new Path(new LinearLineSegment(points)), options); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the provided Points as an open Linear path with the supplied pen
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The source.</param>
|
|
||||
/// <param name="pen">The pen.</param>
|
|
||||
/// <param name="points">The points.</param>
|
|
||||
/// <returns>The Image</returns>
|
|
||||
public static Image<TColor> DrawLines<TColor>(this Image<TColor> source, IPen<TColor> pen, Vector2[] points) |
|
||||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|
||||
{ |
|
||||
return source.DrawPath(pen, new Path(new LinearLineSegment(points))); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the provided Points as an open Bezier path at the provided thickness with the supplied brush
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The source.</param>
|
|
||||
/// <param name="brush">The brush.</param>
|
|
||||
/// <param name="thickness">The thickness.</param>
|
|
||||
/// <param name="points">The points.</param>
|
|
||||
/// <param name="options">The options.</param>
|
|
||||
/// <returns>
|
|
||||
/// The Image
|
|
||||
/// </returns>
|
|
||||
public static Image<TColor> DrawBeziers<TColor>(this Image<TColor> source, IBrush<TColor> brush, float thickness, Vector2[] points, GraphicsOptions options) |
|
||||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|
||||
{ |
|
||||
return source.DrawPath(new Pen<TColor>(brush, thickness), new Path(new BezierLineSegment(points)), options); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the provided Points as an open Bezier path at the provided thickness with the supplied brush
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The source.</param>
|
|
||||
/// <param name="brush">The brush.</param>
|
|
||||
/// <param name="thickness">The thickness.</param>
|
|
||||
/// <param name="points">The points.</param>
|
|
||||
/// <returns>The Image</returns>
|
|
||||
public static Image<TColor> DrawBeziers<TColor>(this Image<TColor> source, IBrush<TColor> brush, float thickness, Vector2[] points) |
|
||||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|
||||
{ |
|
||||
return source.DrawPath(new Pen<TColor>(brush, thickness), new Path(new BezierLineSegment(points))); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the provided Points as an open Bezier path at the provided thickness with the supplied brush
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The source.</param>
|
|
||||
/// <param name="color">The color.</param>
|
|
||||
/// <param name="thickness">The thickness.</param>
|
|
||||
/// <param name="points">The points.</param>
|
|
||||
/// <returns>The Image</returns>
|
|
||||
public static Image<TColor> DrawBeziers<TColor>(this Image<TColor> source, TColor color, float thickness, Vector2[] points) |
|
||||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|
||||
{ |
|
||||
return source.DrawBeziers(new SolidBrush<TColor>(color), thickness, points); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the provided Points as an open Bezier path at the provided thickness with the supplied brush
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The source.</param>
|
|
||||
/// <param name="color">The color.</param>
|
|
||||
/// <param name="thickness">The thickness.</param>
|
|
||||
/// <param name="points">The points.</param>
|
|
||||
/// <param name="options">The options.</param>
|
|
||||
/// <returns>
|
|
||||
/// The Image
|
|
||||
/// </returns>
|
|
||||
public static Image<TColor> DrawBeziers<TColor>(this Image<TColor> source, TColor color, float thickness, Vector2[] points, GraphicsOptions options) |
|
||||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|
||||
{ |
|
||||
return source.DrawBeziers(new SolidBrush<TColor>(color), thickness, points, options); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the provided Points as an open Bezier path with the supplied pen
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The source.</param>
|
|
||||
/// <param name="pen">The pen.</param>
|
|
||||
/// <param name="points">The points.</param>
|
|
||||
/// <param name="options">The options.</param>
|
|
||||
/// <returns>
|
|
||||
/// The Image
|
|
||||
/// </returns>
|
|
||||
public static Image<TColor> DrawBeziers<TColor>(this Image<TColor> source, IPen<TColor> pen, Vector2[] points, GraphicsOptions options) |
|
||||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|
||||
{ |
|
||||
return source.DrawPath(pen, new Path(new BezierLineSegment(points)), options); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Draws the provided Points as an open Bezier path with the supplied pen
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The source.</param>
|
|
||||
/// <param name="pen">The pen.</param>
|
|
||||
/// <param name="points">The points.</param>
|
|
||||
/// <returns>The Image</returns>
|
|
||||
public static Image<TColor> DrawBeziers<TColor>(this Image<TColor> source, IPen<TColor> pen, Vector2[] points) |
|
||||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|
||||
{ |
|
||||
return source.DrawPath(pen, new Path(new BezierLineSegment(points))); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,111 @@ |
|||||
|
// <copyright file="DrawPath.cs" company="James Jackson-South">
|
||||
|
// Copyright (c) James Jackson-South and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>
|
||||
|
|
||||
|
namespace ImageSharp |
||||
|
{ |
||||
|
using System; |
||||
|
using System.Numerics; |
||||
|
using Drawing; |
||||
|
using Drawing.Brushes; |
||||
|
using Drawing.Pens; |
||||
|
using Drawing.Processors; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Extension methods for the <see cref="Image{TColor}"/> type.
|
||||
|
/// </summary>
|
||||
|
public static partial class ImageExtensions |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Draws the outline of the region with the provided pen.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TColor">The type of the color.</typeparam>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="pen">The pen.</param>
|
||||
|
/// <param name="path">The path.</param>
|
||||
|
/// <param name="options">The options.</param>
|
||||
|
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
||||
|
public static Image<TColor> Draw<TColor>(this Image<TColor> source, IPen<TColor> pen, Drawable path, GraphicsOptions options) |
||||
|
where TColor : struct, IPackedPixel, IEquatable<TColor> |
||||
|
{ |
||||
|
return source.Apply(new DrawPathProcessor<TColor>(pen, path, options)); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Draws the outline of the polygon with the provided pen.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TColor">The type of the color.</typeparam>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="pen">The pen.</param>
|
||||
|
/// <param name="path">The path.</param>
|
||||
|
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
||||
|
public static Image<TColor> Draw<TColor>(this Image<TColor> source, IPen<TColor> pen, Drawable path) |
||||
|
where TColor : struct, IPackedPixel, IEquatable<TColor> |
||||
|
{ |
||||
|
return source.Draw(pen, path, GraphicsOptions.Default); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Draws the outline of the polygon with the provided brush at the provided thickness.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TColor">The type of the color.</typeparam>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="brush">The brush.</param>
|
||||
|
/// <param name="thickness">The thickness.</param>
|
||||
|
/// <param name="path">The path.</param>
|
||||
|
/// <param name="options">The options.</param>
|
||||
|
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
||||
|
public static Image<TColor> Draw<TColor>(this Image<TColor> source, IBrush<TColor> brush, float thickness, Drawable path, GraphicsOptions options) |
||||
|
where TColor : struct, IPackedPixel, IEquatable<TColor> |
||||
|
{ |
||||
|
return source.Draw(new Pen<TColor>(brush, thickness), path, options); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Draws the outline of the polygon with the provided brush at the provided thickness.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TColor">The type of the color.</typeparam>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="brush">The brush.</param>
|
||||
|
/// <param name="thickness">The thickness.</param>
|
||||
|
/// <param name="path">The path.</param>
|
||||
|
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
||||
|
public static Image<TColor> Draw<TColor>(this Image<TColor> source, IBrush<TColor> brush, float thickness, Drawable path) |
||||
|
where TColor : struct, IPackedPixel, IEquatable<TColor> |
||||
|
{ |
||||
|
return source.Draw(new Pen<TColor>(brush, thickness), path); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Draws the outline of the polygon with the provided brush at the provided thickness.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TColor">The type of the color.</typeparam>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="color">The color.</param>
|
||||
|
/// <param name="thickness">The thickness.</param>
|
||||
|
/// <param name="path">The path.</param>
|
||||
|
/// <param name="options">The options.</param>
|
||||
|
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
||||
|
public static Image<TColor> Draw<TColor>(this Image<TColor> source, TColor color, float thickness, Drawable path, GraphicsOptions options) |
||||
|
where TColor : struct, IPackedPixel, IEquatable<TColor> |
||||
|
{ |
||||
|
return source.Draw(new SolidBrush<TColor>(color), thickness, path, options); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Draws the outline of the polygon with the provided brush at the provided thickness.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TColor">The type of the color.</typeparam>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="color">The color.</param>
|
||||
|
/// <param name="thickness">The thickness.</param>
|
||||
|
/// <param name="path">The path.</param>
|
||||
|
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
||||
|
public static Image<TColor> Draw<TColor>(this Image<TColor> source, TColor color, float thickness, Drawable path) |
||||
|
where TColor : struct, IPackedPixel, IEquatable<TColor> |
||||
|
{ |
||||
|
return source.Draw(new SolidBrush<TColor>(color), thickness, path); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,51 @@ |
|||||
|
// <copyright file="Drawable.cs" company="James Jackson-South">
|
||||
|
// Copyright (c) James Jackson-South and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>
|
||||
|
|
||||
|
namespace ImageSharp.Drawing |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Represents a path or set of paths that can be drawn as an outline.
|
||||
|
/// </summary>
|
||||
|
public abstract class Drawable |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Gets the maximum number of intersections to could be returned.
|
||||
|
/// </summary>
|
||||
|
public abstract int MaxIntersections { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the bounds.
|
||||
|
/// </summary>
|
||||
|
public abstract Rectangle Bounds { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the point information for the specified x and y location.
|
||||
|
/// </summary>
|
||||
|
/// <param name="x">The x.</param>
|
||||
|
/// <param name="y">The y.</param>
|
||||
|
/// <returns>Information about the point in relation to a drawable edge</returns>
|
||||
|
public abstract PointInfo GetPointInfo(int x, int y); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Scans the X axis for intersections.
|
||||
|
/// </summary>
|
||||
|
/// <param name="x">The x.</param>
|
||||
|
/// <param name="buffer">The buffer.</param>
|
||||
|
/// <param name="length">The length.</param>
|
||||
|
/// <param name="offset">The offset.</param>
|
||||
|
/// <returns>The number of intersections found.</returns>
|
||||
|
public abstract int ScanX(int x, float[] buffer, int length, int offset); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Scans the Y axis for intersections.
|
||||
|
/// </summary>
|
||||
|
/// <param name="y">The position along the y axis to find intersections.</param>
|
||||
|
/// <param name="buffer">The buffer.</param>
|
||||
|
/// <param name="length">The length.</param>
|
||||
|
/// <param name="offset">The offset.</param>
|
||||
|
/// <returns>The number of intersections found.</returns>
|
||||
|
public abstract int ScanY(int y, float[] buffer, int length, int offset); |
||||
|
} |
||||
|
} |
||||
@ -1,173 +0,0 @@ |
|||||
// <copyright file="Fill.cs" company="James Jackson-South">
|
|
||||
// Copyright (c) James Jackson-South and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
// </copyright>
|
|
||||
|
|
||||
namespace ImageSharp |
|
||||
{ |
|
||||
using System; |
|
||||
using System.Numerics; |
|
||||
using Drawing; |
|
||||
using Drawing.Brushes; |
|
||||
using Drawing.Paths; |
|
||||
using Drawing.Processors; |
|
||||
using Drawing.Shapes; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Extension methods for the <see cref="Image{TColor}"/> type.
|
|
||||
/// </summary>
|
|
||||
public static partial class ImageExtensions |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Flood fills the image with the specified brush.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The source.</param>
|
|
||||
/// <param name="brush">The brush.</param>
|
|
||||
/// <returns>The Image</returns>
|
|
||||
public static Image<TColor> Fill<TColor>(this Image<TColor> source, IBrush<TColor> brush) |
|
||||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|
||||
{ |
|
||||
return source.Apply(new FillProcessor<TColor>(brush)); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Flood fills the image with the specified color.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The source.</param>
|
|
||||
/// <param name="color">The color.</param>
|
|
||||
/// <returns>The Image</returns>
|
|
||||
public static Image<TColor> Fill<TColor>(this Image<TColor> source, TColor color) |
|
||||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|
||||
{ |
|
||||
return source.Fill(new SolidBrush<TColor>(color)); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Flood fills the image in the shape o fhte provided polygon with the specified brush..
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The source.</param>
|
|
||||
/// <param name="brush">The brush.</param>
|
|
||||
/// <param name="shape">The shape.</param>
|
|
||||
/// <param name="options">The graphics options.</param>
|
|
||||
/// <returns>The Image</returns>
|
|
||||
public static Image<TColor> Fill<TColor>(this Image<TColor> source, IBrush<TColor> brush, IShape shape, GraphicsOptions options) |
|
||||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|
||||
{ |
|
||||
return source.Apply(new FillShapeProcessor<TColor>(brush, shape, options)); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Flood fills the image in the shape of the provided polygon with the specified brush.
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The source.</param>
|
|
||||
/// <param name="brush">The brush.</param>
|
|
||||
/// <param name="shape">The shape.</param>
|
|
||||
/// <returns>The Image</returns>
|
|
||||
public static Image<TColor> Fill<TColor>(this Image<TColor> source, IBrush<TColor> brush, IShape shape) |
|
||||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|
||||
{ |
|
||||
return source.Apply(new FillShapeProcessor<TColor>(brush, shape, GraphicsOptions.Default)); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Flood fills the image in the shape o fhte provided polygon with the specified brush..
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The source.</param>
|
|
||||
/// <param name="color">The color.</param>
|
|
||||
/// <param name="shape">The shape.</param>
|
|
||||
/// <param name="options">The options.</param>
|
|
||||
/// <returns>
|
|
||||
/// The Image
|
|
||||
/// </returns>
|
|
||||
public static Image<TColor> Fill<TColor>(this Image<TColor> source, TColor color, IShape shape, GraphicsOptions options) |
|
||||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|
||||
{ |
|
||||
return source.Fill(new SolidBrush<TColor>(color), shape, options); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Flood fills the image in the shape o fhte provided polygon with the specified brush..
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The source.</param>
|
|
||||
/// <param name="color">The color.</param>
|
|
||||
/// <param name="shape">The shape.</param>
|
|
||||
/// <returns>The Image</returns>
|
|
||||
public static Image<TColor> Fill<TColor>(this Image<TColor> source, TColor color, IShape shape) |
|
||||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|
||||
{ |
|
||||
return source.Fill(new SolidBrush<TColor>(color), shape); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Flood fills the image in the shape of a Linear polygon described by the points
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The source.</param>
|
|
||||
/// <param name="brush">The brush.</param>
|
|
||||
/// <param name="points">The points.</param>
|
|
||||
/// <param name="options">The options.</param>
|
|
||||
/// <returns>
|
|
||||
/// The Image
|
|
||||
/// </returns>
|
|
||||
public static Image<TColor> FillPolygon<TColor>(this Image<TColor> source, IBrush<TColor> brush, Vector2[] points, GraphicsOptions options) |
|
||||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|
||||
{ |
|
||||
// using Polygon directly instead of LinearPolygon as its will have less indirection
|
|
||||
return source.Fill(brush, new Polygon(new LinearLineSegment(points)), options); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Flood fills the image in the shape of a Linear polygon described by the points
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The source.</param>
|
|
||||
/// <param name="brush">The brush.</param>
|
|
||||
/// <param name="points">The points.</param>
|
|
||||
/// <returns>The Image</returns>
|
|
||||
public static Image<TColor> FillPolygon<TColor>(this Image<TColor> source, IBrush<TColor> brush, Vector2[] points) |
|
||||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|
||||
{ |
|
||||
// using Polygon directly instead of LinearPolygon as its will have less indirection
|
|
||||
return source.Fill(brush, new Polygon(new LinearLineSegment(points))); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Flood fills the image in the shape of a Linear polygon described by the points
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The source.</param>
|
|
||||
/// <param name="color">The color.</param>
|
|
||||
/// <param name="points">The points.</param>
|
|
||||
/// <param name="options">The options.</param>
|
|
||||
/// <returns>
|
|
||||
/// The Image
|
|
||||
/// </returns>
|
|
||||
public static Image<TColor> FillPolygon<TColor>(this Image<TColor> source, TColor color, Vector2[] points, GraphicsOptions options) |
|
||||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|
||||
{ |
|
||||
// using Polygon directly instead of LinearPolygon as its will have less indirection
|
|
||||
return source.Fill(new SolidBrush<TColor>(color), new Polygon(new LinearLineSegment(points)), options); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Flood fills the image in the shape of a Linear polygon described by the points
|
|
||||
/// </summary>
|
|
||||
/// <typeparam name="TColor">The type of the color.</typeparam>
|
|
||||
/// <param name="source">The source.</param>
|
|
||||
/// <param name="color">The color.</param>
|
|
||||
/// <param name="points">The points.</param>
|
|
||||
/// <returns>The Image</returns>
|
|
||||
public static Image<TColor> FillPolygon<TColor>(this Image<TColor> source, TColor color, Vector2[] points) |
|
||||
where TColor : struct, IPackedPixel, IEquatable<TColor> |
|
||||
{ |
|
||||
// using Polygon directly instead of LinearPolygon as its will have less indirection
|
|
||||
return source.Fill(new SolidBrush<TColor>(color), new Polygon(new LinearLineSegment(points))); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,103 @@ |
|||||
|
// <copyright file="FillRegion.cs" company="James Jackson-South">
|
||||
|
// Copyright (c) James Jackson-South and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>
|
||||
|
|
||||
|
namespace ImageSharp |
||||
|
{ |
||||
|
using System; |
||||
|
using System.Numerics; |
||||
|
using Drawing; |
||||
|
using Drawing.Brushes; |
||||
|
using Drawing.Processors; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Extension methods for the <see cref="Image{TColor}"/> type.
|
||||
|
/// </summary>
|
||||
|
public static partial class ImageExtensions |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Flood fills the image with the specified brush.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TColor">The type of the color.</typeparam>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="brush">The details how to fill the region of interest.</param>
|
||||
|
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
||||
|
public static Image<TColor> Fill<TColor>(this Image<TColor> source, IBrush<TColor> brush) |
||||
|
where TColor : struct, IPackedPixel, IEquatable<TColor> |
||||
|
{ |
||||
|
return source.Apply(new FillProcessor<TColor>(brush)); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Flood fills the image with the specified color.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TColor">The type of the color.</typeparam>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="color">The color.</param>
|
||||
|
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
||||
|
public static Image<TColor> Fill<TColor>(this Image<TColor> source, TColor color) |
||||
|
where TColor : struct, IPackedPixel, IEquatable<TColor> |
||||
|
{ |
||||
|
return source.Fill(new SolidBrush<TColor>(color)); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Flood fills the image with in the region with the specified brush.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TColor">The type of the color.</typeparam>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="brush">The brush.</param>
|
||||
|
/// <param name="region">The region.</param>
|
||||
|
/// <param name="options">The graphics options.</param>
|
||||
|
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
||||
|
public static Image<TColor> Fill<TColor>(this Image<TColor> source, IBrush<TColor> brush, Region region, GraphicsOptions options) |
||||
|
where TColor : struct, IPackedPixel, IEquatable<TColor> |
||||
|
{ |
||||
|
return source.Apply(new FillRegionProcessor<TColor>(brush, region, options)); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Flood fills the image with in the region with the specified brush.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TColor">The type of the color.</typeparam>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="brush">The brush.</param>
|
||||
|
/// <param name="region">The region.</param>
|
||||
|
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
||||
|
public static Image<TColor> Fill<TColor>(this Image<TColor> source, IBrush<TColor> brush, Region region) |
||||
|
where TColor : struct, IPackedPixel, IEquatable<TColor> |
||||
|
{ |
||||
|
return source.Fill(brush, region, GraphicsOptions.Default); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Flood fills the image with in the region with the specified color.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TColor">The type of the color.</typeparam>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="color">The color.</param>
|
||||
|
/// <param name="region">The region.</param>
|
||||
|
/// <param name="options">The options.</param>
|
||||
|
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
||||
|
public static Image<TColor> Fill<TColor>(this Image<TColor> source, TColor color, Region region, GraphicsOptions options) |
||||
|
where TColor : struct, IPackedPixel, IEquatable<TColor> |
||||
|
{ |
||||
|
return source.Fill(new SolidBrush<TColor>(color), region, options); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Flood fills the image with in the region with the specified color.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TColor">The type of the color.</typeparam>
|
||||
|
/// <param name="source">The image this method extends.</param>
|
||||
|
/// <param name="color">The color.</param>
|
||||
|
/// <param name="region">The region.</param>
|
||||
|
/// <returns>The <see cref="Image{TColor}"/>.</returns>
|
||||
|
public static Image<TColor> Fill<TColor>(this Image<TColor> source, TColor color, Region region) |
||||
|
where TColor : struct, IPackedPixel, IEquatable<TColor> |
||||
|
{ |
||||
|
return source.Fill(new SolidBrush<TColor>(color), region); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,119 +0,0 @@ |
|||||
// <copyright file="BezierLineSegment.cs" company="James Jackson-South">
|
|
||||
// Copyright (c) James Jackson-South and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
// </copyright>
|
|
||||
|
|
||||
namespace ImageSharp.Drawing.Paths |
|
||||
{ |
|
||||
using System.Numerics; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Represents a line segment that conistst of control points that will be rendered as a cubic bezier curve
|
|
||||
/// </summary>
|
|
||||
/// <seealso cref="ImageSharp.Drawing.Paths.ILineSegment" />
|
|
||||
public class BezierLineSegment : ILineSegment |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// The segments per curve.
|
|
||||
/// code for this taken from <see href="http://devmag.org.za/2011/04/05/bzier-curves-a-tutorial/"/>
|
|
||||
/// </summary>
|
|
||||
private const int SegmentsPerCurve = 50; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// The line points.
|
|
||||
/// </summary>
|
|
||||
private readonly Vector2[] linePoints; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Initializes a new instance of the <see cref="BezierLineSegment"/> class.
|
|
||||
/// </summary>
|
|
||||
/// <param name="points">The points.</param>
|
|
||||
public BezierLineSegment(params Vector2[] points) |
|
||||
{ |
|
||||
Guard.NotNull(points, nameof(points)); |
|
||||
Guard.MustBeGreaterThanOrEqualTo(points.Length, 4, nameof(points)); |
|
||||
|
|
||||
this.linePoints = this.GetDrawingPoints(points); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Returns the current <see cref="ILineSegment" /> a simple linear path.
|
|
||||
/// </summary>
|
|
||||
/// <returns>
|
|
||||
/// Returns the current <see cref="ILineSegment" /> as simple linear path.
|
|
||||
/// </returns>
|
|
||||
public Vector2[] AsSimpleLinearPath() |
|
||||
{ |
|
||||
return this.linePoints; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Returns the drawing points along the line.
|
|
||||
/// </summary>
|
|
||||
/// <param name="controlPoints">The control points.</param>
|
|
||||
/// <returns>
|
|
||||
/// The <see cref="T:Vector2[]"/>.
|
|
||||
/// </returns>
|
|
||||
private Vector2[] GetDrawingPoints(Vector2[] controlPoints) |
|
||||
{ |
|
||||
// TODO we need to calculate an optimal SegmentsPerCurve value
|
|
||||
// depending on the calcualted length of this curve
|
|
||||
int curveCount = (controlPoints.Length - 1) / 3; |
|
||||
int finalPointCount = (SegmentsPerCurve * curveCount) + 1; // we have SegmentsPerCurve for each curve plus the origon point;
|
|
||||
|
|
||||
Vector2[] drawingPoints = new Vector2[finalPointCount]; |
|
||||
|
|
||||
int position = 0; |
|
||||
int targetPoint = controlPoints.Length - 3; |
|
||||
for (int i = 0; i < targetPoint; i += 3) |
|
||||
{ |
|
||||
Vector2 p0 = controlPoints[i]; |
|
||||
Vector2 p1 = controlPoints[i + 1]; |
|
||||
Vector2 p2 = controlPoints[i + 2]; |
|
||||
Vector2 p3 = controlPoints[i + 3]; |
|
||||
|
|
||||
// only do this for the first end point. When i != 0, this coincides with the end point of the previous segment,
|
|
||||
if (i == 0) |
|
||||
{ |
|
||||
drawingPoints[position++] = this.CalculateBezierPoint(0, p0, p1, p2, p3); |
|
||||
} |
|
||||
|
|
||||
for (int j = 1; j <= SegmentsPerCurve; j++) |
|
||||
{ |
|
||||
float t = j / (float)SegmentsPerCurve; |
|
||||
drawingPoints[position++] = this.CalculateBezierPoint(t, p0, p1, p2, p3); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
return drawingPoints; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Calculates the bezier point along the line.
|
|
||||
/// </summary>
|
|
||||
/// <param name="t">The position within the line.</param>
|
|
||||
/// <param name="p0">The p 0.</param>
|
|
||||
/// <param name="p1">The p 1.</param>
|
|
||||
/// <param name="p2">The p 2.</param>
|
|
||||
/// <param name="p3">The p 3.</param>
|
|
||||
/// <returns>
|
|
||||
/// The <see cref="Vector2"/>.
|
|
||||
/// </returns>
|
|
||||
private Vector2 CalculateBezierPoint(float t, Vector2 p0, Vector2 p1, Vector2 p2, Vector2 p3) |
|
||||
{ |
|
||||
float u = 1 - t; |
|
||||
float tt = t * t; |
|
||||
float uu = u * u; |
|
||||
float uuu = uu * u; |
|
||||
float ttt = tt * t; |
|
||||
|
|
||||
Vector2 p = uuu * p0; // first term
|
|
||||
|
|
||||
p += 3 * uu * t * p1; // second term
|
|
||||
p += 3 * u * tt * p2; // third term
|
|
||||
p += ttt * p3; // fourth term
|
|
||||
|
|
||||
return p; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,21 +0,0 @@ |
|||||
// <copyright file="ILineSegment.cs" company="James Jackson-South">
|
|
||||
// Copyright (c) James Jackson-South and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
// </copyright>
|
|
||||
|
|
||||
namespace ImageSharp.Drawing.Paths |
|
||||
{ |
|
||||
using System.Numerics; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Represents a simple path segment
|
|
||||
/// </summary>
|
|
||||
public interface ILineSegment |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Converts the <see cref="ILineSegment" /> into a simple linear path..
|
|
||||
/// </summary>
|
|
||||
/// <returns>Returns the current <see cref="ILineSegment" /> as simple linear path.</returns>
|
|
||||
Vector2[] AsSimpleLinearPath(); // TODO move this over to ReadonlySpan<Vector2> once available
|
|
||||
} |
|
||||
} |
|
||||
@ -1,48 +0,0 @@ |
|||||
// <copyright file="IPath.cs" company="James Jackson-South">
|
|
||||
// Copyright (c) James Jackson-South and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
// </copyright>
|
|
||||
|
|
||||
namespace ImageSharp.Drawing.Paths |
|
||||
{ |
|
||||
using System.Numerics; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Represents a logic path that can be drawn
|
|
||||
/// </summary>
|
|
||||
public interface IPath : ILineSegment |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Gets the bounds enclosing the path
|
|
||||
/// </summary>
|
|
||||
/// <value>
|
|
||||
/// The bounds.
|
|
||||
/// </value>
|
|
||||
RectangleF Bounds { get; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets a value indicating whether this instance is closed.
|
|
||||
/// </summary>
|
|
||||
/// <value>
|
|
||||
/// <c>true</c> if this instance is closed; otherwise, <c>false</c>.
|
|
||||
/// </value>
|
|
||||
bool IsClosed { get; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the length of the path
|
|
||||
/// </summary>
|
|
||||
/// <value>
|
|
||||
/// The length.
|
|
||||
/// </value>
|
|
||||
float Length { get; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Calculates the distance along and away from the path for a specified point.
|
|
||||
/// </summary>
|
|
||||
/// <param name="point">The point along the path.</param>
|
|
||||
/// <returns>
|
|
||||
/// Returns details about the point and its distance away from the path.
|
|
||||
/// </returns>
|
|
||||
PointInfo Distance(Vector2 point); |
|
||||
} |
|
||||
} |
|
||||
@ -1,516 +0,0 @@ |
|||||
// <copyright file="InternalPath.cs" company="James Jackson-South">
|
|
||||
// Copyright (c) James Jackson-South and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
// </copyright>
|
|
||||
namespace ImageSharp.Drawing.Paths |
|
||||
{ |
|
||||
using System; |
|
||||
using System.Collections.Generic; |
|
||||
using System.Linq; |
|
||||
using System.Numerics; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Internal logic for integrating linear paths.
|
|
||||
/// </summary>
|
|
||||
internal class InternalPath |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// The maximum vector
|
|
||||
/// </summary>
|
|
||||
private static readonly Vector2 MaxVector = new Vector2(float.MaxValue); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// The locker.
|
|
||||
/// </summary>
|
|
||||
private static readonly object Locker = new object(); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// The points.
|
|
||||
/// </summary>
|
|
||||
private readonly Vector2[] points; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// The closed path.
|
|
||||
/// </summary>
|
|
||||
private readonly bool closedPath; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// The total distance.
|
|
||||
/// </summary>
|
|
||||
private readonly Lazy<float> totalDistance; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// The constant.
|
|
||||
/// </summary>
|
|
||||
private float[] constant; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// The multiples.
|
|
||||
/// </summary>
|
|
||||
private float[] multiple; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// The distances.
|
|
||||
/// </summary>
|
|
||||
private float[] distance; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// The calculated.
|
|
||||
/// </summary>
|
|
||||
private bool calculated = false; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Initializes a new instance of the <see cref="InternalPath"/> class.
|
|
||||
/// </summary>
|
|
||||
/// <param name="segments">The segments.</param>
|
|
||||
/// <param name="isClosedPath">if set to <c>true</c> [is closed path].</param>
|
|
||||
internal InternalPath(ILineSegment[] segments, bool isClosedPath) |
|
||||
: this(Simplify(segments), isClosedPath) |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Initializes a new instance of the <see cref="InternalPath" /> class.
|
|
||||
/// </summary>
|
|
||||
/// <param name="segment">The segment.</param>
|
|
||||
/// <param name="isClosedPath">if set to <c>true</c> [is closed path].</param>
|
|
||||
internal InternalPath(ILineSegment segment, bool isClosedPath) |
|
||||
: this(segment.AsSimpleLinearPath(), isClosedPath) |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Initializes a new instance of the <see cref="InternalPath" /> class.
|
|
||||
/// </summary>
|
|
||||
/// <param name="points">The points.</param>
|
|
||||
/// <param name="isClosedPath">if set to <c>true</c> [is closed path].</param>
|
|
||||
internal InternalPath(Vector2[] points, bool isClosedPath) |
|
||||
{ |
|
||||
this.points = points; |
|
||||
this.closedPath = isClosedPath; |
|
||||
|
|
||||
float minX = this.points.Min(x => x.X); |
|
||||
float maxX = this.points.Max(x => x.X); |
|
||||
float minY = this.points.Min(x => x.Y); |
|
||||
float maxY = this.points.Max(x => x.Y); |
|
||||
|
|
||||
this.Bounds = new RectangleF(minX, minY, maxX - minX, maxY - minY); |
|
||||
this.totalDistance = new Lazy<float>(this.CalculateLength); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the bounds.
|
|
||||
/// </summary>
|
|
||||
/// <value>
|
|
||||
/// The bounds.
|
|
||||
/// </value>
|
|
||||
public RectangleF Bounds |
|
||||
{ |
|
||||
get; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the length.
|
|
||||
/// </summary>
|
|
||||
/// <value>
|
|
||||
/// The length.
|
|
||||
/// </value>
|
|
||||
public float Length => this.totalDistance.Value; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the points.
|
|
||||
/// </summary>
|
|
||||
/// <value>
|
|
||||
/// The points.
|
|
||||
/// </value>
|
|
||||
internal Vector2[] Points => this.points; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Calculates the distance from the path.
|
|
||||
/// </summary>
|
|
||||
/// <param name="point">The point.</param>
|
|
||||
/// <returns>Returns the distance from the path</returns>
|
|
||||
public PointInfo DistanceFromPath(Vector2 point) |
|
||||
{ |
|
||||
this.CalculateConstants(); |
|
||||
|
|
||||
PointInfoInternal internalInfo = default(PointInfoInternal); |
|
||||
internalInfo.DistanceSquared = float.MaxValue; // Set it to max so that CalculateShorterDistance can reduce it back down
|
|
||||
|
|
||||
int polyCorners = this.points.Length; |
|
||||
|
|
||||
if (!this.closedPath) |
|
||||
{ |
|
||||
polyCorners -= 1; |
|
||||
} |
|
||||
|
|
||||
int closestPoint = 0; |
|
||||
for (int i = 0; i < polyCorners; i++) |
|
||||
{ |
|
||||
int next = i + 1; |
|
||||
if (this.closedPath && next == polyCorners) |
|
||||
{ |
|
||||
next = 0; |
|
||||
} |
|
||||
|
|
||||
if (this.CalculateShorterDistance(this.points[i], this.points[next], point, ref internalInfo)) |
|
||||
{ |
|
||||
closestPoint = i; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
return new PointInfo |
|
||||
{ |
|
||||
DistanceAlongPath = this.distance[closestPoint] + Vector2.Distance(this.points[closestPoint], point), |
|
||||
DistanceFromPath = (float)Math.Sqrt(internalInfo.DistanceSquared), |
|
||||
SearchPoint = point, |
|
||||
ClosestPointOnPath = internalInfo.PointOnLine |
|
||||
}; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 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>
|
|
||||
/// <param name="start">The start.</param>
|
|
||||
/// <param name="end">The end.</param>
|
|
||||
/// <param name="buffer">The buffer.</param>
|
|
||||
/// <param name="count">The count.</param>
|
|
||||
/// <param name="offset">The offset.</param>
|
|
||||
/// <returns>number iof intersections hit</returns>
|
|
||||
public int FindIntersections(Vector2 start, Vector2 end, Vector2[] buffer, int count, int offset) |
|
||||
{ |
|
||||
int polyCorners = this.points.Length; |
|
||||
|
|
||||
if (!this.closedPath) |
|
||||
{ |
|
||||
polyCorners -= 1; |
|
||||
} |
|
||||
|
|
||||
int position = 0; |
|
||||
for (int i = 0; i < polyCorners && count > 0; i++) |
|
||||
{ |
|
||||
int next = i + 1; |
|
||||
if (this.closedPath && next == polyCorners) |
|
||||
{ |
|
||||
next = 0; |
|
||||
} |
|
||||
|
|
||||
Vector2 point = FindIntersection(this.points[i], this.points[next], start, end); |
|
||||
if (point != MaxVector) |
|
||||
{ |
|
||||
buffer[position + offset] = point; |
|
||||
position++; |
|
||||
count--; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
return position; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Determines if the specified point is inside or outside the path.
|
|
||||
/// </summary>
|
|
||||
/// <param name="point">The point.</param>
|
|
||||
/// <returns>Returns true if the point is inside the closed path.</returns>
|
|
||||
public bool PointInPolygon(Vector2 point) |
|
||||
{ |
|
||||
// You can only be inside a path if its "closed"
|
|
||||
if (!this.closedPath) |
|
||||
{ |
|
||||
return false; |
|
||||
} |
|
||||
|
|
||||
if (!this.Bounds.Contains(point.X, point.Y)) |
|
||||
{ |
|
||||
return false; |
|
||||
} |
|
||||
|
|
||||
this.CalculateConstants(); |
|
||||
|
|
||||
Vector2[] poly = this.points; |
|
||||
int polyCorners = poly.Length; |
|
||||
|
|
||||
int j = polyCorners - 1; |
|
||||
bool oddNodes = false; |
|
||||
|
|
||||
for (int i = 0; i < polyCorners; i++) |
|
||||
{ |
|
||||
if ((poly[i].Y < point.Y && poly[j].Y >= point.Y) |
|
||||
|| (poly[j].Y < point.Y && poly[i].Y >= point.Y)) |
|
||||
{ |
|
||||
oddNodes ^= (point.Y * this.multiple[i]) + this.constant[i] < point.X; |
|
||||
} |
|
||||
|
|
||||
j = i; |
|
||||
} |
|
||||
|
|
||||
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 true it the bounding box of the 2 lines intersect</returns>
|
|
||||
private static bool BoundingBoxesIntersect(Vector2 line1Start, Vector2 line1End, Vector2 line2Start, Vector2 line2End) |
|
||||
{ |
|
||||
Vector2 topLeft1 = Vector2.Min(line1Start, line1End); |
|
||||
Vector2 bottomRight1 = Vector2.Max(line1Start, line1End); |
|
||||
|
|
||||
Vector2 topLeft2 = Vector2.Min(line2Start, line2End); |
|
||||
Vector2 bottomRight2 = Vector2.Max(line2Start, line2End); |
|
||||
|
|
||||
float left1 = topLeft1.X; |
|
||||
float right1 = bottomRight1.X; |
|
||||
float top1 = topLeft1.Y; |
|
||||
float bottom1 = bottomRight1.Y; |
|
||||
|
|
||||
float left2 = topLeft2.X; |
|
||||
float right2 = bottomRight2.X; |
|
||||
float top2 = topLeft2.Y; |
|
||||
float bottom2 = bottomRight2.Y; |
|
||||
|
|
||||
return left1 <= right2 && right1 >= left2 |
|
||||
&& |
|
||||
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) |
|
||||
{ |
|
||||
// do bounding boxes overlap, if not then the lines can't and return fast.
|
|
||||
if (!BoundingBoxesIntersect(line1Start, line1End, line2Start, line2End)) |
|
||||
{ |
|
||||
return MaxVector; |
|
||||
} |
|
||||
|
|
||||
Vector2 line1Diff = line1End - line1Start; |
|
||||
Vector2 line2Diff = line2End - line2Start; |
|
||||
|
|
||||
Vector2 point; |
|
||||
if (line1Diff.X == 0) |
|
||||
{ |
|
||||
float slope = line2Diff.Y / line2Diff.X; |
|
||||
float yinter = line2Start.Y - (slope * line2Start.X); |
|
||||
float y = (line1Start.X * slope) + yinter; |
|
||||
point = new Vector2(line1Start.X, y); |
|
||||
|
|
||||
// horizontal and vertical lines
|
|
||||
} |
|
||||
else if (line2Diff.X == 0) |
|
||||
{ |
|
||||
float slope = line1Diff.Y / line1Diff.X; |
|
||||
float yinter = line1Start.Y - (slope * line1Start.X); |
|
||||
float y = (line2Start.X * slope) + yinter; |
|
||||
point = new Vector2(line2Start.X, y); |
|
||||
|
|
||||
// horizontal and vertical lines
|
|
||||
} |
|
||||
else |
|
||||
{ |
|
||||
float slope1 = line1Diff.Y / line1Diff.X; |
|
||||
float slope2 = line2Diff.Y / line2Diff.X; |
|
||||
|
|
||||
float yinter1 = line1Start.Y - (slope1 * line1Start.X); |
|
||||
float yinter2 = line2Start.Y - (slope2 * line2Start.X); |
|
||||
|
|
||||
if (slope1 == slope2 && yinter1 != yinter2) |
|
||||
{ |
|
||||
return MaxVector; |
|
||||
} |
|
||||
|
|
||||
float x = (yinter2 - yinter1) / (slope1 - slope2); |
|
||||
float y = (slope1 * x) + yinter1; |
|
||||
|
|
||||
point = new Vector2(x, y); |
|
||||
} |
|
||||
|
|
||||
if (BoundingBoxesIntersect(line1Start, line1End, point, point)) |
|
||||
{ |
|
||||
return point; |
|
||||
} |
|
||||
else if (BoundingBoxesIntersect(line2Start, line2End, point, point)) |
|
||||
{ |
|
||||
return point; |
|
||||
} |
|
||||
|
|
||||
return MaxVector; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Simplifies the collection of segments.
|
|
||||
/// </summary>
|
|
||||
/// <param name="segments">The segments.</param>
|
|
||||
/// <returns>
|
|
||||
/// The <see cref="T:Vector2[]"/>.
|
|
||||
/// </returns>
|
|
||||
private static Vector2[] Simplify(ILineSegment[] segments) |
|
||||
{ |
|
||||
List<Vector2> simplified = new List<Vector2>(); |
|
||||
foreach (ILineSegment seg in segments) |
|
||||
{ |
|
||||
simplified.AddRange(seg.AsSimpleLinearPath()); |
|
||||
} |
|
||||
|
|
||||
return simplified.ToArray(); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Returns the length of the path.
|
|
||||
/// </summary>
|
|
||||
/// <returns>
|
|
||||
/// The <see cref="float"/>.
|
|
||||
/// </returns>
|
|
||||
private float CalculateLength() |
|
||||
{ |
|
||||
float length = 0; |
|
||||
int polyCorners = this.points.Length; |
|
||||
|
|
||||
if (!this.closedPath) |
|
||||
{ |
|
||||
polyCorners -= 1; |
|
||||
} |
|
||||
|
|
||||
for (int i = 0; i < polyCorners; i++) |
|
||||
{ |
|
||||
int next = i + 1; |
|
||||
if (this.closedPath && next == polyCorners) |
|
||||
{ |
|
||||
next = 0; |
|
||||
} |
|
||||
|
|
||||
length += Vector2.Distance(this.points[i], this.points[next]); |
|
||||
} |
|
||||
|
|
||||
return length; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Calculate the constants.
|
|
||||
/// </summary>
|
|
||||
private void CalculateConstants() |
|
||||
{ |
|
||||
// http://alienryderflex.com/polygon/ source for point in polygon logic
|
|
||||
if (this.calculated) |
|
||||
{ |
|
||||
return; |
|
||||
} |
|
||||
|
|
||||
lock (Locker) |
|
||||
{ |
|
||||
if (this.calculated) |
|
||||
{ |
|
||||
return; |
|
||||
} |
|
||||
|
|
||||
Vector2[] poly = this.points; |
|
||||
int polyCorners = poly.Length; |
|
||||
this.constant = new float[polyCorners]; |
|
||||
this.multiple = new float[polyCorners]; |
|
||||
this.distance = new float[polyCorners]; |
|
||||
int i, j = polyCorners - 1; |
|
||||
|
|
||||
this.distance[0] = 0; |
|
||||
|
|
||||
for (i = 0; i < polyCorners; i++) |
|
||||
{ |
|
||||
this.distance[j] = this.distance[i] + Vector2.Distance(poly[i], poly[j]); |
|
||||
if (poly[j].Y == poly[i].Y) |
|
||||
{ |
|
||||
this.constant[i] = poly[i].X; |
|
||||
this.multiple[i] = 0; |
|
||||
} |
|
||||
else |
|
||||
{ |
|
||||
Vector2 subtracted = poly[j] - poly[i]; |
|
||||
this.constant[i] = (poly[i].X - ((poly[i].Y * poly[j].X) / subtracted.Y)) + ((poly[i].Y * poly[i].X) / subtracted.Y); |
|
||||
this.multiple[i] = subtracted.X / subtracted.Y; |
|
||||
} |
|
||||
|
|
||||
j = i; |
|
||||
} |
|
||||
|
|
||||
this.calculated = true; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Calculate any shorter distances along the path.
|
|
||||
/// </summary>
|
|
||||
/// <param name="start">The start position.</param>
|
|
||||
/// <param name="end">The end position.</param>
|
|
||||
/// <param name="point">The current point.</param>
|
|
||||
/// <param name="info">The info.</param>
|
|
||||
/// <returns>
|
|
||||
/// The <see cref="bool"/>.
|
|
||||
/// </returns>
|
|
||||
private bool CalculateShorterDistance(Vector2 start, Vector2 end, Vector2 point, ref PointInfoInternal info) |
|
||||
{ |
|
||||
Vector2 diffEnds = end - start; |
|
||||
|
|
||||
float lengthSquared = diffEnds.LengthSquared(); |
|
||||
Vector2 diff = point - start; |
|
||||
|
|
||||
Vector2 multiplied = diff * diffEnds; |
|
||||
float u = (multiplied.X + multiplied.Y) / lengthSquared; |
|
||||
|
|
||||
if (u > 1) |
|
||||
{ |
|
||||
u = 1; |
|
||||
} |
|
||||
else if (u < 0) |
|
||||
{ |
|
||||
u = 0; |
|
||||
} |
|
||||
|
|
||||
Vector2 multipliedByU = diffEnds * u; |
|
||||
|
|
||||
Vector2 pointOnLine = start + multipliedByU; |
|
||||
|
|
||||
Vector2 d = pointOnLine - point; |
|
||||
|
|
||||
float dist = d.LengthSquared(); |
|
||||
|
|
||||
if (info.DistanceSquared > dist) |
|
||||
{ |
|
||||
info.DistanceSquared = dist; |
|
||||
info.PointOnLine = pointOnLine; |
|
||||
return true; |
|
||||
} |
|
||||
|
|
||||
return false; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Contains information about the current point.
|
|
||||
/// </summary>
|
|
||||
private struct PointInfoInternal |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// The distance squared.
|
|
||||
/// </summary>
|
|
||||
public float DistanceSquared; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// The point on the current line.
|
|
||||
/// </summary>
|
|
||||
public Vector2 PointOnLine; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,55 +0,0 @@ |
|||||
// <copyright file="LinearLineSegment.cs" company="James Jackson-South">
|
|
||||
// Copyright (c) James Jackson-South and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
// </copyright>
|
|
||||
|
|
||||
namespace ImageSharp.Drawing.Paths |
|
||||
{ |
|
||||
using System.Linq; |
|
||||
using System.Numerics; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Represents a series of control points that will be joined by straight lines
|
|
||||
/// </summary>
|
|
||||
/// <seealso cref="ILineSegment" />
|
|
||||
public class LinearLineSegment : ILineSegment |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// The collection of points.
|
|
||||
/// </summary>
|
|
||||
private readonly Vector2[] points; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Initializes a new instance of the <see cref="LinearLineSegment"/> class.
|
|
||||
/// </summary>
|
|
||||
/// <param name="start">The start.</param>
|
|
||||
/// <param name="end">The end.</param>
|
|
||||
public LinearLineSegment(Vector2 start, Vector2 end) |
|
||||
: this(new[] { start, end }) |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Initializes a new instance of the <see cref="LinearLineSegment"/> class.
|
|
||||
/// </summary>
|
|
||||
/// <param name="points">The points.</param>
|
|
||||
public LinearLineSegment(params Vector2[] points) |
|
||||
{ |
|
||||
Guard.NotNull(points, nameof(points)); |
|
||||
Guard.MustBeGreaterThanOrEqualTo(points.Count(), 2, nameof(points)); |
|
||||
|
|
||||
this.points = points; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Converts the <see cref="ILineSegment" /> into a simple linear path..
|
|
||||
/// </summary>
|
|
||||
/// <returns>
|
|
||||
/// Returns the current <see cref="ILineSegment" /> as simple linear path.
|
|
||||
/// </returns>
|
|
||||
public Vector2[] AsSimpleLinearPath() |
|
||||
{ |
|
||||
return this.points; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,51 +0,0 @@ |
|||||
// <copyright file="Path.cs" company="James Jackson-South">
|
|
||||
// Copyright (c) James Jackson-South and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
// </copyright>
|
|
||||
|
|
||||
namespace ImageSharp.Drawing.Paths |
|
||||
{ |
|
||||
using System.Numerics; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// A aggregate of <see cref="ILineSegment"/>s making a single logical path
|
|
||||
/// </summary>
|
|
||||
/// <seealso cref="IPath" />
|
|
||||
public class Path : IPath |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// The inner path.
|
|
||||
/// </summary>
|
|
||||
private readonly InternalPath innerPath; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Initializes a new instance of the <see cref="Path"/> class.
|
|
||||
/// </summary>
|
|
||||
/// <param name="segment">The segment.</param>
|
|
||||
public Path(params ILineSegment[] segment) |
|
||||
{ |
|
||||
this.innerPath = new InternalPath(segment, false); |
|
||||
} |
|
||||
|
|
||||
/// <inheritdoc />
|
|
||||
public RectangleF Bounds => this.innerPath.Bounds; |
|
||||
|
|
||||
/// <inheritdoc />
|
|
||||
public bool IsClosed => false; |
|
||||
|
|
||||
/// <inheritdoc />
|
|
||||
public float Length => this.innerPath.Length; |
|
||||
|
|
||||
/// <inheritdoc />
|
|
||||
public Vector2[] AsSimpleLinearPath() |
|
||||
{ |
|
||||
return this.innerPath.Points; |
|
||||
} |
|
||||
|
|
||||
/// <inheritdoc />
|
|
||||
public PointInfo Distance(Vector2 point) |
|
||||
{ |
|
||||
return this.innerPath.DistanceFromPath(point); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,35 +0,0 @@ |
|||||
// <copyright file="PointInfo.cs" company="James Jackson-South">
|
|
||||
// Copyright (c) James Jackson-South and contributors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
// </copyright>
|
|
||||
|
|
||||
namespace ImageSharp.Drawing.Paths |
|
||||
{ |
|
||||
using System.Numerics; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Returns meta data about the nearest point on a path from a vector
|
|
||||
/// </summary>
|
|
||||
public struct PointInfo |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// The search point
|
|
||||
/// </summary>
|
|
||||
public Vector2 SearchPoint; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// The distance along path <see cref="ClosestPointOnPath"/> is away from the start of the path
|
|
||||
/// </summary>
|
|
||||
public float DistanceAlongPath; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// The distance <see cref="SearchPoint"/> is away from <see cref="ClosestPointOnPath"/>.
|
|
||||
/// </summary>
|
|
||||
public float DistanceFromPath; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// The closest point to <see cref="SearchPoint"/> that lies on the path.
|
|
||||
/// </summary>
|
|
||||
public Vector2 ClosestPointOnPath; |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,26 @@ |
|||||
|
// <copyright file="PointInfo.cs" company="James Jackson-South">
|
||||
|
// Copyright (c) James Jackson-South and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>
|
||||
|
|
||||
|
namespace ImageSharp.Drawing |
||||
|
{ |
||||
|
using System; |
||||
|
using System.Numerics; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Returns details about how far away from the inside of a shape and the color the pixel could be.
|
||||
|
/// </summary>
|
||||
|
public struct PointInfo |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// The distance along path
|
||||
|
/// </summary>
|
||||
|
public float DistanceAlongPath; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// The distance from path
|
||||
|
/// </summary>
|
||||
|
public float DistanceFromPath; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,46 @@ |
|||||
|
// <copyright file="Region.cs" company="James Jackson-South">
|
||||
|
// Copyright (c) James Jackson-South and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>
|
||||
|
|
||||
|
namespace ImageSharp.Drawing |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Represents a region of an image.
|
||||
|
/// </summary>
|
||||
|
public abstract class Region |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Gets the maximum number of intersections to could be returned.
|
||||
|
/// </summary>
|
||||
|
public abstract int MaxIntersections { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the bounding box that entirly surrounds this region.
|
||||
|
/// </summary>
|
||||
|
/// <remarks>
|
||||
|
/// This should always contains all possible points returned from eather <see cref="ScanX(int, float[], int, int)"/> or <see cref="ScanY(int, float[], int, int)"/>.
|
||||
|
/// </remarks>
|
||||
|
public abstract Rectangle Bounds { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Scans the X axis for intersections.
|
||||
|
/// </summary>
|
||||
|
/// <param name="x">The position along the X axies to find intersections.</param>
|
||||
|
/// <param name="buffer">The buffer.</param>
|
||||
|
/// <param name="length">The length.</param>
|
||||
|
/// <param name="offset">The offset.</param>
|
||||
|
/// <returns>The number of intersections found.</returns>
|
||||
|
public abstract int ScanX(int x, float[] buffer, int length, int offset); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Scans the Y axis for intersections.
|
||||
|
/// </summary>
|
||||
|
/// <param name="y">The position along the y axis to find intersections.</param>
|
||||
|
/// <param name="buffer">The buffer.</param>
|
||||
|
/// <param name="length">The length.</param>
|
||||
|
/// <param name="offset">The offset.</param>
|
||||
|
/// <returns>The number of intersections found.</returns>
|
||||
|
public abstract int ScanY(int y, float[] buffer, int length, int offset); |
||||
|
} |
||||
|
} |
||||
@ -1,93 +0,0 @@ |
|||||
// <copyright file="BezierPolygon.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 |
|
||||
{ |
|
||||
using System.Collections; |
|
||||
using System.Collections.Generic; |
|
||||
using System.Numerics; |
|
||||
using Paths; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Represents a polygon made up exclusivly of a single close cubic Bezier curve.
|
|
||||
/// </summary>
|
|
||||
public sealed class BezierPolygon : IShape |
|
||||
{ |
|
||||
private Polygon innerPolygon; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Initializes a new instance of the <see cref="BezierPolygon"/> class.
|
|
||||
/// </summary>
|
|
||||
/// <param name="points">The points.</param>
|
|
||||
public BezierPolygon(params Vector2[] points) |
|
||||
{ |
|
||||
this.innerPolygon = new Polygon(new BezierLineSegment(points)); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the bounding box of this shape.
|
|
||||
/// </summary>
|
|
||||
/// <value>
|
|
||||
/// The bounds.
|
|
||||
/// </value>
|
|
||||
public RectangleF Bounds => this.innerPolygon.Bounds; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the maximum number intersections that a shape can have when testing a line.
|
|
||||
/// </summary>
|
|
||||
/// <value>
|
|
||||
/// The maximum intersections.
|
|
||||
/// </value>
|
|
||||
public int MaxIntersections => this.innerPolygon.MaxIntersections; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// the distance of the point from the outline of the shape, if the value is negative it is inside the polygon bounds
|
|
||||
/// </summary>
|
|
||||
/// <param name="point">The point.</param>
|
|
||||
/// <returns>
|
|
||||
/// The distance from the shape.
|
|
||||
/// </returns>
|
|
||||
public float Distance(Vector2 point) => this.innerPolygon.Distance(point); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 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>
|
|
||||
/// <param name="start">The start point of the line.</param>
|
|
||||
/// <param name="end">The end point of the line.</param>
|
|
||||
/// <param name="buffer">The buffer that will be populated with intersections.</param>
|
|
||||
/// <param name="count">The count.</param>
|
|
||||
/// <param name="offset">The offset.</param>
|
|
||||
/// <returns>
|
|
||||
/// The number of intersections populated into the buffer.
|
|
||||
/// </returns>
|
|
||||
public int FindIntersections(Vector2 start, Vector2 end, Vector2[] buffer, int count, int offset) |
|
||||
{ |
|
||||
return this.innerPolygon.FindIntersections(start, end, buffer, count, offset); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Returns an enumerator that iterates through the collection.
|
|
||||
/// </summary>
|
|
||||
/// <returns>
|
|
||||
/// An enumerator that can be used to iterate through the collection.
|
|
||||
/// </returns>
|
|
||||
public IEnumerator<IPath> GetEnumerator() |
|
||||
{ |
|
||||
return this.innerPolygon.GetEnumerator(); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Returns an enumerator that iterates through a collection.
|
|
||||
/// </summary>
|
|
||||
/// <returns>
|
|
||||
/// An <see cref="T:System.Collections.IEnumerator" /> object that can be used to iterate through the collection.
|
|
||||
/// </returns>
|
|
||||
IEnumerator IEnumerable.GetEnumerator() |
|
||||
{ |
|
||||
return this.innerPolygon.GetEnumerator(); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,246 +0,0 @@ |
|||||
// <copyright file="ComplexPolygon.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 |
|
||||
{ |
|
||||
using System; |
|
||||
using System.Collections; |
|
||||
using System.Collections.Generic; |
|
||||
using System.Linq; |
|
||||
using System.Numerics; |
|
||||
|
|
||||
using Paths; |
|
||||
using PolygonClipper; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Represents a complex polygon made up of one or more outline
|
|
||||
/// polygons and one or more holes to punch out of them.
|
|
||||
/// </summary>
|
|
||||
/// <seealso cref="ImageSharp.Drawing.Shapes.IShape" />
|
|
||||
public sealed class ComplexPolygon : IShape |
|
||||
{ |
|
||||
private const float ClipperScaleFactor = 100f; |
|
||||
private IShape[] shapes; |
|
||||
private IEnumerable<IPath> paths; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Initializes a new instance of the <see cref="ComplexPolygon"/> class.
|
|
||||
/// </summary>
|
|
||||
/// <param name="outline">The outline.</param>
|
|
||||
/// <param name="holes">The holes.</param>
|
|
||||
public ComplexPolygon(IShape outline, params IShape[] holes) |
|
||||
: this(new[] { outline }, holes) |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Initializes a new instance of the <see cref="ComplexPolygon"/> class.
|
|
||||
/// </summary>
|
|
||||
/// <param name="outlines">The outlines.</param>
|
|
||||
/// <param name="holes">The holes.</param>
|
|
||||
public ComplexPolygon(IShape[] outlines, IShape[] holes) |
|
||||
{ |
|
||||
Guard.NotNull(outlines, nameof(outlines)); |
|
||||
Guard.MustBeGreaterThanOrEqualTo(outlines.Length, 1, nameof(outlines)); |
|
||||
|
|
||||
this.MaxIntersections = this.FixAndSetShapes(outlines, holes); |
|
||||
|
|
||||
float minX = this.shapes.Min(x => x.Bounds.Left); |
|
||||
float maxX = this.shapes.Max(x => x.Bounds.Right); |
|
||||
float minY = this.shapes.Min(x => x.Bounds.Top); |
|
||||
float maxY = this.shapes.Max(x => x.Bounds.Bottom); |
|
||||
|
|
||||
this.Bounds = new RectangleF(minX, minY, maxX - minX, maxY - minY); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the bounding box of this shape.
|
|
||||
/// </summary>
|
|
||||
/// <value>
|
|
||||
/// The bounds.
|
|
||||
/// </value>
|
|
||||
public RectangleF Bounds { get; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the maximum number intersections that a shape can have when testing a line.
|
|
||||
/// </summary>
|
|
||||
/// <value>
|
|
||||
/// The maximum intersections.
|
|
||||
/// </value>
|
|
||||
public int MaxIntersections { get; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// the distance of the point from the outline of the shape, if the value is negative it is inside the polygon bounds
|
|
||||
/// </summary>
|
|
||||
/// <param name="point">The point.</param>
|
|
||||
/// <returns>
|
|
||||
/// Returns the distance from thr shape to the point
|
|
||||
/// </returns>
|
|
||||
/// <remarks>
|
|
||||
/// Due to the clipping we did during construction we know that out shapes do not overlap at there edges
|
|
||||
/// therefore for apoint to be in more that one we must be in a hole of another, theoretically this could
|
|
||||
/// then flip again to be in a outlin inside a hole inside an outline :)
|
|
||||
/// </remarks>
|
|
||||
float IShape.Distance(Vector2 point) |
|
||||
{ |
|
||||
float dist = float.MaxValue; |
|
||||
bool inside = false; |
|
||||
foreach (IShape shape in this.shapes) |
|
||||
{ |
|
||||
float d = shape.Distance(point); |
|
||||
|
|
||||
if (d <= 0) |
|
||||
{ |
|
||||
// we are inside a poly
|
|
||||
d = -d; // flip the sign
|
|
||||
inside ^= true; // flip the inside flag
|
|
||||
} |
|
||||
|
|
||||
if (d < dist) |
|
||||
{ |
|
||||
dist = d; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
if (inside) |
|
||||
{ |
|
||||
return -dist; |
|
||||
} |
|
||||
|
|
||||
return dist; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 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>
|
|
||||
/// <param name="start">The start point of the line.</param>
|
|
||||
/// <param name="end">The end point of the line.</param>
|
|
||||
/// <param name="buffer">The buffer that will be populated with intersections.</param>
|
|
||||
/// <param name="count">The count.</param>
|
|
||||
/// <param name="offset">The offset.</param>
|
|
||||
/// <returns>
|
|
||||
/// The number of intersections populated into the buffer.
|
|
||||
/// </returns>
|
|
||||
public int FindIntersections(Vector2 start, Vector2 end, Vector2[] buffer, int count, int offset) |
|
||||
{ |
|
||||
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>
|
|
||||
/// Returns an enumerator that iterates through the collection.
|
|
||||
/// </summary>
|
|
||||
/// <returns>
|
|
||||
/// An enumerator that can be used to iterate through the collection.
|
|
||||
/// </returns>
|
|
||||
public IEnumerator<IPath> GetEnumerator() |
|
||||
{ |
|
||||
return this.paths.GetEnumerator(); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Returns an enumerator that iterates through a collection.
|
|
||||
/// </summary>
|
|
||||
/// <returns>
|
|
||||
/// An <see cref="T:System.Collections.IEnumerator" /> object that can be used to iterate through the collection.
|
|
||||
/// </returns>
|
|
||||
IEnumerator IEnumerable.GetEnumerator() |
|
||||
{ |
|
||||
return this.GetEnumerator(); |
|
||||
} |
|
||||
|
|
||||
private void AddPoints(Clipper clipper, IShape shape, PolyType polyType) |
|
||||
{ |
|
||||
// if the path is already the shape use it directly and skip the path loop.
|
|
||||
if (shape is IPath) |
|
||||
{ |
|
||||
clipper.AddPath( |
|
||||
(IPath)shape, |
|
||||
polyType); |
|
||||
} |
|
||||
else |
|
||||
{ |
|
||||
foreach (IPath path in shape) |
|
||||
{ |
|
||||
clipper.AddPath( |
|
||||
path, |
|
||||
polyType); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
private void AddPoints(Clipper clipper, IEnumerable<IShape> shapes, PolyType polyType) |
|
||||
{ |
|
||||
foreach (IShape shape in shapes) |
|
||||
{ |
|
||||
this.AddPoints(clipper, shape, polyType); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
private void ExtractOutlines(PolyNode tree, List<IShape> shapes, List<IPath> paths) |
|
||||
{ |
|
||||
if (tree.Contour.Any()) |
|
||||
{ |
|
||||
// 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) |
|
||||
{ |
|
||||
shapes.Add((IShape)tree.SourcePath); |
|
||||
paths.Add(tree.SourcePath); |
|
||||
} |
|
||||
else |
|
||||
{ |
|
||||
// convert the Clipper Contour from scaled ints back down to the origional size (this is going to be lossy but not significantly)
|
|
||||
Polygon polygon = new Polygon(new Paths.LinearLineSegment(tree.Contour.ToArray())); |
|
||||
|
|
||||
shapes.Add(polygon); |
|
||||
paths.Add(polygon); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
foreach (PolyNode c in tree.Children) |
|
||||
{ |
|
||||
this.ExtractOutlines(c, shapes, paths); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
private int FixAndSetShapes(IEnumerable<IShape> outlines, IEnumerable<IShape> holes) |
|
||||
{ |
|
||||
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
|
|
||||
this.AddPoints(clipper, outlines, PolyType.Subject); |
|
||||
this.AddPoints(clipper, holes, PolyType.Clip); |
|
||||
|
|
||||
PolyTree tree = clipper.Execute(); |
|
||||
|
|
||||
List<IShape> shapes = new List<IShape>(); |
|
||||
List<IPath> paths = new List<IPath>(); |
|
||||
|
|
||||
// convert the 'tree' back to paths
|
|
||||
this.ExtractOutlines(tree, shapes, paths); |
|
||||
this.shapes = shapes.ToArray(); |
|
||||
this.paths = paths.ToArray(); |
|
||||
|
|
||||
int intersections = 0; |
|
||||
foreach (IShape s in this.shapes) |
|
||||
{ |
|
||||
intersections += s.MaxIntersections; |
|
||||
} |
|
||||
|
|
||||
return intersections; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,56 +0,0 @@ |
|||||
// <copyright file="IShape.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 |
|
||||
{ |
|
||||
using System.Collections.Generic; |
|
||||
using System.Numerics; |
|
||||
using Paths; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Represents a closed set of paths making up a single shape.
|
|
||||
/// </summary>
|
|
||||
public interface IShape : IEnumerable<IPath> |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// Gets the bounding box of this shape.
|
|
||||
/// </summary>
|
|
||||
/// <value>
|
|
||||
/// The bounds.
|
|
||||
/// </value>
|
|
||||
RectangleF Bounds { get; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the maximum number intersections that a shape can have when testing a line.
|
|
||||
/// </summary>
|
|
||||
/// <value>
|
|
||||
/// The maximum intersections.
|
|
||||
/// </value>
|
|
||||
int MaxIntersections { get; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// the distance of the point from the outline of the shape, if the value is negative it is inside the polygon bounds
|
|
||||
/// </summary>
|
|
||||
/// <param name="point">The point.</param>
|
|
||||
/// <returns>
|
|
||||
/// Returns the distance from the shape to the point
|
|
||||
/// </returns>
|
|
||||
float Distance(Vector2 point); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 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>
|
|
||||
/// <param name="start">The start point of the line.</param>
|
|
||||
/// <param name="end">The end point of the line.</param>
|
|
||||
/// <param name="buffer">The buffer that will be populated with intersections.</param>
|
|
||||
/// <param name="count">The count.</param>
|
|
||||
/// <param name="offset">The offset.</param>
|
|
||||
/// <returns>
|
|
||||
/// The number of intersections populated into the buffer.
|
|
||||
/// </returns>
|
|
||||
int FindIntersections(Vector2 start, Vector2 end, Vector2[] buffer, int count, int offset); |
|
||||
} |
|
||||
} |
|
||||
@ -1,93 +0,0 @@ |
|||||
// <copyright file="LinearPolygon.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 |
|
||||
{ |
|
||||
using System.Collections; |
|
||||
using System.Collections.Generic; |
|
||||
using System.Numerics; |
|
||||
using Paths; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Represents a polygon made up exclusivly of a single Linear path.
|
|
||||
/// </summary>
|
|
||||
public sealed class LinearPolygon : IShape |
|
||||
{ |
|
||||
private Polygon innerPolygon; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Initializes a new instance of the <see cref="LinearPolygon"/> class.
|
|
||||
/// </summary>
|
|
||||
/// <param name="points">The points.</param>
|
|
||||
public LinearPolygon(params Vector2[] points) |
|
||||
{ |
|
||||
this.innerPolygon = new Polygon(new LinearLineSegment(points)); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the bounding box of this shape.
|
|
||||
/// </summary>
|
|
||||
/// <value>
|
|
||||
/// The bounds.
|
|
||||
/// </value>
|
|
||||
public RectangleF Bounds => this.innerPolygon.Bounds; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the maximum number intersections that a shape can have when testing a line.
|
|
||||
/// </summary>
|
|
||||
/// <value>
|
|
||||
/// The maximum intersections.
|
|
||||
/// </value>
|
|
||||
public int MaxIntersections |
|
||||
{ |
|
||||
get |
|
||||
{ |
|
||||
return this.innerPolygon.MaxIntersections; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// the distance of the point from the outline of the shape, if the value is negative it is inside the polygon bounds
|
|
||||
/// </summary>
|
|
||||
/// <param name="point">The point.</param>
|
|
||||
/// <returns>
|
|
||||
/// Returns the distance from the shape to the point
|
|
||||
/// </returns>
|
|
||||
public float Distance(Vector2 point) => this.innerPolygon.Distance(point); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 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>
|
|
||||
/// <param name="start">The start point of the line.</param>
|
|
||||
/// <param name="end">The end point of the line.</param>
|
|
||||
/// <param name="buffer">The buffer that will be populated with intersections.</param>
|
|
||||
/// <param name="count">The count.</param>
|
|
||||
/// <param name="offset">The offset.</param>
|
|
||||
/// <returns>
|
|
||||
/// The number of intersections populated into the buffer.
|
|
||||
/// </returns>
|
|
||||
public int FindIntersections(Vector2 start, Vector2 end, Vector2[] buffer, int count, int offset) |
|
||||
{ |
|
||||
return this.innerPolygon.FindIntersections(start, end, buffer, count, offset); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Returns an enumerator that iterates through the collection.
|
|
||||
/// </summary>
|
|
||||
/// <returns>
|
|
||||
/// An enumerator that can be used to iterate through the collection.
|
|
||||
/// </returns>
|
|
||||
public IEnumerator<IPath> GetEnumerator() => this.innerPolygon.GetEnumerator(); |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Returns an enumerator that iterates through a collection.
|
|
||||
/// </summary>
|
|
||||
/// <returns>
|
|
||||
/// An <see cref="T:System.Collections.IEnumerator" /> object that can be used to iterate through the collection.
|
|
||||
/// </returns>
|
|
||||
IEnumerator IEnumerable.GetEnumerator() => this.innerPolygon.GetEnumerator(); |
|
||||
} |
|
||||
} |
|
||||
@ -1,156 +0,0 @@ |
|||||
// <copyright file="Polygon.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 |
|
||||
{ |
|
||||
using System.Collections; |
|
||||
using System.Collections.Generic; |
|
||||
using System.Numerics; |
|
||||
|
|
||||
using Paths; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// A shape made up of a single path made up of one of more <see cref="ILineSegment"/>s
|
|
||||
/// </summary>
|
|
||||
public sealed class Polygon : IShape, IPath |
|
||||
{ |
|
||||
private readonly InternalPath innerPath; |
|
||||
private readonly IEnumerable<IPath> pathCollection; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Initializes a new instance of the <see cref="Polygon"/> class.
|
|
||||
/// </summary>
|
|
||||
/// <param name="segments">The segments.</param>
|
|
||||
public Polygon(params ILineSegment[] segments) |
|
||||
{ |
|
||||
this.innerPath = new InternalPath(segments, true); |
|
||||
this.pathCollection = new[] { this }; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Initializes a new instance of the <see cref="Polygon" /> class.
|
|
||||
/// </summary>
|
|
||||
/// <param name="segment">The segment.</param>
|
|
||||
public Polygon(ILineSegment segment) |
|
||||
{ |
|
||||
this.innerPath = new InternalPath(segment, true); |
|
||||
this.pathCollection = new[] { this }; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the bounding box of this shape.
|
|
||||
/// </summary>
|
|
||||
/// <value>
|
|
||||
/// The bounds.
|
|
||||
/// </value>
|
|
||||
public RectangleF Bounds => this.innerPath.Bounds; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the length of the path
|
|
||||
/// </summary>
|
|
||||
/// <value>
|
|
||||
/// The length.
|
|
||||
/// </value>
|
|
||||
public float Length => this.innerPath.Length; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets a value indicating whether this instance is closed.
|
|
||||
/// </summary>
|
|
||||
/// <value>
|
|
||||
/// <c>true</c> if this instance is closed; otherwise, <c>false</c>.
|
|
||||
/// </value>
|
|
||||
public bool IsClosed => true; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the maximum number intersections that a shape can have when testing a line.
|
|
||||
/// </summary>
|
|
||||
/// <value>
|
|
||||
/// The maximum intersections.
|
|
||||
/// </value>
|
|
||||
public int MaxIntersections => this.innerPath.Points.Length; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// the distance of the point from the outline of the shape, if the value is negative it is inside the polygon bounds
|
|
||||
/// </summary>
|
|
||||
/// <param name="point">The point.</param>
|
|
||||
/// <returns>
|
|
||||
/// The distance of the point away from the shape
|
|
||||
/// </returns>
|
|
||||
public float Distance(Vector2 point) |
|
||||
{ |
|
||||
bool isInside = this.innerPath.PointInPolygon(point); |
|
||||
|
|
||||
float distance = this.innerPath.DistanceFromPath(point).DistanceFromPath; |
|
||||
if (isInside) |
|
||||
{ |
|
||||
return -distance; |
|
||||
} |
|
||||
|
|
||||
return distance; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Returns an enumerator that iterates through the collection.
|
|
||||
/// </summary>
|
|
||||
/// <returns>
|
|
||||
/// An enumerator that can be used to iterate through the collection.
|
|
||||
/// </returns>
|
|
||||
public IEnumerator<IPath> GetEnumerator() |
|
||||
{ |
|
||||
return this.pathCollection.GetEnumerator(); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Returns an enumerator that iterates through a collection.
|
|
||||
/// </summary>
|
|
||||
/// <returns>
|
|
||||
/// An <see cref="T:System.Collections.IEnumerator" /> object that can be used to iterate through the collection.
|
|
||||
/// </returns>
|
|
||||
IEnumerator IEnumerable.GetEnumerator() |
|
||||
{ |
|
||||
return this.pathCollection.GetEnumerator(); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Calcualtes the distance along and away from the path for a specified point.
|
|
||||
/// </summary>
|
|
||||
/// <param name="point">The point along the path.</param>
|
|
||||
/// <returns>
|
|
||||
/// distance metadata about the point.
|
|
||||
/// </returns>
|
|
||||
PointInfo IPath.Distance(Vector2 point) |
|
||||
{ |
|
||||
return this.innerPath.DistanceFromPath(point); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Returns the current shape as a simple linear path.
|
|
||||
/// </summary>
|
|
||||
/// <returns>
|
|
||||
/// Returns the current <see cref="ILineSegment" /> as simple linear path.
|
|
||||
/// </returns>
|
|
||||
public Vector2[] AsSimpleLinearPath() |
|
||||
{ |
|
||||
return this.innerPath.Points; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 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>
|
|
||||
/// <param name="start">The start point of the line.</param>
|
|
||||
/// <param name="end">The end point of the line.</param>
|
|
||||
/// <param name="buffer">The buffer that will be populated with intersections.</param>
|
|
||||
/// <param name="count">The count.</param>
|
|
||||
/// <param name="offset">The offset.</param>
|
|
||||
/// <returns>
|
|
||||
/// The number of intersections populated into the buffer.
|
|
||||
/// </returns>
|
|
||||
public int FindIntersections(Vector2 start, Vector2 end, Vector2[] buffer, int count, int offset) |
|
||||
{ |
|
||||
return this.innerPath.FindIntersections(start, end, buffer, count, offset); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
File diff suppressed because it is too large
@ -1,31 +0,0 @@ |
|||||
// <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) |
|
||||
{ |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,31 +0,0 @@ |
|||||
// <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 |
|
||||
} |
|
||||
} |
|
||||
@ -1,31 +0,0 @@ |
|||||
// <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 |
|
||||
} |
|
||||
} |
|
||||
@ -1,38 +0,0 @@ |
|||||
// <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
|
|
||||
} |
|
||||
} |
|
||||
@ -1,48 +0,0 @@ |
|||||
// <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; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,38 +0,0 @@ |
|||||
// <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
|
|
||||
} |
|
||||
} |
|
||||
@ -1,44 +0,0 @@ |
|||||
// <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
|
|
||||
} |
|
||||
} |
|
||||
@ -1,38 +0,0 @@ |
|||||
// <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
|
|
||||
} |
|
||||
} |
|
||||
@ -1,43 +0,0 @@ |
|||||
// <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
|
|
||||
} |
|
||||
} |
|
||||
@ -1,64 +0,0 @@ |
|||||
// <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
|
|
||||
} |
|
||||
} |
|
||||
@ -1,179 +0,0 @@ |
|||||
// <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; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,81 +0,0 @@ |
|||||
// <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; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,31 +0,0 @@ |
|||||
// <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 |
|
||||
} |
|
||||
} |
|
||||
@ -1,40 +0,0 @@ |
|||||
# 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 * |
|
||||
* * |
|
||||
*******************************************************************************/ |
|
||||
``` |
|
||||
@ -1,33 +0,0 @@ |
|||||
// <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
|
|
||||
} |
|
||||
} |
|
||||
@ -1,118 +0,0 @@ |
|||||
// <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
|
|
||||
} |
|
||||
} |
|
||||
@ -1,281 +0,0 @@ |
|||||
// <copyright file="RectangularPolygon.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 |
|
||||
{ |
|
||||
using System; |
|
||||
using System.Collections; |
|
||||
using System.Collections.Generic; |
|
||||
using System.Linq; |
|
||||
using System.Numerics; |
|
||||
using System.Threading.Tasks; |
|
||||
using Paths; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// A way of optermising drawing rectangles.
|
|
||||
/// </summary>
|
|
||||
/// <seealso cref="ImageSharp.Drawing.Shapes.IShape" />
|
|
||||
public class RectangularPolygon : IShape, IPath |
|
||||
{ |
|
||||
private readonly RectangleF rectangle; |
|
||||
private readonly Vector2 topLeft; |
|
||||
private readonly Vector2 bottomRight; |
|
||||
private readonly Vector2[] points; |
|
||||
private readonly IEnumerable<IPath> pathCollection; |
|
||||
private readonly float halfLength; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Initializes a new instance of the <see cref="RectangularPolygon"/> class.
|
|
||||
/// </summary>
|
|
||||
/// <param name="rect">The rect.</param>
|
|
||||
public RectangularPolygon(ImageSharp.Rectangle rect) |
|
||||
: this((RectangleF)rect) |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Initializes a new instance of the <see cref="RectangularPolygon"/> class.
|
|
||||
/// </summary>
|
|
||||
/// <param name="rect">The rect.</param>
|
|
||||
public RectangularPolygon(ImageSharp.RectangleF rect) |
|
||||
{ |
|
||||
this.rectangle = rect; |
|
||||
this.points = new Vector2[4] |
|
||||
{ |
|
||||
this.topLeft = new Vector2(rect.Left, rect.Top), |
|
||||
new Vector2(rect.Right, rect.Top), |
|
||||
this.bottomRight = new Vector2(rect.Right, rect.Bottom), |
|
||||
new Vector2(rect.Left, rect.Bottom) |
|
||||
}; |
|
||||
|
|
||||
this.halfLength = this.rectangle.Width + this.rectangle.Height; |
|
||||
this.Length = this.halfLength * 2; |
|
||||
this.pathCollection = new[] { this }; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the bounding box of this shape.
|
|
||||
/// </summary>
|
|
||||
/// <value>
|
|
||||
/// The bounds.
|
|
||||
/// </value>
|
|
||||
public RectangleF Bounds => this.rectangle; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets a value indicating whether this instance is closed.
|
|
||||
/// </summary>
|
|
||||
/// <value>
|
|
||||
/// <c>true</c> if this instance is closed; otherwise, <c>false</c>.
|
|
||||
/// </value>
|
|
||||
public bool IsClosed => true; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the length of the path
|
|
||||
/// </summary>
|
|
||||
/// <value>
|
|
||||
/// The length.
|
|
||||
/// </value>
|
|
||||
public float Length { get; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the maximum number intersections that a shape can have when testing a line.
|
|
||||
/// </summary>
|
|
||||
/// <value>
|
|
||||
/// The maximum intersections.
|
|
||||
/// </value>
|
|
||||
public int MaxIntersections => 4; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Calculates the distance along and away from the path for a specified point.
|
|
||||
/// </summary>
|
|
||||
/// <param name="point">The point along the path.</param>
|
|
||||
/// <returns>
|
|
||||
/// Returns details about the point and its distance away from the path.
|
|
||||
/// </returns>
|
|
||||
PointInfo IPath.Distance(Vector2 point) |
|
||||
{ |
|
||||
bool inside; // dont care about inside/outside for paths just distance
|
|
||||
return this.Distance(point, false, out inside); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// the distance of the point from the outline of the shape, if the value is negative it is inside the polygon bounds
|
|
||||
/// </summary>
|
|
||||
/// <param name="point">The point.</param>
|
|
||||
/// <returns>
|
|
||||
/// Returns the distance from the shape to the point
|
|
||||
/// </returns>
|
|
||||
public float Distance(Vector2 point) |
|
||||
{ |
|
||||
bool insidePoly; |
|
||||
PointInfo result = this.Distance(point, true, out insidePoly); |
|
||||
|
|
||||
// invert the distance from path when inside
|
|
||||
return insidePoly ? -result.DistanceFromPath : result.DistanceFromPath; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Returns an enumerator that iterates through the collection.
|
|
||||
/// </summary>
|
|
||||
/// <returns>
|
|
||||
/// An enumerator that can be used to iterate through the collection.
|
|
||||
/// </returns>
|
|
||||
public IEnumerator<IPath> GetEnumerator() |
|
||||
{ |
|
||||
return this.pathCollection.GetEnumerator(); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Returns an enumerator that iterates through a collection.
|
|
||||
/// </summary>
|
|
||||
/// <returns>
|
|
||||
/// An <see cref="T:System.Collections.IEnumerator" /> object that can be used to iterate through the collection.
|
|
||||
/// </returns>
|
|
||||
IEnumerator IEnumerable.GetEnumerator() |
|
||||
{ |
|
||||
return this.pathCollection.GetEnumerator(); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Converts the <see cref="ILineSegment" /> into a simple linear path..
|
|
||||
/// </summary>
|
|
||||
/// <returns>
|
|
||||
/// Returns the current <see cref="ILineSegment" /> as simple linear path.
|
|
||||
/// </returns>
|
|
||||
public Vector2[] AsSimpleLinearPath() |
|
||||
{ |
|
||||
return this.points; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// 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>
|
|
||||
/// <param name="start">The start point of the line.</param>
|
|
||||
/// <param name="end">The end point of the line.</param>
|
|
||||
/// <param name="buffer">The buffer that will be populated with intersections.</param>
|
|
||||
/// <param name="count">The count.</param>
|
|
||||
/// <param name="offset">The offset.</param>
|
|
||||
/// <returns>
|
|
||||
/// The number of intersections populated into the buffer.
|
|
||||
/// </returns>
|
|
||||
public int FindIntersections(Vector2 start, Vector2 end, Vector2[] buffer, int count, int offset) |
|
||||
{ |
|
||||
int discovered = 0; |
|
||||
Vector2 startPoint = Vector2.Clamp(start, this.topLeft, this.bottomRight); |
|
||||
Vector2 endPoint = Vector2.Clamp(end, this.topLeft, this.bottomRight); |
|
||||
|
|
||||
if (startPoint == Vector2.Clamp(startPoint, start, end)) |
|
||||
{ |
|
||||
// if start closest is within line then its a valid point
|
|
||||
discovered++; |
|
||||
buffer[offset++] = startPoint; |
|
||||
} |
|
||||
|
|
||||
if (endPoint == Vector2.Clamp(endPoint, start, end)) |
|
||||
{ |
|
||||
// if start closest is within line then its a valid point
|
|
||||
discovered++; |
|
||||
buffer[offset++] = endPoint; |
|
||||
} |
|
||||
|
|
||||
return discovered; |
|
||||
} |
|
||||
|
|
||||
private PointInfo Distance(Vector2 point, bool getDistanceAwayOnly, out bool isInside) |
|
||||
{ |
|
||||
// point in rectangle
|
|
||||
// if after its clamped by the extreams its still the same then it must be inside :)
|
|
||||
Vector2 clamped = Vector2.Clamp(point, this.topLeft, this.bottomRight); |
|
||||
isInside = clamped == point; |
|
||||
|
|
||||
float distanceFromEdge = float.MaxValue; |
|
||||
float distanceAlongEdge = 0f; |
|
||||
|
|
||||
if (isInside) |
|
||||
{ |
|
||||
// get the absolute distances from the extreams
|
|
||||
Vector2 topLeftDist = Vector2.Abs(point - this.topLeft); |
|
||||
Vector2 bottomRightDist = Vector2.Abs(point - this.bottomRight); |
|
||||
|
|
||||
// get the min components
|
|
||||
Vector2 minDists = Vector2.Min(topLeftDist, bottomRightDist); |
|
||||
|
|
||||
// and then the single smallest (dont have to worry about direction)
|
|
||||
distanceFromEdge = Math.Min(minDists.X, minDists.Y); |
|
||||
|
|
||||
if (!getDistanceAwayOnly) |
|
||||
{ |
|
||||
// we need to make clamped the closest point
|
|
||||
if (this.topLeft.X + distanceFromEdge == point.X) |
|
||||
{ |
|
||||
// closer to lhf
|
|
||||
clamped.X = this.topLeft.X; // y is already the same
|
|
||||
|
|
||||
// distance along edge is length minus the amout down we are from the top of the rect
|
|
||||
distanceAlongEdge = this.Length - (clamped.Y - this.topLeft.Y); |
|
||||
} |
|
||||
else if (this.topLeft.Y + distanceFromEdge == point.Y) |
|
||||
{ |
|
||||
// closer to top
|
|
||||
clamped.Y = this.topLeft.Y; // x is already the same
|
|
||||
|
|
||||
distanceAlongEdge = clamped.X - this.topLeft.X; |
|
||||
} |
|
||||
else if (this.bottomRight.Y - distanceFromEdge == point.Y) |
|
||||
{ |
|
||||
// closer to bottom
|
|
||||
clamped.Y = this.bottomRight.Y; // x is already the same
|
|
||||
|
|
||||
distanceAlongEdge = (this.bottomRight.X - clamped.X) + this.halfLength; |
|
||||
} |
|
||||
else if (this.bottomRight.X - distanceFromEdge == point.X) |
|
||||
{ |
|
||||
// closer to rhs
|
|
||||
clamped.X = this.bottomRight.X; // x is already the same
|
|
||||
|
|
||||
distanceAlongEdge = (this.bottomRight.Y - clamped.Y) + this.rectangle.Width; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
else |
|
||||
{ |
|
||||
// clamped is the point on the path thats closest no matter what
|
|
||||
distanceFromEdge = (clamped - point).Length(); |
|
||||
|
|
||||
if (!getDistanceAwayOnly) |
|
||||
{ |
|
||||
// we need to figure out whats the cloests edge now and thus what distance/poitn is closest
|
|
||||
if (this.topLeft.X == clamped.X) |
|
||||
{ |
|
||||
// distance along edge is length minus the amout down we are from the top of the rect
|
|
||||
distanceAlongEdge = this.Length - (clamped.Y - this.topLeft.Y); |
|
||||
} |
|
||||
else if (this.topLeft.Y == clamped.Y) |
|
||||
{ |
|
||||
distanceAlongEdge = clamped.X - this.topLeft.X; |
|
||||
} |
|
||||
else if (this.bottomRight.Y == clamped.Y) |
|
||||
{ |
|
||||
distanceAlongEdge = (this.bottomRight.X - clamped.X) + this.halfLength; |
|
||||
} |
|
||||
else if (this.bottomRight.X == clamped.X) |
|
||||
{ |
|
||||
distanceAlongEdge = (this.bottomRight.Y - clamped.Y) + this.rectangle.Width; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
return new PointInfo |
|
||||
{ |
|
||||
SearchPoint = point, |
|
||||
DistanceFromPath = distanceFromEdge, |
|
||||
ClosestPointOnPath = clamped, |
|
||||
DistanceAlongPath = distanceAlongEdge |
|
||||
}; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue