Files
git.stella-ops.org/src/__Libraries/StellaOps.ElkSharp/ElkEdgeRoutingGeometry.cs

110 lines
3.3 KiB
C#

namespace StellaOps.ElkSharp;
internal static partial class ElkEdgeRoutingGeometry
{
private const double CoordinateTolerance = 0.5d;
internal static IReadOnlyList<RoutedEdgeSegment> FlattenSegments(IReadOnlyCollection<ElkRoutedEdge> edges)
{
var segments = new List<RoutedEdgeSegment>();
foreach (var edge in edges)
{
segments.AddRange(FlattenSegments(edge));
}
return segments;
}
internal static IReadOnlyList<RoutedEdgeSegment> FlattenSegments(ElkRoutedEdge edge)
{
var segments = new List<RoutedEdgeSegment>();
foreach (var section in edge.Sections)
{
var points = new List<ElkPoint> { 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<ElkPoint> leftPath,
IReadOnlyList<ElkPoint> 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;
}
}