using System.Collections.Generic;
using OpenNest.Geometry;
using OpenNest.Math;
namespace OpenNest.Desktop.Rendering;
/// One drawn piece of a figure, ending at .
public abstract record PathSegment(Vector End);
/// A straight line from the previous point to .
public sealed record LineTo(Vector End) : PathSegment(End);
///
/// A circular arc about , in degrees measured from +X toward +Y (the
/// y-up drawing frame); a positive sweep turns counterclockwise. A sweep of 360 degrees is a full
/// circle. Toolkits join the previous point to the arc's start with a line, as GDI+ and Skia do.
///
public sealed record ArcTo(Vector End, Vector Center, double Radius, double StartAngle, double SweepAngle)
: PathSegment(End)
{
public bool IsFullCircle => System.Math.Abs(SweepAngle) >= 360.0;
}
///
/// One continuous run of drawing moves: a move to followed by
/// . Toolkit-neutral; each desktop app converts figures to its own path type.
///
public sealed class PathFigure
{
public PathFigure(Vector start, IReadOnlyList segments)
{
Start = start;
Segments = segments;
}
public Vector Start { get; }
public IReadOnlyList Segments { get; }
public Vector End => Segments.Count == 0 ? Start : Segments[Segments.Count - 1].End;
/// Whether the figure ends where it starts, so a toolkit may close it.
public bool IsClosed => Start.DistanceTo(End) <= Tolerance.Epsilon;
public override string ToString() => $"{Start} +{Segments.Count} {(IsClosed ? "closed" : "open")}";
}