Beispiel #1
0
        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);
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        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);
        }