namespace StellaOps.ElkSharp; internal static partial class ElkEdgeRoutingGeometry { private const double CoordinateTolerance = 0.5d; internal static IReadOnlyList FlattenSegments(IReadOnlyCollection edges) { var segments = new List(); foreach (var edge in edges) { segments.AddRange(FlattenSegments(edge)); } return segments; } internal static IReadOnlyList FlattenSegments(ElkRoutedEdge edge) { var segments = new List(); foreach (var section in edge.Sections) { var points = new List { section.StartPoint }; points.AddRange(section.BendPoints); points.Add(section.EndPoint); for (var i = 0; i < points.Count - 1; i++) { segments.Add(new RoutedEdgeSegment(edge.Id, points[i], points[i + 1])); } } return segments; } internal static double ComputePathLength(ElkRoutedEdge edge) { return FlattenSegments(edge).Sum(segment => ComputeSegmentLength(segment.Start, segment.End)); } internal static double ComputeSegmentLength(ElkPoint start, ElkPoint end) { var dx = end.X - start.X; var dy = end.Y - start.Y; return Math.Sqrt((dx * dx) + (dy * dy)); } internal static double ComputeLongestSharedSegmentLength(ElkRoutedEdge left, ElkRoutedEdge right) { var leftSegments = FlattenSegments(left); var rightSegments = FlattenSegments(right); var longest = 0d; foreach (var leftSegment in leftSegments) { foreach (var rightSegment in rightSegments) { longest = Math.Max(longest, ComputeSharedSegmentLength( leftSegment.Start, leftSegment.End, rightSegment.Start, rightSegment.End)); } } return longest; } internal static double ComputeLongestSharedApproachSegmentLength( IReadOnlyList leftPath, IReadOnlyList rightPath, int maxSegmentsFromEnd = 3) { var leftSegments = FlattenSegmentsNearEnd(leftPath, maxSegmentsFromEnd); var rightSegments = FlattenSegmentsNearEnd(rightPath, maxSegmentsFromEnd); var longest = 0d; foreach (var leftSegment in leftSegments) { foreach (var rightSegment in rightSegments) { longest = Math.Max(longest, ComputeSharedSegmentLength( leftSegment.Start, leftSegment.End, rightSegment.Start, rightSegment.End)); } } return longest; } internal static ElkPoint ResolveApproachPoint(ElkRoutedEdge edge) { var lastSection = edge.Sections.Last(); if (lastSection.BendPoints.Count > 0) { return lastSection.BendPoints.Last(); } return lastSection.StartPoint; } internal static bool PointsEqual(ElkPoint left, ElkPoint right) { return Math.Abs(left.X - right.X) <= CoordinateTolerance && Math.Abs(left.Y - right.Y) <= CoordinateTolerance; } }