Ejemplo n.º 1
0
        private static int MakeNewEqTree(BundleTree tree, IList <Segment> slist, int sIdx, Segment[] contS, ISpatiallyComparable sweepEvent)
        {
            // TODO: Refactor this horrible method!
            Bundle currB = null;
            int    nc    = 0;
            int    ic    = 0;

            while (nc < 2 && contS[nc] != null)
            {
                ++nc;
            }

            int iss = sIdx;

            while (sIdx < slist.Count && slist[sIdx].CompareTo(sweepEvent) <= 0)
            {
                ++sIdx;
            }

            if (ic >= nc && iss >= sIdx)
            {
                return(sIdx);
            }

            Segment currS = ic < nc && (iss >= sIdx || contS[ic].CompareTo(slist[iss]) <= 0) ? contS[ic++] : slist[iss++];

            bool currBIsRed = currS.IsRed ^ true;

            do
            {
                if (currBIsRed == currS.IsRed)
                {
                    Debug.Assert(currB != null);
                    currB.insertSegAtTop(currS);
                }
                else
                {
                    currBIsRed = currS.IsRed;
                    currB      = new Bundle(currBIsRed, null, currB, currS);
                    tree.InsertBAtTop(currB);
                }
                currS.useStart = false;
                if (ic < nc || iss < sIdx)
                {
                    if (ic < nc && (iss >= sIdx || contS[ic].CompareTo(slist[iss]) <= 0))
                    {
                        currS = contS[ic++];
                    }
                    else
                    {
                        currS = slist[iss++];
                    }
                }
                else
                {
                    return(sIdx);
                }
            }while(true);
        }
Ejemplo n.º 2
0
        public void Merge(BundleTree rhs, bool mergeUp)
        {
            if (rhs == null)
            {
                return;
            }
            if (rhs.IsEmpty)
            {
                return;
            }

            if (IsEmpty)
            {
                bTree  = rhs.bTree;
                top    = rhs.top;
                bottom = rhs.bottom;
            }
            else if (mergeUp)
            {
                if (top.IsRed)
                {
                    bTree.Merge(top, rhs.bTree);
                }
                else
                {
                    bTree.Merge(top.PurpleDown, rhs.bTree);
                }
                top.PurpleUp          = rhs.bottom;
                rhs.bottom.PurpleDown = top;
                if (top.IsRed == rhs.bottom.IsRed)
                {
                    GroupBundles(top, true);
                }
                top = rhs.top;
            }
            else
            {
                if (rhs.top.IsRed)
                {
                    rhs.bTree.Merge(rhs.top, bTree);
                }
                else
                {
                    rhs.bTree.Merge(rhs.top.PurpleDown, bTree);
                }
                bTree             = rhs.bTree;
                rhs.top.PurpleUp  = bottom;
                bottom.PurpleDown = rhs.top;
                if (rhs.top.IsRed == bottom.IsRed)
                {
                    GroupBundles(rhs.top, true);
                }
                bottom = rhs.bottom;
            }
        }
Ejemplo n.º 3
0
 private static void SwapMerge(Bundle lower, Bundle upper, BundleTree rBundleTree)
 {
     lower.RemovePurpleL();
     RecordIntersections(lower, upper);
     lower.AddAbovePurpleL(upper);
     if (lower.IsRed == lower.PurpleUp.IsRed)
     {
         rBundleTree.GroupBundles(lower, true);
     }
     if (upper.IsRed == upper.PurpleDown.IsRed)
     {
         rBundleTree.GroupBundles(upper, false);
     }
 }
Ejemplo n.º 4
0
        private static void FindContSegs(BundleTree oldEqTree, Segment[] contSegs, FPoint sweepEvent)
        {
            int i = 0;

            contSegs[0] = null;
            contSegs[1] = null;
            for (Bundle bptr = oldEqTree.Top; bptr != null; bptr = bptr.PurpleDown)
            {
                for (Segment sptr = bptr.Top; sptr != null; sptr = sptr.Down)
                {
                    if (sptr.EndsAfter(sweepEvent))
                    {
                        contSegs[i++] = sptr.BreakSeg(sweepEvent);
                    }
                }
            }
        }
