using System; using System.Collections.Generic; using System.Collections.ObjectModel; using MultiWheelC.TrajectoryPlanning.CoarsePath; using MultiWheelC.TrajectoryPlanning.PathSmoothing; namespace MultiWheelC.TrajectoryPlanning.EMPlanner; public sealed class DirectionSegmentView { public DirectionSegmentView( int segmentIndex, TravelDirection direction, IReadOnlyList points, ReferenceBoundary startBoundary, ReferenceBoundary endBoundary, double sourceStartArcLength) { if (segmentIndex < 0) throw new ArgumentOutOfRangeException(nameof(segmentIndex)); if (points == null || points.Count == 0) throw new ArgumentException("A direction segment requires points.", nameof(points)); if (startBoundary == null || endBoundary == null) throw new ArgumentNullException(startBoundary == null ? nameof(startBoundary) : nameof(endBoundary)); if (startBoundary.SegmentIndex != segmentIndex || endBoundary.SegmentIndex != segmentIndex) throw new ArgumentException("Boundary segment identity must match the segment."); if (points[0] == null || Math.Abs(points[0].ArcLength) > 1e-12d) throw new ArgumentException("A direction segment must begin at local S zero.", nameof(points)); var copy = new List(points.Count); double previousS = -1d; for (int index = 0; index < points.Count; index++) { SmoothedPathPoint point = points[index]; if (point == null || point.Direction != direction || point.ArcLength < 0d || point.ArcLength < previousS) throw new ArgumentException("Direction segment points are invalid.", nameof(points)); copy.Add(point); previousS = point.ArcLength; } if (Math.Abs(endBoundary.SegmentLocalS - previousS) > 1e-12d) throw new ArgumentException("End boundary must match the final local S.", nameof(endBoundary)); SegmentIndex = segmentIndex; Direction = direction; Points = new ReadOnlyCollection(copy); StartBoundary = startBoundary; EndBoundary = endBoundary; SourceStartArcLength = sourceStartArcLength; } public int SegmentIndex { get; } public TravelDirection Direction { get; } public IReadOnlyList Points { get; } public ReferenceBoundary StartBoundary { get; } public ReferenceBoundary EndBoundary { get; } public double SourceStartArcLength { get; } public double LengthMeters { get { return EndBoundary.SegmentLocalS; } } }