/// <summary> /// Add a new interval to this interval tree. /// Time complexity : O(d(log(n) + m)) where d is dimensions and /// m is the number of intervals that overlaps with this inserted interval. /// </summary> public void Insert(T[] start, T[] end) { validateDimensions(start, end); if (items.Contains(new Tuple <T[], T[]>(start, end))) { throw new Exception("Inteval exists."); } var currentTrees = new List <OneDimentionalIntervalTree <T> > { tree }; for (var i = 0; i < dimensions; i++) { var allOverlaps = new List <OneDimentionalIntervalTree <T> >(); foreach (var tree in currentTrees) { //insert in current dimension tree.Insert(new OneDimentionalInterval <T>(start[i], end[i], defaultValue)); //get all overlaps //and insert next dimension value to each overlapping node var overlaps = tree.GetOverlaps(new OneDimentionalInterval <T>(start[i], end[i], defaultValue)); foreach (var overlap in overlaps) { allOverlaps.Add(overlap.NextDimensionIntervals); } } currentTrees = allOverlaps; } items.Add(new Tuple <T[], T[]> (start, end)); Count++; }
/// <summary> /// Does this interval overlap with any interval in this interval tree? /// </summary> private List <Tuple <T[], T[]> > getOverlaps(OneDimentionalIntervalTree <T> currentTree, T[] start, T[] end, int dimension) { var nodes = currentTree.GetOverlaps(new OneDimentionalInterval <T>(start[dimension], end[dimension], defaultValue)); if (dimension + 1 == dimensions) { var result = new List <Tuple <T[], T[]> >(); foreach (var node in nodes) { var fStart = new T[dimensions]; var fEnd = new T[dimensions]; fStart[dimension] = node.Start; fEnd[dimension] = node.End[node.MatchingEndIndex]; var thisDimResult = new Tuple <T[], T[]>(fStart, fEnd); result.Add(thisDimResult); } return(result); } else { var result = new List <Tuple <T[], T[]> >(); foreach (var node in nodes) { var nextDimResult = getOverlaps(node.NextDimensionIntervals, start, end, dimension + 1); foreach (var nextResult in nextDimResult) { nextResult.Item1[dimension] = node.Start; nextResult.Item2[dimension] = node.End[node.MatchingEndIndex]; result.Add(nextResult); } } return(result); } }