Ejemplo n.º 5
0
        private BundleTree InitSentinels()
        {
            BundleTree rBundleTree = new BundleTree();
            double     lx          = (redMinMax[0] >= blueMinMax[0] ? blueMinMax[0] : redMinMax[0]) - 1.0D;
            double     ly          = (redMinMax[2] >= blueMinMax[2] ? blueMinMax[2] : redMinMax[2]) - 1.0D;
            double     ux          = (redMinMax[1] <= blueMinMax[1] ? blueMinMax[1] : redMinMax[1]) + 1.0D;
            double     uy          = (redMinMax[3] <= blueMinMax[3] ? blueMinMax[3] : redMinMax[3]) + 1.0D;

            Segment[] boundary =
            {
                new Segment(new FPoint(lx, ly - 1.0D), new FPoint(ux, ly - 1.0D), true),
                new Segment(new FPoint(lx, ly),        new FPoint(ux, ly),        false),
                new Segment(new FPoint(lx, uy),        new FPoint(ux, uy),        false),
                new Segment(new FPoint(lx, uy + 1.0D), new FPoint(ux, uy + 1.0D), true)
            };

            MakeNewEqTree(rBundleTree, boundary, 0, new Segment[1], new FPoint(ux + 1.0D, uy + 1.0D));
            return(rBundleTree);
        }
Ejemplo n.º 6
0
        private static void RecordEndIntersections(BundleTree oldEqTree, BundleTree newEqTree)
        {
            int      intCount = -1;
            SingleLL intptr   = null;
            Segment  prev     = null;

            for (Bundle bptr = oldEqTree.Top; bptr != null; bptr = bptr.PurpleDown)
            {
                for (Segment sptr = bptr.Top; sptr != null; sptr = sptr.Down)
                {
                    intCount++;
                    if (intptr == null)
                    {
                        intptr      = new SingleLL(sptr, null);
                        intptr.next = intptr;
                    }
                    else
                    {
                        intptr.next = new SingleLL(sptr, intptr.next);
                        intptr      = intptr.next;
                    }
                }
            }

            for (Bundle bptr = newEqTree.Bottom; bptr != null; bptr = bptr.PurpleUp)
            {
                for (Segment sptr = bptr.Bottom; sptr != null; sptr = sptr.Up)
                {
                    intCount++;
                    if (intptr == null)
                    {
                        intptr      = new SingleLL(sptr, null);
                        intptr.next = intptr;
                    }
                    else
                    {
                        intptr.next = new SingleLL(sptr, intptr.next);
                        intptr      = intptr.next;
                    }
                }
            }

            if (intCount <= 0)
            {
                return;
            }
            Debug.Assert(intptr != null);
            intptr = intptr.next;
            for (Bundle bptr = oldEqTree.Top; bptr != null; bptr = bptr.PurpleDown)
            {
                for (Segment sptr = bptr.Top; sptr != null; sptr = sptr.Down)
                {
                    sptr.AddEndIntersections(intptr, intCount);
                    if (prev != null && prev.IsSameSeg(sptr))
                    {
                        prev.AddLIntersection(sptr);
                        sptr.AddLIntersection(prev);
                    }
                    intptr = intptr.next;
                    prev   = sptr;
                }
            }

            for (Bundle bptr = newEqTree.Bottom; bptr != null; bptr = bptr.PurpleUp)
            {
                for (Segment sptr = bptr.Bottom; sptr != null; sptr = sptr.Up)
                {
                    sptr.AddStartIntersections(intptr, intCount);
                    intptr = intptr.next;
                }
            }
        }
