// Copyright (c) Six Labors.
// Licensed under the Six Labors Split License.
using System;
using System.Numerics;
namespace SixLabors.ImageSharp.Drawing {
///
/// A star-shaped polygon defined by alternating inner and outer radii.
///
public sealed class StarPolygon : Polygon
{
///
/// Initializes a new instance of the class.
///
/// The center point of the star.
/// The number of star prongs.
/// The inner star radius.
/// The outer star radius.
/// The angle of rotation in degrees.
public StarPolygon(PointF location, int prongs, float innerRadii, float outerRadii, float angle)
: base(CreateSegment(location, innerRadii, outerRadii, prongs, angle))
{
}
///
/// Initializes a new instance of the class.
///
/// The center point of the star.
/// The number of star prongs.
/// The inner star radius.
/// The outer star radius.
public StarPolygon(PointF location, int prongs, float innerRadii, float outerRadii)
: this(location, prongs, innerRadii, outerRadii, 0)
{
}
///
/// Initializes a new instance of the class.
///
/// The x-coordinate of the star center.
/// The y-coordinate of the star center.
/// The number of star prongs.
/// The inner star radius.
/// The outer star radius.
/// The angle of rotation in degrees.
public StarPolygon(float x, float y, int prongs, float innerRadii, float outerRadii, float angle)
: this(new PointF(x, y), prongs, innerRadii, outerRadii, angle)
{
}
///
/// Initializes a new instance of the class.
///
/// The x-coordinate of the star center.
/// The y-coordinate of the star center.
/// The number of star prongs.
/// The inner star radius.
/// The outer star radius.
public StarPolygon(float x, float y, int prongs, float innerRadii, float outerRadii)
: this(new PointF(x, y), prongs, innerRadii, outerRadii)
{
}
private static LinearLineSegment CreateSegment(Vector2 location, float innerRadii, float outerRadii, int prongs, float angle)
{
Guard.MustBeGreaterThan(prongs, 2, nameof(prongs));
Guard.MustBeGreaterThan(innerRadii, 0, nameof(innerRadii));
Guard.MustBeGreaterThan(outerRadii, 0, nameof(outerRadii));
Vector2 distanceVectorInner = new(0, innerRadii);
Vector2 distanceVectorOuter = new(0, outerRadii);
int vertices = prongs * 2;
float anglePerSegments = (float)(2 * Math.PI / vertices);
float current = GeometryUtilities.DegreeToRadian(angle);
PointF[] points = new PointF[vertices];
Vector2 distance = distanceVectorInner;
for (int i = 0; i < vertices; i++)
{
if (distance == distanceVectorInner)
{
distance = distanceVectorOuter;
}
else
{
distance = distanceVectorInner;
}
Vector2 rotated = PointF.Transform(distance, Matrix4x4.CreateRotationZ(current));
points[i] = rotated + location;
current += anglePerSegments;
}
return new LinearLineSegment(points);
}
}
}