public bool IntersectsWith(FltDomain domain) { if (ReferenceEquals(domain, this)) { return(true); } if (domain.IsEmpty()) { return(false); } // 1, 6 if (!m_Interval.IntersectsWith(domain.m_Interval)) { return(false); } if (domain.IsSimple()) { return(IntersectsWith(domain.m_Interval)); } if (IsSimple()) { return(domain.IntersectsWith(m_Interval)); } int index0 = 0; int index1 = 0; bool intersect = false; while (index0 < m_IntervalList.Count && index1 < domain.m_IntervalList.Count && !intersect) { FltInterval ival0 = m_IntervalList[index0]; FltInterval ival1 = domain.m_IntervalList[index1]; if (ival0.Max < ival1.Min) { ++index0; } else if (ival1.Max < ival0.Min) { ++index1; } else { intersect = true; } } return(intersect); }
public FltDomain Subtract(FltDomain domain) { FltInterval interval = domain.Interval; if (interval.IsZero()) { return(this); } return(new FltDomain((m_Interval - interval).Inflate())); }
public override bool Equals(object obj) { if (ReferenceEquals(this, obj)) { return(true); } FltDomain domain = obj as FltDomain; if (!ReferenceEquals(domain, null)) { return(Equals(domain)); } return(false); }
public FltDomain Multiply(FltDomain domain) { FltInterval interval = domain.Interval; if (interval.IsOne()) { return(this); } FltInterval result = m_Interval * interval; if (result.IsEmpty()) { return(m_Empty); } return(new FltDomain(result.Inflate())); }
public FltDomain Abs() { if (IsEmpty()) { return(m_Empty); } if (m_Interval.Min >= 0) { return(this); } if (m_Interval.Max <= 0) { return(Negate()); } FltDomain lower = -Intersect(double.MinValue, 0); FltDomain upper = Intersect(0, double.MaxValue); return(lower.Union(upper)); }
public FltDomain Sqrt() { if (IsEmpty()) { return(m_Empty); } if (m_Interval.Max < 0) { return(m_Empty); } if (m_Interval.IsZero() || m_Interval.IsOne()) { return(this); } FltDomain result = new FltDomain(); result.m_Interval = m_Interval.Sqrt(); if (IsSimple()) { return(result); } result.m_IntervalList = new List <FltInterval>(m_IntervalList.Count); foreach (FltInterval interval in m_IntervalList) { if (interval.Max >= 0) { result.m_IntervalList.Add(interval.Sqrt()); } } result.CheckSimple(); return(result); }
public FltDomain Inflate() { if (IsEmpty()) { return(m_Empty); } FltDomain result = new FltDomain(); result.m_Interval = m_Interval.Inflate(); if (IsSimple()) { return(result); } result.m_IntervalList = new List <FltInterval>(m_IntervalList.Count); foreach (FltInterval interval in m_IntervalList) { result.m_IntervalList.Add(interval.Inflate()); } return(result); }
public FltDomain Negate() { if (m_Interval.IsBound() && m_Interval.Min == 0) { return(this); } FltDomain result = new FltDomain(); result.m_Interval = -m_Interval; if (IsSimple()) { return(result); } result.m_IntervalList = new List <FltInterval>(m_IntervalList.Count); foreach (FltInterval interval in m_IntervalList) { result.m_IntervalList.Add(-interval); } return(result); }
public FltDomain Divide(double value) { if (value == 1) { return(this); } FltDomain result = new FltDomain(); result.m_Interval = m_Interval / value; if (IsSimple()) { return(result); } result.m_IntervalList = new List <FltInterval>(m_IntervalList.Count); foreach (FltInterval interval in m_IntervalList) { result.m_IntervalList.Add(interval / value); } return(result); }
public FltDomain Divide(FltDomain domain) { FltInterval interval = domain.Interval; if (interval.IsOne()) { return(this); } bool div2 = false; FltInterval intv1 = FltInterval.Divide1(m_Interval, interval, ref div2); if (div2) { FltInterval intv2 = FltInterval.Divide2(m_Interval, interval, div2); return(new FltDomain(new FltInterval[] { intv1.Inflate(), intv2.Inflate() })); } else { return(new FltDomain(intv1.Inflate())); } }
public FltDomain Intersect(FltInterval interval) { if (interval.IsEmpty()) { return(m_Empty); } // 1, 6 if (!IntersectsWith(interval)) { return(m_Empty); } // 3 if (interval.Min <= m_Interval.Min && interval.Max >= m_Interval.Max) { //if( interval.Contains( m_Interval ) ) return(this); } FltInterval intv = m_Interval.Intersect(interval); FltDomain result = new FltDomain(); result.m_Interval = intv; if (!IsSimple()) { result.m_IntervalList = new List <FltInterval>(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 && I2_IntersectMin(m_IntervalList[idx], interval)) { result.m_IntervalList.Add(m_IntervalList[idx].Intersect(interval)); ++idx; } // 4 if (idx < m_IntervalList.Count && I4_Divide(m_IntervalList[idx], interval)) { 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 && I5_IntersectMax(m_IntervalList[idx], interval)) { result.m_IntervalList.Add(m_IntervalList[idx].Intersect(interval)); ++idx; } // 1 : complete after can be skipped result.UpdateInterval(); } return(result); }
public FltDomain Difference(FltDomain domain) { if (ReferenceEquals(domain, this)) { return(m_Empty); } if (domain.IsEmpty()) { return(this); } if (domain.IsSimple()) { return(Difference(domain.m_Interval)); } //1, 6 if (!IntersectsWith(domain.m_Interval)) { return(this); } // Need to be a bit smart, put our interval in a list, in case it gets chopped up. List <FltInterval> intervalList; if (IsSimple()) { intervalList = new List <FltInterval>(1); intervalList.Add(m_Interval); } else { intervalList = m_IntervalList; } FltDomain result = new FltDomain(); result.m_IntervalList = new List <FltInterval>(intervalList.Count + domain.m_IntervalList.Count); int idx = 0; int domIdx = 0; while (idx < intervalList.Count || domIdx < domain.m_IntervalList.Count) { // 6 if (idx == intervalList.Count) { domIdx = domain.m_IntervalList.Count; } // 1 else if (domIdx == domain.m_IntervalList.Count) { idx = intervalList.Count; } else { FltInterval intv = intervalList[idx]; FltInterval domIntv = domain.m_IntervalList[domIdx]; // 1 : completely before if (domIntv.Max < intv.Min) { ++domIdx; } // 6 : completely after else if (domIntv.Min > intv.Max) { result.m_IntervalList.Add(intv); ++idx; } // 3 else if (domIntv.Contains(intv)) { ++idx; } // 4 : divide into two intervals... else if (I4_Divide(intv, domIntv)) { while (domIdx < domain.m_IntervalList.Count && I4_Divide(intv, domIntv)) { result.m_IntervalList.Add(new FltInterval(intv.Min, Epsilon.Prev(domIntv.Min))); intv = new FltInterval(Epsilon.Next(domIntv.Max), intv.Max); ++domIdx; if (domIdx < domain.m_IntervalList.Count) { domIntv = domain.m_IntervalList[domIdx]; } } result.m_IntervalList.Add(intv); } // 2 else if (I2_IntersectMin(intv, domIntv)) { result.m_IntervalList.Add(intv.Difference(domIntv)); ++domIdx; } // 5 else if (I5_IntersectMax(intv, domIntv)) { result.m_IntervalList.Add(intv.Difference(domIntv)); ++idx; } } } result.UpdateInterval(); return(result); }
public FltDomain Difference(FltInterval interval) { if (interval.IsEmpty()) { return(this); } // 1, 6 if (!IntersectsWith(interval)) { return(this); } // 3 : completely remove interval => empty if (interval.Contains(m_Interval)) { return(m_Empty); } // Result domain FltDomain result = new FltDomain(); result.m_Interval = m_Interval.Difference(interval); if (IsSimple()) { // 4 : divide into two intervals... if (I4_Divide(interval, m_Interval)) { result.m_IntervalList = new List <FltInterval>(2); result.m_IntervalList.Add(new FltInterval(m_Interval.Min, Epsilon.Prev(interval.Min))); result.m_IntervalList.Add(new FltInterval(Epsilon.Next(interval.Max), m_Interval.Max)); } } else { result.m_IntervalList = new List <FltInterval>(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 && I2_IntersectMin(interval, m_IntervalList[idx])) { result.m_IntervalList.Add(m_IntervalList[idx].Difference(interval)); ++idx; } // 4 : divide into two intervals... if (idx < m_IntervalList.Count && I4_Divide(interval, m_IntervalList[idx])) { result.m_IntervalList.Add(new FltInterval(m_Interval.Min, Epsilon.Prev(interval.Min))); result.m_IntervalList.Add(new FltInterval(Epsilon.Next(interval.Max), m_Interval.Max)); } // 3 else { for ( ; idx < m_IntervalList.Count && interval.Contains(m_IntervalList[idx]); ++idx) { } } // 5 if (idx < m_IntervalList.Count && I5_IntersectMax(interval, m_IntervalList[idx])) { 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 FltDomain Union(FltDomain 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 { FltDomain result = new FltDomain(); result.m_Interval = m_Interval.Union(domain.m_Interval); result.m_IntervalList = new List <FltInterval>(m_IntervalList.Count + domain.m_IntervalList.Count); // 1 : completely before if (domain.m_Interval.Max < m_Interval.Min) { 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) { 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 { FltInterval intv = m_IntervalList[idx]; FltInterval domIntv = domain.m_IntervalList[domIdx]; // 1 : completely before if (domIntv.Max < intv.Min) { equal = false; result.m_IntervalList.Add(domIntv); ++domIdx; } // 6 : completely after else if (domIntv.Min > intv.Max) { result.m_IntervalList.Add(intv); ++idx; } // 3 else if (domIntv.Contains(intv)) { equal = false; ++idx; } // 3 else if (intv.Contains(domIntv)) { ++domIdx; } // 2, 5 else { equal = false; FltInterval intvTmp = intv.Union(domIntv); ++idx; // contains... for ( ; idx < m_IntervalList.Count && intvTmp.Contains(m_IntervalList[idx]); ++idx) { } ; // intersect... while (idx < m_IntervalList.Count && m_IntervalList[idx].IntersectsWith(intvTmp)) { intvTmp = intvTmp.Union(m_IntervalList[idx]); ++idx; } result.m_IntervalList.Add(intvTmp); ++domIdx; } } } if (equal) { return(this); } result.CheckSimple(); } return(result); } }
public FltDomain Union(FltInterval interval) { if (interval.IsEmpty()) { return(this); } if (IsEmpty()) { return(new FltDomain(interval)); } // ~4 if (Contains(interval)) { return(this); } // 3 if (interval.Contains(m_Interval)) { return(new FltDomain(interval)); } if (IsSimple()) { // 1 if (interval.Max < m_Interval.Min) { return(new FltDomain(interval, m_Interval)); } // 6 if (interval.Min > m_Interval.Max) { return(new FltDomain(m_Interval, interval)); } // 2, 5 return(new FltDomain(m_Interval.Union(interval))); } else { FltDomain result = new FltDomain(); result.m_Interval = m_Interval.Union(interval); result.m_IntervalList = new List <FltInterval>(m_IntervalList.Count + 1); // 1 if (interval.Max < m_Interval.Min) { result.m_IntervalList.Add(interval); result.m_IntervalList.AddRange(m_IntervalList); } // 6 else if (interval.Min > m_Interval.Max) { 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); ++idx) { result.m_IntervalList.Add(m_IntervalList[idx]); } if (idx < m_IntervalList.Count) { FltInterval intv = interval; // intersect if (idx < m_IntervalList.Count && m_IntervalList[idx].IntersectsWith(intv)) { intv = intv.Union(m_IntervalList[idx]); ++idx; } // 3 for ( ; idx < m_IntervalList.Count && intv.Contains(m_IntervalList[idx]); ++idx) { } // intersect if (idx < m_IntervalList.Count && m_IntervalList[idx].IntersectsWith(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); } }
public FltDomain(FltDomain domain) { m_Interval = domain.m_Interval; m_IntervalList = domain.m_IntervalList; }
public FltDomain Intersect(FltDomain domain) { if (ReferenceEquals(domain, this)) { return(this); } if (domain.IsEmpty()) { return(m_Empty); } if (domain.IsSimple()) { return(Intersect(domain.m_Interval)); } // 1, 6 if (!IntersectsWith(domain)) { return(m_Empty); } // If the target is contained, then the result would be equal to the domain, hence we return the domain. if (IsSimple()) { if (domain.Contains(m_Interval)) { return(this); } if (m_Interval.Contains(domain.m_Interval)) { return(domain); } } // Need to be a bit smart, put our interval in a list, in case it gets chopped up. List <FltInterval> intervalList; if (IsSimple()) { intervalList = new List <FltInterval>(1); intervalList.Add(m_Interval); } else { intervalList = m_IntervalList; } FltDomain result = new FltDomain(); result.m_IntervalList = new List <FltInterval>(intervalList.Count + domain.m_IntervalList.Count); int idx = 0; int domIdx = 0; bool equal = true; while (idx < intervalList.Count || domIdx < domain.m_IntervalList.Count) { // 6 if (idx == intervalList.Count) { domIdx = domain.m_IntervalList.Count; } // 1 else if (domIdx == domain.m_IntervalList.Count) { idx = intervalList.Count; equal = false; } else { FltInterval intv = intervalList[idx]; FltInterval domIntv = domain.m_IntervalList[domIdx]; // 1 : completely before if (domIntv.Max < intv.Min) { ++domIdx; } // 6 : completely after else if (domIntv.Min > intv.Max) { ++idx; equal = false; } // 3 else if (domIntv.Contains(intv)) { result.m_IntervalList.Add(intv); ++idx; } // ~4 : divide into two intervals... else if (I4_Divide(intv, domIntv)) { result.m_IntervalList.Add(domIntv); ++domIdx; equal = false; } // 2 else if (I2_IntersectMin(intv, domIntv)) { result.m_IntervalList.Add(intv.Intersect(domIntv)); ++domIdx; equal = false; } // 5 else if (I5_IntersectMax(intv, domIntv)) { result.m_IntervalList.Add(intv.Intersect(domIntv)); ++idx; equal = false; } } } if (equal) { return(this); } result.UpdateInterval(); return(result); }
public SimpleIntervalEnumerator(FltDomain domain) { m_MoveNext = true; m_Domain = domain; }