Ejemplo n.º 7
0
        private void CalcIntersections()
        {
            Debug.Assert(mergedSegments != null);
            Segment[] contSegs = new Segment[2];
            ClearIntersections();
            IEnumerable <FPoint> eventList   = CreateEventList(mergedSegments);
            BundleTree           rBundleTree = InitSentinels();
            int imerge = 0;

            foreach (FPoint sweepEvent in eventList)
            {
                Bundle bClose  = rBundleTree.FindSmBAbove(sweepEvent);
                Bundle bRedTeq = bClose.PurpleDown.PurpleDown;
                if (bRedTeq.PurpleDown != null)
                {
                    for (bRedTeq = rBundleTree.separateEq(bRedTeq, sweepEvent, true, false); Witnessed(bRedTeq.PurpleDown, bRedTeq, sweepEvent); SwapMerge(bRedTeq.PurpleDown, bRedTeq, rBundleTree))
                    {
                    }
                    rBundleTree.separateEq(bRedTeq.PurpleDown, sweepEvent, true, true);
                    if (Witnessed(bRedTeq.PurpleDown, bRedTeq, sweepEvent))
                    {
                        SwapMerge(bRedTeq.PurpleDown, bRedTeq, rBundleTree);
                    }
                    if (bRedTeq.PurpleUp.IsRed)
                    {
                        bClose = bRedTeq.PurpleUp;
                    }
                    if (bClose.PurpleUp != null)
                    {
                        for (; Witnessed(bClose, bClose.PurpleUp, sweepEvent); SwapMerge(bClose, bClose.PurpleUp, rBundleTree))
                        {
                        }
                        rBundleTree.separateEq(bClose.PurpleUp, sweepEvent, true, false);
                        if (Witnessed(bClose, bClose.PurpleUp, sweepEvent))
                        {
                            SwapMerge(bClose, bClose.PurpleUp, rBundleTree);
                        }
                    }
                    if (bRedTeq.PurpleUp.IsRed)
                    {
                        rBundleTree.GroupBundles(bRedTeq, true);
                    }
                    for (bRedTeq = rBundleTree.separateEq(bRedTeq, sweepEvent, false, false); Witnessed(bRedTeq.PurpleDown, bRedTeq, sweepEvent); SwapMerge(bRedTeq.PurpleDown, bRedTeq, rBundleTree))
                    {
                    }
                    rBundleTree.separateEq(bRedTeq.PurpleDown, sweepEvent, false, true);
                    if (Witnessed(bRedTeq.PurpleDown, bRedTeq, sweepEvent))
                    {
                        SwapMerge(bRedTeq.PurpleDown, bRedTeq, rBundleTree);
                    }
                    if (bRedTeq.PurpleUp.IsRed)
                    {
                        rBundleTree.GroupBundles(bRedTeq, true);
                    }
                }
                bClose = rBundleTree.FindLgBBelow(sweepEvent);
                Bundle bRedBeq = bClose.PurpleUp.PurpleUp;
                if (bRedBeq.PurpleUp != null)
                {
                    for (bRedBeq = rBundleTree.separateEq(bRedBeq, sweepEvent, false, true); Witnessed(bRedBeq, bRedBeq.PurpleUp, sweepEvent); SwapMerge(bRedBeq, bRedBeq.PurpleUp, rBundleTree))
                    {
                    }
                    rBundleTree.separateEq(bRedBeq.PurpleUp, sweepEvent, false, false);
                    if (Witnessed(bRedBeq, bRedBeq.PurpleUp, sweepEvent))
                    {
                        SwapMerge(bRedBeq, bRedBeq.PurpleUp, rBundleTree);
                    }
                    if (bRedBeq.PurpleDown.IsRed)
                    {
                        bClose = bRedBeq.PurpleDown;
                    }
                    if (bClose.PurpleDown != null)
                    {
                        for (; Witnessed(bClose.PurpleDown, bClose, sweepEvent); SwapMerge(bClose.PurpleDown, bClose, rBundleTree))
                        {
                        }
                        rBundleTree.separateEq(bClose.PurpleDown, sweepEvent, false, true);
                        if (Witnessed(bClose.PurpleDown, bClose, sweepEvent))
                        {
                            SwapMerge(bClose.PurpleDown, bClose, rBundleTree);
                        }
                    }
                    if (bRedBeq.PurpleDown.IsRed)
                    {
                        rBundleTree.GroupBundles(bRedBeq, false);
                    }
                    for (bRedBeq = rBundleTree.separateEq(bRedBeq, sweepEvent, true, true); Witnessed(bRedBeq, bRedBeq.PurpleUp, sweepEvent); SwapMerge(bRedBeq, bRedBeq.PurpleUp, rBundleTree))
                    {
                    }
                    rBundleTree.separateEq(bRedBeq.PurpleUp, sweepEvent, true, false);
                    if (Witnessed(bRedBeq, bRedBeq.PurpleUp, sweepEvent))
                    {
                        SwapMerge(bRedBeq, bRedBeq.PurpleUp, rBundleTree);
                    }
                    if (bRedBeq.PurpleDown.IsRed)
                    {
                        rBundleTree.GroupBundles(bRedBeq, false);
                    }
                }
                BundleTree plusTree  = rBundleTree.Split(sweepEvent, true);
                BundleTree minusTree = rBundleTree;
                BundleTree oldEqTree = minusTree.Split(sweepEvent, false);
                FindContSegs(oldEqTree, contSegs, sweepEvent);
                rBundleTree = new BundleTree();
                imerge      = MakeNewEqTree(rBundleTree, mergedSegments, imerge, contSegs, sweepEvent);
                RecordEndIntersections(oldEqTree, rBundleTree);
                rBundleTree.Merge(plusTree, true);
                rBundleTree.Merge(minusTree, false);
            }
        }
