зеркало из https://github.com/SixLabors/Shapes.git
remove old code
This commit is contained in:
Родитель
10cf98fab8
Коммит
9e047e83aa
|
@ -1,18 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Shaper2D
|
||||
{
|
||||
public interface ILineSegment
|
||||
{
|
||||
/// <summary>
|
||||
/// Simplifies the specified quality.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
IEnumerable<Vector2> Simplify();
|
||||
}
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
using Shaper2D.Primitives;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Shaper2D
|
||||
{
|
||||
public class LinearLineSegment : ILineSegment
|
||||
{
|
||||
public IReadOnlyList<Vector2> ControlPoints { get; }
|
||||
|
||||
|
||||
internal LinearLineSegment(IEnumerable<Vector2> points)
|
||||
{
|
||||
//Guard.NotNull(points, nameof(points));
|
||||
//Guard.MustBeGreaterThanOrEqualTo(points.Count(), 2, nameof(points));
|
||||
|
||||
ControlPoints = new ReadOnlyCollection<Vector2>(points.ToList());
|
||||
}
|
||||
|
||||
public LinearLineSegment(params PointF[] points)
|
||||
: this(points?.Select(x => x.ToVector2()))
|
||||
{
|
||||
}
|
||||
|
||||
public LinearLineSegment(IEnumerable<PointF> points)
|
||||
: this(points?.Select(x => x.ToVector2()))
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public IEnumerable<Vector2> Simplify()
|
||||
{
|
||||
return ControlPoints;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,210 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Shaper2D.Primitives
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an ordered pair of floating point x- and y-coordinates that defines a point in
|
||||
/// a two-dimensional plane.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This struct is fully mutable. This is done (against the guidelines) for the sake of performance,
|
||||
/// as it avoids the need to create new values for modification operations.
|
||||
/// </remarks>
|
||||
public struct PointF : IEquatable<PointF>
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a <see cref="PointF"/> that has X and Y values set to zero.
|
||||
/// </summary>
|
||||
public static readonly PointF Empty = default(PointF);
|
||||
/// <summary>
|
||||
/// The backing vector for SIMD support.
|
||||
/// </summary>
|
||||
private Vector2 backingVector;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Point"/> struct.
|
||||
/// </summary>
|
||||
/// <param name="x">The horizontal position of the point.</param>
|
||||
/// <param name="y">The vertical position of the point.</param>
|
||||
public PointF(float x, float y)
|
||||
: this()
|
||||
{
|
||||
this.backingVector = new Vector2(x, y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Point"/> struct.
|
||||
/// </summary>
|
||||
/// <param name="vector">
|
||||
/// The vector representing the width and height.
|
||||
/// </param>
|
||||
public PointF(Vector2 vector)
|
||||
{
|
||||
this.backingVector = vector;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the x-coordinate of this <see cref="Point"/>.
|
||||
/// </summary>
|
||||
public float X => backingVector.X;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the y-coordinate of this <see cref="Point"/>.
|
||||
/// </summary>
|
||||
public float Y => backingVector.Y;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this <see cref="Point"/> is empty.
|
||||
/// </summary>
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public bool IsEmpty => this.Equals(Empty);
|
||||
|
||||
/// <summary>
|
||||
/// Computes the sum of adding two points.
|
||||
/// </summary>
|
||||
/// <param name="left">The point on the left hand of the operand.</param>
|
||||
/// <param name="right">The point on the right hand of the operand.</param>
|
||||
/// <returns>
|
||||
/// The <see cref="Point"/>
|
||||
/// </returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static PointF operator +(PointF left, PointF right)
|
||||
{
|
||||
return new PointF(left.backingVector + right.backingVector);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the difference left by subtracting one point from another.
|
||||
/// </summary>
|
||||
/// <param name="left">The point on the left hand of the operand.</param>
|
||||
/// <param name="right">The point on the right hand of the operand.</param>
|
||||
/// <returns>
|
||||
/// The <see cref="Point"/>
|
||||
/// </returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static PointF operator -(PointF left, PointF right)
|
||||
{
|
||||
return new PointF(left.backingVector - right.backingVector);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two <see cref="Point"/> objects for equality.
|
||||
/// </summary>
|
||||
/// <param name="left">
|
||||
/// The <see cref="Point"/> on the left side of the operand.
|
||||
/// </param>
|
||||
/// <param name="right">
|
||||
/// The <see cref="Point"/> on the right side of the operand.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// True if the current left is equal to the <paramref name="right"/> parameter; otherwise, false.
|
||||
/// </returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool operator ==(PointF left, PointF right)
|
||||
{
|
||||
return left.backingVector == right.backingVector;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two <see cref="Point"/> objects for inequality.
|
||||
/// </summary>
|
||||
/// <param name="left">
|
||||
/// The <see cref="Point"/> on the left side of the operand.
|
||||
/// </param>
|
||||
/// <param name="right">
|
||||
/// The <see cref="Point"/> on the right side of the operand.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// True if the current left is unequal to the <paramref name="right"/> parameter; otherwise, false.
|
||||
/// </returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool operator !=(PointF left, PointF right)
|
||||
{
|
||||
return left.backingVector != right.backingVector;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a <see cref="Vector2"/> representation for this <see cref="Point"/>.
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="Vector2"/> representation for this object.</returns>
|
||||
public Vector2 ToVector2()
|
||||
{
|
||||
return new Vector2(this.backingVector.X, this.backingVector.Y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Translates this <see cref="Point"/> by the specified amount.
|
||||
/// </summary>
|
||||
/// <param name="dx">The amount to offset the x-coordinate.</param>
|
||||
/// <param name="dy">The amount to offset the y-coordinate.</param>
|
||||
public void Offset(int dx, int dy)
|
||||
{
|
||||
this.backingVector.X += dx;
|
||||
this.backingVector.Y += dy;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Translates this <see cref="Point"/> by the specified amount.
|
||||
/// </summary>
|
||||
/// <param name="p">The <see cref="Point"/> used offset this <see cref="Point"/>.</param>
|
||||
public void Offset(PointF p)
|
||||
{
|
||||
this.backingVector += p.backingVector;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return this.GetHashCode(this);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string ToString()
|
||||
{
|
||||
if (this.IsEmpty)
|
||||
{
|
||||
return "Point [ Empty ]";
|
||||
}
|
||||
|
||||
return $"Point [ X={this.X}, Y={this.Y} ]";
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is PointF)
|
||||
{
|
||||
return this.Equals((PointF)obj);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Equals(PointF other)
|
||||
{
|
||||
return this.backingVector == other.backingVector;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the hash code for this instance.
|
||||
/// </summary>
|
||||
/// <param name="point">
|
||||
/// The instance of <see cref="Point"/> to return the hash code for.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// A 32-bit signed integer that is the hash code for this instance.
|
||||
/// </returns>
|
||||
private int GetHashCode(PointF point)
|
||||
{
|
||||
return point.backingVector.GetHashCode();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,284 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Shaper2D.Primitives
|
||||
{
|
||||
|
||||
public struct RectangleF : IEquatable<RectangleF>
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a <see cref="RectangleF"/> that has X, Y, Width, and Height values set to zero.
|
||||
/// </summary>
|
||||
public static readonly RectangleF Empty = default(RectangleF);
|
||||
|
||||
/// <summary>
|
||||
/// The backing vector for SIMD support.
|
||||
/// </summary>
|
||||
private Vector4 backingVector;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RectangleF"/> struct.
|
||||
/// </summary>
|
||||
/// <param name="x">The horizontal position of the rectangle.</param>
|
||||
/// <param name="y">The vertical position of the rectangle.</param>
|
||||
/// <param name="width">The width of the rectangle.</param>
|
||||
/// <param name="height">The height of the rectangle.</param>
|
||||
public RectangleF(float x, float y, float width, float height)
|
||||
{
|
||||
this.backingVector = new Vector4(x, y, width, height);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RectangleF"/> struct.
|
||||
/// </summary>
|
||||
/// <param name="vector">The vector.</param>
|
||||
public RectangleF(Vector4 vector)
|
||||
{
|
||||
this.backingVector = vector;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the x-coordinate of this <see cref="RectangleF"/>.
|
||||
/// </summary>
|
||||
public float X
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.backingVector.X;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
this.backingVector.X = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the y-coordinate of this <see cref="RectangleF"/>.
|
||||
/// </summary>
|
||||
public float Y
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.backingVector.Y;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
this.backingVector.Y = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the width of this <see cref="RectangleF"/>.
|
||||
/// </summary>
|
||||
public float Width
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.backingVector.Z;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
this.backingVector.Z = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the height of this <see cref="RectangleF"/>.
|
||||
/// </summary>
|
||||
public float Height
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.backingVector.W;
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
this.backingVector.W = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this <see cref="RectangleF"/> is empty.
|
||||
/// </summary>
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public bool IsEmpty => this.Equals(Empty);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the y-coordinate of the top edge of this <see cref="Rectangle"/>.
|
||||
/// </summary>
|
||||
public float Top => this.Y;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the x-coordinate of the right edge of this <see cref="Rectangle"/>.
|
||||
/// </summary>
|
||||
public float Right => this.X + this.Width;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the y-coordinate of the bottom edge of this <see cref="Rectangle"/>.
|
||||
/// </summary>
|
||||
public float Bottom => this.Y + this.Height;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the x-coordinate of the left edge of this <see cref="Rectangle"/>.
|
||||
/// </summary>
|
||||
public float Left => this.X;
|
||||
|
||||
/// <summary>
|
||||
/// Computes the sum of adding two rectangles.
|
||||
/// </summary>
|
||||
/// <param name="left">The rectangle on the left hand of the operand.</param>
|
||||
/// <param name="right">The rectangle on the right hand of the operand.</param>
|
||||
/// <returns>
|
||||
/// The <see cref="Rectangle"/>
|
||||
/// </returns>
|
||||
public static RectangleF operator +(RectangleF left, RectangleF right)
|
||||
{
|
||||
return new RectangleF(left.backingVector + right.backingVector);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the difference left by subtracting one rectangle from another.
|
||||
/// </summary>
|
||||
/// <param name="left">The rectangle on the left hand of the operand.</param>
|
||||
/// <param name="right">The rectangle on the right hand of the operand.</param>
|
||||
/// <returns>
|
||||
/// The <see cref="Rectangle"/>
|
||||
/// </returns>
|
||||
public static RectangleF operator -(RectangleF left, RectangleF right)
|
||||
{
|
||||
return new RectangleF(left.backingVector - right.backingVector);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two <see cref="Rectangle"/> objects for equality.
|
||||
/// </summary>
|
||||
/// <param name="left">
|
||||
/// The <see cref="Rectangle"/> on the left side of the operand.
|
||||
/// </param>
|
||||
/// <param name="right">
|
||||
/// The <see cref="Rectangle"/> on the right side of the operand.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// True if the current left is equal to the <paramref name="right"/> parameter; otherwise, false.
|
||||
/// </returns>
|
||||
public static bool operator ==(RectangleF left, RectangleF right)
|
||||
{
|
||||
return left.Equals(right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two <see cref="Rectangle"/> objects for inequality.
|
||||
/// </summary>
|
||||
/// <param name="left">
|
||||
/// The <see cref="Rectangle"/> on the left side of the operand.
|
||||
/// </param>
|
||||
/// <param name="right">
|
||||
/// The <see cref="Rectangle"/> on the right side of the operand.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// True if the current left is unequal to the <paramref name="right"/> parameter; otherwise, false.
|
||||
/// </returns>
|
||||
public static bool operator !=(RectangleF left, RectangleF right)
|
||||
{
|
||||
return !left.Equals(right);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the center point of the given <see cref="Rectangle"/>
|
||||
/// </summary>
|
||||
/// <param name="rectangle">The rectangle</param>
|
||||
/// <returns><see cref="Point"/></returns>
|
||||
public static Point Center(Rectangle rectangle)
|
||||
{
|
||||
return new Point(rectangle.Left + (rectangle.Width / 2), rectangle.Top + (rectangle.Height / 2));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if the specfied point is contained within the rectangular region defined by
|
||||
/// this <see cref="Rectangle"/>.
|
||||
/// </summary>
|
||||
/// <param name="x">The x-coordinate of the given point.</param>
|
||||
/// <param name="y">The y-coordinate of the given point.</param>
|
||||
/// <returns>The <see cref="bool"/></returns>
|
||||
public bool Contains(int x, int y)
|
||||
{
|
||||
// TODO: SIMD?
|
||||
return this.X <= x
|
||||
&& x < this.Right
|
||||
&& this.Y <= y
|
||||
&& y < this.Bottom;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Determines if the specfied <see cref="Rectangle"/> intersects the rectangular region defined by
|
||||
/// this <see cref="Rectangle"/>.
|
||||
/// </summary>
|
||||
/// <param name="rect">The other Rectange </param>
|
||||
/// <returns>The <see cref="bool"/></returns>
|
||||
public bool Intersects(Rectangle rect)
|
||||
{
|
||||
return rect.Left <= this.Right && rect.Right >= this.Left
|
||||
&&
|
||||
rect.Top <= this.Bottom && rect.Bottom >= this.Top;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return this.GetHashCode(this);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string ToString()
|
||||
{
|
||||
if (this.IsEmpty)
|
||||
{
|
||||
return "Rectangle [ Empty ]";
|
||||
}
|
||||
|
||||
return
|
||||
$"Rectangle [ X={this.X}, Y={this.Y}, Width={this.Width}, Height={this.Height} ]";
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is Rectangle)
|
||||
{
|
||||
return this.Equals((Rectangle)obj);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Equals(Rectangle other)
|
||||
{
|
||||
return this.backingVector.Equals(other.backingVector);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the hash code for this instance.
|
||||
/// </summary>
|
||||
/// <param name="rectangle">
|
||||
/// The instance of <see cref="Rectangle"/> to return the hash code for.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// A 32-bit signed integer that is the hash code for this instance.
|
||||
/// </returns>
|
||||
private int GetHashCode(Rectangle rectangle)
|
||||
{
|
||||
return rectangle.backingVector.GetHashCode();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,175 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Numerics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Shaper2D.Primitives
|
||||
{
|
||||
/// <summary>
|
||||
/// Stores an ordered pair of integers, which specify a height and width.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This struct is fully mutable. This is done (against the guidelines) for the sake of performance,
|
||||
/// as it avoids the need to create new values for modification operations.
|
||||
/// </remarks>
|
||||
public struct SizeF : IEquatable<SizeF>
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a <see cref="SizeF"/> that has Width and Height values set to zero.
|
||||
/// </summary>
|
||||
public static readonly SizeF Empty = default(SizeF);
|
||||
|
||||
/// <summary>
|
||||
/// The backing vector for SIMD support.
|
||||
/// </summary>
|
||||
private Vector2 backingVector;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Size"/> struct.
|
||||
/// </summary>
|
||||
/// <param name="width">The width of the size.</param>
|
||||
/// <param name="height">The height of the size.</param>
|
||||
public SizeF(float width, float height)
|
||||
{
|
||||
backingVector = new Vector2(width, height);
|
||||
}
|
||||
|
||||
public SizeF(Vector2 vector)
|
||||
{
|
||||
backingVector = vector;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the width of this <see cref="SizeF"/>.
|
||||
/// </summary>
|
||||
public float Width => backingVector.X;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the height of this <see cref="SizeF"/>.
|
||||
/// </summary>
|
||||
public float Height => backingVector.Y;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this <see cref="SizeF"/> is empty.
|
||||
/// </summary>
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public bool IsEmpty => this.Equals(Empty);
|
||||
|
||||
/// <summary>
|
||||
/// Computes the sum of adding two sizes.
|
||||
/// </summary>
|
||||
/// <param name="left">The size on the left hand of the operand.</param>
|
||||
/// <param name="right">The size on the right hand of the operand.</param>
|
||||
/// <returns>
|
||||
/// The <see cref="Size"/>
|
||||
/// </returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static SizeF operator +(SizeF left, SizeF right)
|
||||
{
|
||||
return new SizeF(left.backingVector + right.backingVector);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Computes the difference left by subtracting one size from another.
|
||||
/// </summary>
|
||||
/// <param name="left">The size on the left hand of the operand.</param>
|
||||
/// <param name="right">The size on the right hand of the operand.</param>
|
||||
/// <returns>
|
||||
/// The <see cref="SizeF"/>
|
||||
/// </returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static SizeF operator -(SizeF left, SizeF right)
|
||||
{
|
||||
return new SizeF(left.backingVector - right.backingVector);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two <see cref="Size"/> objects for equality.
|
||||
/// </summary>
|
||||
/// <param name="left">
|
||||
/// The <see cref="Size"/> on the left side of the operand.
|
||||
/// </param>
|
||||
/// <param name="right">
|
||||
/// The <see cref="Size"/> on the right side of the operand.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// True if the current left is equal to the <paramref name="right"/> parameter; otherwise, false.
|
||||
/// </returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool operator ==(SizeF left, SizeF right)
|
||||
{
|
||||
return left.backingVector == right.backingVector;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compares two <see cref="Size"/> objects for inequality.
|
||||
/// </summary>
|
||||
/// <param name="left">
|
||||
/// The <see cref="Size"/> on the left side of the operand.
|
||||
/// </param>
|
||||
/// <param name="right">
|
||||
/// The <see cref="Size"/> on the right side of the operand.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// True if the current left is unequal to the <paramref name="right"/> parameter; otherwise, false.
|
||||
/// </returns>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool operator !=(SizeF left, SizeF right)
|
||||
{
|
||||
return left.backingVector != right.backingVector;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return this.GetHashCode(this);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override string ToString()
|
||||
{
|
||||
if (this.IsEmpty)
|
||||
{
|
||||
return "Size [ Empty ]";
|
||||
}
|
||||
|
||||
return $"Size [ Width={this.Width}, Height={this.Height} ]";
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is SizeF)
|
||||
{
|
||||
return this.Equals((SizeF)obj);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Equals(SizeF other)
|
||||
{
|
||||
return this.backingVector == other.backingVector;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the hash code for this instance.
|
||||
/// </summary>
|
||||
/// <param name="size">
|
||||
/// The instance of <see cref="Size"/> to return the hash code for.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// A 32-bit signed integer that is the hash code for this instance.
|
||||
/// </returns>
|
||||
private int GetHashCode(SizeF size)
|
||||
{
|
||||
return size.backingVector.GetHashCode();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
using System.Resources;
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("Shaper2D")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("Shaper2D")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2016")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
[assembly: NeutralResourcesLanguage("en")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
|
@ -1,57 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{8EC582C9-750F-48BC-B48E-B3F89A5BA7B7}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Shaper2D</RootNamespace>
|
||||
<AssemblyName>Shaper2D</AssemblyName>
|
||||
<DefaultLanguage>en-US</DefaultLanguage>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<TargetFrameworkProfile>
|
||||
</TargetFrameworkProfile>
|
||||
<TargetFrameworkVersion>v5.0</TargetFrameworkVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<!-- A reference to the entire .NET Framework is automatically included -->
|
||||
<None Include="project.json" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Primitives\Size.cs" />
|
||||
<Compile Include="Primitives\Point.cs" />
|
||||
<Compile Include="Primitives\Rectangle.cs" />
|
||||
<Compile Include="SimplePolygon.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
|
@ -1,354 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Numerics;
|
||||
using Shaper2D.Primitives;
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
namespace Shaper2D
|
||||
{
|
||||
internal class SimplePolygon
|
||||
{
|
||||
private Lazy<RectangleF> bounds;
|
||||
private IReadOnlyList<ILineSegment> segments;
|
||||
public bool IsHole { get; set; } = false;
|
||||
|
||||
public SimplePolygon(ILineSegment segments)
|
||||
: this(new[] { segments })
|
||||
{
|
||||
}
|
||||
|
||||
public SimplePolygon(IEnumerable<Vector2> points)
|
||||
: this(new LinearLineSegment(points))
|
||||
{
|
||||
}
|
||||
|
||||
public SimplePolygon(IEnumerable<ILineSegment> segments)
|
||||
{
|
||||
this.segments = new ReadOnlyCollection<ILineSegment>(segments.ToList());
|
||||
|
||||
bounds = new Lazy<RectangleF>(CalculateBounds);
|
||||
}
|
||||
|
||||
public int Corners
|
||||
{
|
||||
get
|
||||
{
|
||||
CalculatePoints();
|
||||
return polyCorners;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Vector2 this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
CalculatePoints();
|
||||
|
||||
var boundexIndex = Math.Abs(index) % polyCorners;
|
||||
if (index < 0)
|
||||
{
|
||||
// back counting
|
||||
index = polyCorners - boundexIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
index = boundexIndex;
|
||||
}
|
||||
|
||||
return new Vector2(polyX[index], polyY[index]);
|
||||
}
|
||||
}
|
||||
|
||||
public RectangleF Bounds => bounds.Value;
|
||||
|
||||
float[] constant;
|
||||
float[] multiple;
|
||||
bool calcualted = false;
|
||||
object locker = new object();
|
||||
|
||||
float[] polyY;
|
||||
float[] polyX;
|
||||
int polyCorners;
|
||||
bool calcualtedPoints = false;
|
||||
object lockerPoints = new object();
|
||||
|
||||
private void CalculatePoints()
|
||||
{
|
||||
if (calcualtedPoints) return;
|
||||
lock (lockerPoints)
|
||||
{
|
||||
if (calcualtedPoints) return;
|
||||
|
||||
var points = Simplify(segments).ToArray();
|
||||
polyX = points.Select(x => (float)x.X).ToArray();
|
||||
polyY = points.Select(x => (float)x.Y).ToArray();
|
||||
polyCorners = points.Length;
|
||||
calcualtedPoints = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void CalculateConstants()
|
||||
{
|
||||
if (calcualted) return;
|
||||
lock (locker)
|
||||
{
|
||||
if (calcualted) return;
|
||||
|
||||
// ensure points are availible
|
||||
CalculatePoints();
|
||||
|
||||
constant = new float[polyCorners];
|
||||
multiple = new float[polyCorners];
|
||||
int i, j = polyCorners - 1;
|
||||
|
||||
for (i = 0; i < polyCorners; i++)
|
||||
{
|
||||
if (polyY[j] == polyY[i])
|
||||
{
|
||||
constant[i] = polyX[i];
|
||||
multiple[i] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
constant[i] = polyX[i] - (polyY[i] * polyX[j]) / (polyY[j] - polyY[i]) + (polyY[i] * polyX[i]) / (polyY[j] - polyY[i]);
|
||||
multiple[i] = (polyX[j] - polyX[i]) / (polyY[j] - polyY[i]);
|
||||
}
|
||||
j = i;
|
||||
}
|
||||
|
||||
|
||||
|
||||
calcualted = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool PointInPolygon(float x, float y)
|
||||
{
|
||||
if (!Bounds.Contains((int)x, (int)y))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// things we cound do to make this more efficient
|
||||
// pre calculate simple regions that are inside the polygo and see if its contained in one of those
|
||||
|
||||
CalculateConstants();
|
||||
|
||||
|
||||
var j = polyCorners - 1;
|
||||
bool oddNodes = false;
|
||||
|
||||
for (var i = 0; i < polyCorners; i++)
|
||||
{
|
||||
if ((polyY[i] < y && polyY[j] >= y
|
||||
|| polyY[j] < y && polyY[i] >= y))
|
||||
{
|
||||
oddNodes ^= (y * multiple[i] + constant[i] < x);
|
||||
}
|
||||
j = i;
|
||||
}
|
||||
|
||||
return oddNodes;
|
||||
}
|
||||
|
||||
private float DistanceSquared(float x1, float y1, float x2, float y2, float xp, float yp)
|
||||
{
|
||||
var px = x2 - x1;
|
||||
var py = y2 - y1;
|
||||
|
||||
float something = px * px + py * py;
|
||||
|
||||
var u = ((xp - x1) * px + (yp - y1) * py) / something;
|
||||
|
||||
if (u > 1)
|
||||
{
|
||||
u = 1;
|
||||
}
|
||||
else if (u < 0)
|
||||
{
|
||||
u = 0;
|
||||
}
|
||||
|
||||
var x = x1 + u * px;
|
||||
var y = y1 + u * py;
|
||||
|
||||
var dx = x - xp;
|
||||
var dy = y - yp;
|
||||
|
||||
return dx * dx + dy * dy;
|
||||
}
|
||||
|
||||
private float CalculateDistance(Vector2 vector)
|
||||
{
|
||||
return CalculateDistance(vector.X, vector.Y);
|
||||
}
|
||||
|
||||
private float CalculateDistance(float x, float y)
|
||||
{
|
||||
|
||||
float distance = float.MaxValue;
|
||||
for (var i = 0; i < polyCorners; i++)
|
||||
{
|
||||
var next = i + 1;
|
||||
if (next == polyCorners)
|
||||
{
|
||||
next = 0;
|
||||
}
|
||||
|
||||
var lastDistance = DistanceSquared(polyX[i], polyY[i], polyX[next], polyY[next], x, y);
|
||||
|
||||
if (lastDistance < distance)
|
||||
{
|
||||
distance = lastDistance;
|
||||
}
|
||||
}
|
||||
|
||||
return (float)Math.Sqrt(distance);
|
||||
}
|
||||
|
||||
public float Distance(Vector2 vector)
|
||||
{
|
||||
return Distance(vector.X, vector.Y);
|
||||
}
|
||||
|
||||
public float Distance(float x, float y)
|
||||
{
|
||||
// we will do a nieve point in polygon test here for now
|
||||
// TODO optermise here and actually return a distance
|
||||
if (PointInPolygon(x, y))
|
||||
{
|
||||
if (IsHole)
|
||||
{
|
||||
return CalculateDistance(x, y);
|
||||
}
|
||||
//we are on line or inside
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (IsHole)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return CalculateDistance(x, y);
|
||||
}
|
||||
|
||||
private RectangleF CalculateBounds()
|
||||
{
|
||||
// ensure points are availible
|
||||
CalculatePoints();
|
||||
var minX = polyX.Min();
|
||||
var maxX = polyX.Max();
|
||||
var minY = polyY.Min();
|
||||
var maxY = polyY.Max();
|
||||
|
||||
return new RectangleF(minX, minY, maxX - minX, maxY - minY);
|
||||
}
|
||||
|
||||
private IEnumerable<Vector2> Simplify(IEnumerable<ILineSegment> segments)
|
||||
{
|
||||
//used to deduplicate
|
||||
HashSet<Vector2> pointHash = new HashSet<Vector2>();
|
||||
|
||||
foreach (var segment in segments)
|
||||
{
|
||||
var points = segment.Simplify();
|
||||
foreach (var p in points)
|
||||
{
|
||||
if (!pointHash.Contains(p))
|
||||
{
|
||||
pointHash.Add(p);
|
||||
yield return p;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Vector2? LineIntersectionPoint(Vector2 ps1, Vector2 pe1, Vector2 ps2, Vector2 pe2)
|
||||
{
|
||||
// Get A,B,C of first line - points : ps1 to pe1
|
||||
float A1 = pe1.Y - ps1.Y;
|
||||
float B1 = ps1.X - pe1.X;
|
||||
float C1 = A1 * ps1.X + B1 * ps1.Y;
|
||||
|
||||
// Get A,B,C of second line - points : ps2 to pe2
|
||||
float A2 = pe2.Y - ps2.Y;
|
||||
float B2 = ps2.X - pe2.X;
|
||||
float C2 = A2 * ps2.X + B2 * ps2.Y;
|
||||
|
||||
// Get delta and check if the lines are parallel
|
||||
float delta = A1 * B2 - A2 * B1;
|
||||
if (delta == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// now return the Vector2 intersection point
|
||||
return new Vector2(
|
||||
(B2 * C1 - B1 * C2) / delta,
|
||||
(A1 * C2 - A2 * C1) / delta
|
||||
);
|
||||
}
|
||||
|
||||
private RectangleF GetBounds(Vector2 start, Vector2 end)
|
||||
{
|
||||
var minX = Math.Min(start.X, end.X);
|
||||
var maxX = Math.Min(start.X, end.X);
|
||||
|
||||
var minY = Math.Min(start.Y, end.Y);
|
||||
var maxY = Math.Min(start.Y, end.Y);
|
||||
|
||||
return new RectangleF((int)minX, (int)minY, (int)maxX - (int)minX, (int)maxY - (int)minY);
|
||||
}
|
||||
|
||||
//public Vector2? GetIntersectionPoint(SimplePolygon polygon)
|
||||
//{
|
||||
// for (var i = 0; i < this.Corners; i++)
|
||||
// {
|
||||
// var prevPoint = this[i - 1];
|
||||
|
||||
// var currentPoint = this[i];
|
||||
|
||||
// RectangleF src = GetBounds(prevPoint, currentPoint);
|
||||
|
||||
|
||||
// for (var j = 0; j < polygon.Corners; j++)
|
||||
// {
|
||||
|
||||
// var prevPointOther = polygon[j - 1];
|
||||
|
||||
// var currentPointOther = polygon[j];
|
||||
|
||||
// RectangleF target = GetBounds(prevPointOther, currentPointOther);
|
||||
|
||||
// //first do they have overlapping bounding boxes
|
||||
|
||||
// if (src.Intersects(target))
|
||||
// {
|
||||
// //there boxes intersect lets find where there lines touch
|
||||
|
||||
// LineIntersectionPoint()
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
// }
|
||||
// // does this poly intersect with another
|
||||
|
||||
|
||||
//}
|
||||
|
||||
public SimplePolygon Clone()
|
||||
{
|
||||
List<Vector2> points = new List<Vector2>();
|
||||
for (var i = 0; i < this.polyCorners; i++)
|
||||
{
|
||||
points.Add(this[i]);
|
||||
}
|
||||
return new SimplePolygon(points) { IsHole = this.IsHole };
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,12 +0,0 @@
|
|||
{
|
||||
"supports": {},
|
||||
"dependencies": {
|
||||
"Microsoft.NETCore.Portable.Compatibility": "1.0.1",
|
||||
"NETStandard.Library": "1.6.0",
|
||||
"System.Numerics.Vectors": "4.3.0",
|
||||
"System.Runtime.Numerics": "4.0.1"
|
||||
},
|
||||
"frameworks": {
|
||||
"netstandard1.1": {}
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче