public static double OverlappingTimeSpan(ITimeSpan a, ITimeSpan b) { if (!UtilsCommon.IsOverlapping(a, b)) { return(0); } // |-----------------------| a // |-------------------| b if (a.StartTime <= b.StartTime && a.EndTime >= b.EndTime) { return(b.EndTime - b.StartTime); } // |-------------------| a // |-----------------------| b if (a.StartTime >= b.StartTime && a.EndTime <= b.EndTime) { return(a.EndTime - a.StartTime); } // |-------------------| a // |-----------------------| b if (a.StartTime <= b.StartTime && a.EndTime <= b.EndTime) { return(a.EndTime - b.StartTime); } // |-----------------------| a // |-------------------| b return(b.EndTime - a.StartTime); }
/// <summary> /// Returns the longest list of line containers, for which no line containers overlap. Addtionaly /// these containers are sorted by start time. /// </summary> public static List <LineContainer <T> > GetNonOverlappingTimeSpans <T>(LinkedList <T> lines, double threshold = 0) where T : ITimeSpan { var containers = new LinkedList <LineContainer <T> >(); var lineAlreadyAdded = new bool[lines.Count]; var lineANode = lines.First; var lineBNode = lines.First; int lineAindex = 0; int lineBindex = 0; while (lineANode != null) { if (lineAlreadyAdded [lineAindex]) { lineAindex++; lineANode = lineANode.Next; continue; } // create new container for this line var lineContainer = new LineContainer <T>(); lineContainer.AddLine(lineANode.Value); lineAlreadyAdded[lineAindex] = true; containers.AddLast(lineContainer); restartLoop: lineBNode = lineANode.Next; lineBindex = lineAindex + 1; while (lineBNode != null) { if (lineAlreadyAdded [lineBindex]) { lineBindex++; lineBNode = lineBNode.Next; continue; } // just test treshold if line collides with container if (UtilsCommon.IsOverlapping(lineBNode.Value, lineContainer)) { foreach (ITimeSpan timeSpanInContainer in lineContainer.TimeSpans) { if (UtilsCommon.OverlappingScore(lineBNode.Value, timeSpanInContainer) > threshold) { lineContainer.AddLine(lineBNode.Value); lineAlreadyAdded[lineBindex] = true; goto restartLoop; } } } lineBindex++; lineBNode = lineBNode.Next; } lineAindex++; lineANode = lineANode.Next; } // XXX: is sort necessary var containerList = containers.ToList(); containerList.Sort(); return(containerList); }