Ejemplo n.º 8
0
        public BundleTree Split(ISpatiallyComparable splitPos, bool keep)
        {
            BundleTree upperPart = null;
            Segment    splitSeg;
            Bundle     splitB;

            if (keep)
            {
                splitB = FindSmBAbove(splitPos);
                if (splitB.PurpleDown != null && splitB.PurpleDown.CompareTo(splitPos) > 0)
                {
                    splitB = splitB.PurpleDown;
                }

                if (splitB.PurpleDown != null)
                {
                    splitB = splitB.PurpleDown;
                    bool found = splitB.TryFindSmallestSegmentAbove(splitPos, out splitSeg);
                    Debug.Assert(found == (splitSeg != null));
                }
                else
                {
                    upperPart = new BundleTree(bTree, top, bottom);
                    bTree     = null;
                    top       = bottom = null;
                    return(upperPart);
                }
            }
            else
            {
                splitB = FindLgBBelow(splitPos);
                if (splitB.PurpleUp != null && splitB.PurpleUp.CompareTo(splitPos) < 0)
                {
                    splitB = splitB.PurpleUp;
                }

                if (splitB.PurpleUp != null)
                {
                    bool found = splitB.PurpleUp.TryFindLargestSegmentBelow(splitPos, out splitSeg);
                    if (found)
                    {
                        splitB = splitB.PurpleUp;
                    }
                }
                else
                {
                    return(new BundleTree());
                }
            }

            if (splitSeg != null)
            {
                splitB.Split(splitSeg, keep ^ true);
                PlainInsert(splitB.PurpleUp);
            }
            SplayTree <ISpatiallyComparable> s = splitB.IsRed ? bTree.SplitAt(splitB, true) : bTree.SplitAt(splitB.PurpleDown, true);

            upperPart    = new BundleTree(s, top, splitB.PurpleUp);
            top          = splitB;
            top.PurpleUp = upperPart.bottom.PurpleDown = null;
            return(upperPart);
        }