Exemplo n.º 1
0
        private void Initialize()
        {
            sweepline         = new OA_Sweepline();
            eventQueue        = new RBTreeSet <OA_EventPoint>(OA_EventPoint.Compare);
            outputSubdivision = new DCEL_Subdivision();

            foreach (DCEL_Subdivision inputSubdivision in inputSubdivisions)
            {
                foreach (DCEL_HalfEdge inputHalfEdge in inputSubdivision.HalfEdges.Keys)
                {
                    OA_EventPoint upper = new OA_EventPoint(inputHalfEdge.Origin.Position);
                    OA_EventPoint lower = new OA_EventPoint(inputHalfEdge.Destination.Position);

                    //We want to take only one of the twins from every pair of half edges.
                    if (upper.CompareTo(lower) > 0)
                    {
                        continue;
                    }

                    RBTreeSetNode <OA_EventPoint> upper_node = new RBTreeSetNode <OA_EventPoint>(upper);
                    RBTreeSetNode <OA_EventPoint> lower_node = new RBTreeSetNode <OA_EventPoint>(lower);

                    //If we didn't add the newly created event point, it already existed.
                    if (!eventQueue.Add(ref upper_node))
                    {
                        upper = upper_node.Key;
                    }
                    if (!eventQueue.Add(ref lower_node))
                    {
                        lower = lower_node.Key;
                    }

                    OA_Segment segment = new OA_Segment(sweepline);
                    segment.Source.Add(new OA_Source <DCEL_HalfEdge>(inputSubdivision, inputHalfEdge));
                    segment.Upper = upper;
                    segment.Lower = lower;
                    //***May be adding a duplicate if segment is in both subdivisions!
                    upper.UpperList.Add(segment);

                    if (!upper.Source.Any(OA_Source <DCEL_Vertex> .IsFrom(inputSubdivision)))
                    {
                        upper.Source.Add(new OA_Source <DCEL_Vertex>(inputSubdivision, inputHalfEdge.Origin));
                    }

                    if (!lower.Source.Any(OA_Source <DCEL_Vertex> .IsFrom(inputSubdivision)))
                    {
                        lower.Source.Add(new OA_Source <DCEL_Vertex>(inputSubdivision, inputHalfEdge.Destination));
                    }
                }
            }

            foreach (OA_EventPoint eventPoint in eventQueue.Keys)
            {
                //***Remove those duplicates here, joining their source lists.
                eventPoint.UpperList.RemoveDuplicates(OA_Segment.CompareEndpoints, OA_Segment.JoinSource);
            }
        }
Exemplo n.º 2
0
        private void SetLeftPick(OA_EventPoint eventPoint)
        {
            RBTreeSetNode <OA_Segment> leftPick_node = sweepline.Status.FindMax(OA_Segment.IntersectsSweeplineLeftOfEventPointExclusive);

            if (leftPick_node != null)
            {
                eventPoint.LeftPick = leftPick_node.Key;
            }
            else
            {
                eventPoint.LeftPick = null;
            }
        }
Exemplo n.º 3
0
        private void HandleEventPoint(OA_EventPoint eventPoint)
        {
            AssertValidSweeplineStatus();

            //Sweep to before the event point
            sweepline.IncidentEventPoint = eventPoint;
            sweepline.BeforeEventPoint   = true;

            AssertValidSweeplineStatus();

            if (phase == Phase.MergingPhase)
            {
                SetLeftPick(eventPoint);
            }

            //Determine all segments that contain the event point, and partition them
            List <OA_Segment> upperList = eventPoint.UpperList;
            List <OA_Segment> middleList;
            List <OA_Segment> lowerList;

            sweepline.Status
            .FindRange(OA_Segment.CompareSweeplineIntersectionToCurrentEventPoint).Select(node => node.Key)
            .Partition(OA_Segment.LowerIsCurrentEventPoint, out lowerList, out middleList);

            //upperList gets added, middleList gets reversed, lowerList gets removed
            EventPointTransition(upperList, middleList, lowerList);

            AssertValidSweeplineStatus();

            switch (phase)
            {
            case Phase.SplittingPhase:
                HandleIntersection_SplittingPhase(eventPoint, upperList, middleList, lowerList);
                break;

            case Phase.MergingPhase:
                HandleIntersection_MergingPhase(eventPoint, upperList, middleList, lowerList);
                break;

            default:
                throw new Exception();
            }

            AssertValidSweeplineStatus();

            if (upperList.IsEmpty() && middleList.IsEmpty())
            {
                RBTreeSetNode <OA_Segment> predecessorNode = sweepline.Status.FindMax(OA_Segment.IntersectsSweeplineLeftOfEventPointInclusive);
                RBTreeSetNode <OA_Segment> successorNode   = sweepline.Status.FindMin(OA_Segment.IntersectsSweeplineRightOfEventPointInclusive);
                if (predecessorNode != null && successorNode != null)
                {
                    FindNewEventPoint(predecessorNode.Key, successorNode.Key, eventPoint);
                }
            }
            else
            {
                var leftmostIntersectingNode = sweepline.Status.FindMin(OA_Segment.IntersectsSweeplineRightOfEventPointInclusive);
                var leftmostPredecessorNode  = leftmostIntersectingNode.Predecessor;
                if (leftmostPredecessorNode != null)
                {
                    FindNewEventPoint(leftmostPredecessorNode.Key, leftmostIntersectingNode.Key, eventPoint);
                }

                var rightmostIntersectingNode = sweepline.Status.FindMax(OA_Segment.IntersectsSweeplineLeftOfEventPointInclusive);
                var rightmostSuccessorNode    = rightmostIntersectingNode.Successor;
                if (rightmostSuccessorNode != null)
                {
                    FindNewEventPoint(rightmostIntersectingNode.Key, rightmostSuccessorNode.Key, eventPoint);
                }
            }
        }