/// <summary> /// Squash path sections on one axis that share common ground /// </summary> private IEnumerable <PathSection> Squash(IEnumerable <PathSection> sections) { var orderedSections = sections .OrderBy(x => x.BottomLeft.X) .ThenBy(x => x.BottomLeft.Y) .ToList(); var squashed = new List <PathSection>(); var current = orderedSections.First(); foreach (var s in orderedSections) { if (s.BottomLeft.X > current.TopRight.X || s.BottomLeft.Y > current.TopRight.Y) { squashed.Add(current); current = s; } else { var mx = Math.Max(current.TopRight.X, s.TopRight.X); var my = Math.Max(current.TopRight.Y, s.TopRight.Y); current = new PathSection(current.BottomLeft, new Point(mx, my)); } } if (current != null) { squashed.Add(current); } return(squashed); }
/// <summary> /// Get intersection of two path sections /// </summary> /// <returns>Intersection, if exists, null otherwise</returns> private PathSection GetIntersection(PathSection a, PathSection b) { if (a.Horizontal == b.Horizontal) { // sections are parallel to each other // there can be [0, Min(a.Length, b.Length)] places in common if (a.Horizontal) { // horizontal lines if (a.BottomLeft.Y == b.BottomLeft.Y) { var bl = Math.Max(a.BottomLeft.X, b.BottomLeft.X); var tr = Math.Min(a.TopRight.X, b.TopRight.X); // return intersection if exists return(bl <= tr ? new PathSection(new Point(bl, a.BottomLeft.Y), new Point(tr, a.BottomLeft.Y)) : null); } else { // lines are in different Y axis, there cannot be any intersection return(null); } } else { // vertical lines if (a.BottomLeft.X == b.BottomLeft.X) { var bl = Math.Max(a.BottomLeft.Y, b.BottomLeft.Y); var tr = Math.Min(a.TopRight.Y, b.TopRight.Y); // return intersection if exists return(bl <= tr ? new PathSection(new Point(a.BottomLeft.X, bl), new Point(a.BottomLeft.X, tr)) : null); } else { // lines are in different X axis, there cannot be any intersection return(null); } } } else { // sections are perpendicular to each other // there can be [0, 1] places in common var h = a.Horizontal ? a : b; var v = a.Horizontal ? b : a; var c1 = (h.BottomLeft.X <= v.BottomLeft.X) && (v.BottomLeft.X <= h.TopRight.X); var c2 = (v.BottomLeft.Y <= h.BottomLeft.Y) && (h.BottomLeft.Y <= v.TopRight.Y); var ip = new Point(v.BottomLeft.X, h.BottomLeft.Y); return(c1 && c2 ? new PathSection(ip, ip) : null); } }