public IntDomain2 Intersect(IntInterval interval) { if (interval.IsEmpty()) { return(m_Empty); } // 1, 6 if (!IntersectsWith(interval)) { return(m_Empty); } // 3 if (m_Interval.Min >= interval.Min && m_Interval.Max <= interval.Max) { return(this); } IntInterval intv = m_Interval.Intersect(interval); IntDomain2 result = new IntDomain2(); result.m_Interval = intv; if (!IsSimple()) { result.m_IntervalList = new List <IntInterval>(m_IntervalList.Count); int idx = 0; // 6 : completely before for ( ; idx < m_IntervalList.Count && m_IntervalList[idx].Max < interval.Min; ++idx) { } ; // 2 if (idx < m_IntervalList.Count && m_IntervalList[idx].Min < interval.Min && m_IntervalList[idx].Max <= interval.Max) { result.m_IntervalList.Add(m_IntervalList[idx].Intersect(interval)); ++idx; } // 4 if (idx < m_IntervalList.Count && m_IntervalList[idx].Min <interval.Min && m_IntervalList[idx].Max> interval.Max) { result.m_IntervalList.Add(m_IntervalList[idx].Intersect(interval)); } // 3 else { for ( ; idx < m_IntervalList.Count && interval.Contains(m_IntervalList[idx]); ++idx) { result.m_IntervalList.Add(m_IntervalList[idx]); } } // 5 if (idx < m_IntervalList.Count && m_IntervalList[idx].Min > interval.Min && m_IntervalList[idx].Max >= interval.Max) { result.m_IntervalList.Add(m_IntervalList[idx].Intersect(interval)); ++idx; } // 1 : complete after can be skipped result.CheckSimple(); } return(result); }
public IntDomain2 Union(IntDomain2 domain) { if (ReferenceEquals(domain, this)) { return(this); } if (domain.IsEmpty()) { return(this); } if (IsEmpty()) { return(domain); } if (domain.IsSimple()) { return(Union(domain.m_Interval)); } if (IsSimple()) { if (m_Interval.Contains(domain.m_Interval)) { return(this); } return(domain.Union(m_Interval)); } else { IntDomain2 result = new IntDomain2(); result.m_Interval = m_Interval.Union(domain.m_Interval); result.m_IntervalList = new List <IntInterval>(m_IntervalList.Count + domain.m_IntervalList.Count); // 1 : completely before if (domain.m_Interval.Max < m_Interval.Min - 1) { result.m_IntervalList.AddRange(domain.m_IntervalList); result.m_IntervalList.AddRange(m_IntervalList); } // 6 : completely after else if (domain.m_Interval.Min > m_Interval.Max + 1) { result.m_IntervalList.AddRange(m_IntervalList); result.m_IntervalList.AddRange(domain.m_IntervalList); } else { int idx = 0; int domIdx = 0; bool equal = true; while (idx < m_IntervalList.Count || domIdx < domain.m_IntervalList.Count) { // 6 : if (idx == m_IntervalList.Count) { equal = false; for ( ; domIdx < domain.m_IntervalList.Count; ++domIdx) { result.m_IntervalList.Add(domain.m_IntervalList[domIdx]); } } // 1 : remaining intervals after else if (domIdx == domain.m_IntervalList.Count) { for ( ; idx < m_IntervalList.Count; ++idx) { result.m_IntervalList.Add(m_IntervalList[idx]); } } else { IntInterval intv = m_IntervalList[idx]; IntInterval domIntv = domain.m_IntervalList[domIdx]; // 1 : completely before if (domIntv.Max < intv.Min - 1) { equal = false; result.m_IntervalList.Add(domIntv); ++domIdx; } // 6 : completely after else if (domIntv.Min > intv.Max + 1) { result.m_IntervalList.Add(intv); ++idx; } // 3 else if (domIntv.Min < intv.Min && domIntv.Max > intv.Max) { equal = false; ++idx; } // 4 else if (domIntv.Min >= intv.Min && domIntv.Max <= intv.Max) { ++domIdx; } // 2, 5 else { equal = false; IntInterval intvTmp = intv.Union(domIntv); ++idx; // contains... for ( ; idx < m_IntervalList.Count && intvTmp.Contains(m_IntervalList[idx]); ++idx) { } ; // adjacent | intersect... while (idx < m_IntervalList.Count && IntersectsWithOrIsAdjacent(m_IntervalList[idx], intvTmp)) { intvTmp = intvTmp.Union(m_IntervalList[idx]); ++idx; } result.m_IntervalList.Add(intvTmp); ++domIdx; } } } if (equal) { return(this); } result.CheckSimple(); } return(result); } }
public IntDomain2 Difference(IntInterval interval) { if (interval.IsEmpty()) { return(this); } // 1, 6 if (!IntersectsWith(interval)) { return(this); } // 3 : completely remove interval => empty if (interval.Min <= m_Interval.Min && interval.Max >= m_Interval.Max) { return(m_Empty); } // Result domain IntDomain2 result = new IntDomain2(); result.m_Interval = m_Interval.Difference(interval); if (IsSimple()) { // 4 : divide into two intervals... if (interval.Min > m_Interval.Min && interval.Max < m_Interval.Max) { result.m_IntervalList = new List <IntInterval>(2); result.m_IntervalList.Add(new IntInterval(m_Interval.Min, interval.Min - 1)); result.m_IntervalList.Add(new IntInterval(interval.Max + 1, m_Interval.Max)); } } else { result.m_IntervalList = new List <IntInterval>(m_IntervalList.Count + 1); int idx = 0; // 6 for ( ; idx < m_IntervalList.Count && m_IntervalList[idx].Max < interval.Min; ++idx) { result.m_IntervalList.Add(m_IntervalList[idx]); } // 2 if (idx < m_IntervalList.Count && m_IntervalList[idx].Min < interval.Min && m_IntervalList[idx].Max <= interval.Max) { result.m_IntervalList.Add(m_IntervalList[idx].Difference(interval)); ++idx; } // 4 : divide into two intervals... if (idx < m_IntervalList.Count && m_IntervalList[idx].Min <interval.Min && m_IntervalList[idx].Max> interval.Max) { result.m_IntervalList.Add(new IntInterval(m_Interval.Min, interval.Min - 1)); result.m_IntervalList.Add(new IntInterval(interval.Max + 1, m_Interval.Max)); } // 3 else { for ( ; idx < m_IntervalList.Count && interval.Contains(m_IntervalList[idx]); ++idx) { } } // 5 if (idx < m_IntervalList.Count && m_IntervalList[idx].Min >= interval.Min && m_IntervalList[idx].Max > interval.Max) { result.m_IntervalList.Add(m_IntervalList[idx].Difference(interval)); ++idx; } // 1 for ( ; idx < m_IntervalList.Count; ++idx) { result.m_IntervalList.Add(m_IntervalList[idx]); } result.CheckSimple(); } return(result); }
public IntDomain2 Union(IntInterval interval) { if (interval.IsEmpty()) { return(this); } if (IsEmpty()) { return(new IntDomain2(interval)); } // ~4 if (Contains(interval)) { return(this); } // 3 if (interval.Contains(m_Interval)) { return(new IntDomain2(interval)); } if (IsSimple()) { // 1 if (interval.Max < m_Interval.Min - 1) { return(new IntDomain2(interval, m_Interval)); } // 6 if (interval.Min > m_Interval.Max + 1) { return(new IntDomain2(m_Interval, interval)); } // 2, 5 return(new IntDomain2(m_Interval.Union(interval))); } else { IntDomain2 result = new IntDomain2(); result.m_Interval = m_Interval.Union(interval); result.m_IntervalList = new List <IntInterval>(m_IntervalList.Count + 1); // 1 if (interval.Max < m_Interval.Min - 1) { result.m_IntervalList.Add(interval); result.m_IntervalList.AddRange(m_IntervalList); } // 6 else if (interval.Min > m_Interval.Max + 1) { result.m_IntervalList.AddRange(m_IntervalList); result.m_IntervalList.Add(interval); } else { // 6 int idx = 0; for ( ; idx < m_IntervalList.Count && m_IntervalList[idx].Max < interval.Min - 1; ++idx) { result.m_IntervalList.Add(m_IntervalList[idx]); } if (idx < m_IntervalList.Count) { IntInterval intv = interval; // adjacent | intersect if (idx < m_IntervalList.Count && IntersectsWithOrIsAdjacent(m_IntervalList[idx], intv)) { intv = intv.Union(m_IntervalList[idx]); ++idx; } // 3 for ( ; idx < m_IntervalList.Count && intv.Contains(m_IntervalList[idx]); ++idx) { } // adjacent | intersect if (idx < m_IntervalList.Count && IntersectsWithOrIsAdjacent(m_IntervalList[idx], intv)) { intv = intv.Union(m_IntervalList[idx]); ++idx; } result.m_IntervalList.Add(intv); // 1 for ( ; idx < m_IntervalList.Count; ++idx) { result.m_IntervalList.Add(m_IntervalList[idx]); } } else { // 6 result.m_IntervalList.Add(interval); } } result.CheckSimple(); return(result); } }