// // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. // namespace ImageSharp.Drawing.Shapes { using System.Collections; using System.Collections.Generic; using System.Numerics; using Paths; /// /// A shape made up of a single path made up of one of more s /// public sealed class Polygon : IShape, IPath { private readonly InternalPath innerPath; private readonly IEnumerable pathCollection; /// /// Initializes a new instance of the class. /// /// The segments. public Polygon(params ILineSegment[] segments) { this.innerPath = new InternalPath(segments, true); this.pathCollection = new[] { this }; } /// /// Initializes a new instance of the class. /// /// The segment. public Polygon(ILineSegment segment) { this.innerPath = new InternalPath(segment, true); this.pathCollection = new[] { this }; } /// /// Gets the bounding box of this shape. /// /// /// The bounds. /// public RectangleF Bounds => this.innerPath.Bounds; /// /// Gets the length of the path /// /// /// The length. /// public float Length => this.innerPath.Length; /// /// Gets a value indicating whether this instance is closed. /// /// /// true if this instance is closed; otherwise, false. /// public bool IsClosed => true; /// /// Gets the maximum number intersections that a shape can have when testing a line. /// /// /// The maximum intersections. /// public int MaxIntersections => this.innerPath.Points.Length; /// /// the distance of the point from the outline of the shape, if the value is negative it is inside the polygon bounds /// /// The point. /// /// The distance of the point away from the shape /// public float Distance(Vector2 point) { bool isInside = this.innerPath.PointInPolygon(point); float distance = this.innerPath.DistanceFromPath(point).DistanceFromPath; if (isInside) { return -distance; } return distance; } /// /// Returns an enumerator that iterates through the collection. /// /// /// An enumerator that can be used to iterate through the collection. /// public IEnumerator GetEnumerator() { return this.pathCollection.GetEnumerator(); } /// /// Returns an enumerator that iterates through a collection. /// /// /// An object that can be used to iterate through the collection. /// IEnumerator IEnumerable.GetEnumerator() { return this.pathCollection.GetEnumerator(); } /// /// Calcualtes the distance along and away from the path for a specified point. /// /// The point along the path. /// /// distance metadata about the point. /// PointInfo IPath.Distance(Vector2 point) { return this.innerPath.DistanceFromPath(point); } /// /// Returns the current shape as a simple linear path. /// /// /// Returns the current as simple linear path. /// public Vector2[] AsSimpleLinearPath() { return this.innerPath.Points; } /// /// Based on a line described by and /// populate a buffer for all points on the polygon that the line intersects. /// /// The start point of the line. /// The end point of the line. /// The buffer that will be populated with intersections. /// The count. /// The offset. /// /// The number of intersections populated into the buffer. /// public int FindIntersections(Vector2 start, Vector2 end, Vector2[] buffer, int count, int offset) { return this.innerPath.FindIntersections(start, end, buffer, count, offset); } } }