// Copyright (c) Six Labors. // Licensed under the Six Labors Split License. using System; using System.Numerics; namespace SixLabors.ImageSharp.Drawing { /// /// A pie sector polygon defined by a center point, radii, rotation, and arc sweep. /// public sealed class PiePolygon : Polygon { /// /// Initializes a new instance of the class. /// /// The center point of the pie sector. /// The x and y radii of the pie ellipse. /// The ellipse rotation in degrees. /// The pie start angle in degrees. /// The pie sweep angle in degrees. public PiePolygon(PointF center, SizeF radius, float rotation, float startAngle, float sweepAngle) : base(CreateSegments(center, radius, rotation, startAngle, sweepAngle)) { } /// /// Initializes a new instance of the class. /// /// The center point of the pie sector. /// The x and y radii of the pie ellipse. /// The pie start angle in degrees. /// The pie sweep angle in degrees. public PiePolygon(PointF center, SizeF radius, float startAngle, float sweepAngle) : this(center, radius, 0F, startAngle, sweepAngle) { } /// /// Initializes a new instance of the class. /// /// The x-coordinate of the pie center. /// The y-coordinate of the pie center. /// The x-radius of the pie ellipse. /// The y-radius of the pie ellipse. /// The ellipse rotation in degrees. /// The pie start angle in degrees. /// The pie sweep angle in degrees. public PiePolygon(float x, float y, float radiusX, float radiusY, float rotation, float startAngle, float sweepAngle) : this(new PointF(x, y), new SizeF(radiusX, radiusY), rotation, startAngle, sweepAngle) { } /// /// Initializes a new instance of the class. /// /// The x-coordinate of the pie center. /// The y-coordinate of the pie center. /// The x-radius of the pie ellipse. /// The y-radius of the pie ellipse. /// The pie start angle in degrees. /// The pie sweep angle in degrees. public PiePolygon(float x, float y, float radiusX, float radiusY, float startAngle, float sweepAngle) : this(x, y, radiusX, radiusY, 0F, startAngle, sweepAngle) { } private PiePolygon(ILineSegment[] segments) : base(segments, true) { } /// public override IPath Transform(Matrix4x4 matrix) { if (matrix.IsIdentity) { return this; } ILineSegment[] segments = new ILineSegment[this.LineSegments.Count]; for (int i = 0; i < segments.Length; i++) { segments[i] = this.LineSegments[i].Transform(matrix); } return new PiePolygon(segments); } private static ILineSegment[] CreateSegments(PointF center, SizeF radius, float rotation, float startAngle, float sweepAngle) { Guard.MustBeGreaterThan(radius.Width, 0, "radiusX"); Guard.MustBeGreaterThan(radius.Height, 0, "radiusY"); PointF arcStart = GetArcPoint(center, radius, rotation, startAngle); ArcLineSegment arc = new(center, radius, rotation, startAngle, sweepAngle); return [ new LinearLineSegment(center, arcStart), arc, new LinearLineSegment(arc.EndPoint, center) ]; } private static PointF GetArcPoint(PointF center, SizeF radius, float rotation, float angle) { float rotationRadians = rotation * (MathF.PI / 180F); float angleRadians = angle * (MathF.PI / 180F); float cosRotation = MathF.Cos(rotationRadians); float sinRotation = MathF.Sin(rotationRadians); float cosAngle = MathF.Cos(angleRadians); float sinAngle = MathF.Sin(angleRadians); return new PointF( center.X + (radius.Width * cosRotation * cosAngle) - (radius.Height * sinRotation * sinAngle), center.Y + (radius.Width * sinRotation * cosAngle) + (radius.Height * cosRotation * sinAngle)); } } }