Пример #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);
            }
        }
Пример #2
0
        public IEnumerable <DCEL_Face> AdjacentFaces()
        {
            RBTreeSet <DCEL_Face> faceSet = new RBTreeSet <DCEL_Face>(DCEL_Element.Compare);

            foreach (DCEL_HalfEdge halfEdge in IncidentHalfEdges)
            {
                if (halfEdge.Twin.IncidentFace != this)
                {
                    faceSet.Add(new RBTreeSetNode <DCEL_Face>(halfEdge.Twin.IncidentFace));
                }
            }
            return(faceSet.Keys);
        }
Пример #3
0
        private void FindNewEventPoint(OA_Segment segment1, OA_Segment segment2, OA_EventPoint eventPoint)
        {
            VecRat2 pointIntersection   = new VecRat2();
            SegRat2 segmentIntersection = new SegRat2();

            SegmentIntersectionType result = GeomAid.SegmentIntersection(segment1.ToSegRat2(), segment2.ToSegRat2(), ref pointIntersection, ref segmentIntersection);

            if (result == SegmentIntersectionType.Point)
            {
                OA_EventPoint newEventPoint = new OA_EventPoint(pointIntersection);
                if (eventPoint.CompareTo(newEventPoint) < 0)
                {
                    //Add the new event point if it isn't already in the event queue
                    eventQueue.Add(new RBTreeSetNode <OA_EventPoint>(newEventPoint));
                }
            }
            else if (result == SegmentIntersectionType.Segment)
            {
                throw new NotImplementedException("Didn't think this would ever happen?!");
            }
        }
Пример #4
0
        private static void HandleEventPoint(EventPoint eventPoint, LinkedList <Segment> upperList,
                                             Sweepline sweepline, RBTreeMap <EventPoint, LinkedList <Segment> > eventQueue, RBTreeSet <Segment> status, out LineSegmentIntersection reportedIntersection)
        {
            reportedIntersection = null;

            sweepline.IncidentEventPoint = eventPoint;
            sweepline.BeforeEventPoint   = true;

            //1.
            //upperList brought in as part of the input. None of its elements currently intersect the sweepline!

            //2.
            IEnumerable <Segment> middleList, lowerList;

            status.FindRange(Segment.CompareSweeplineIntersectionToCurrentEventPoint).Select(node => node.Key)
            .Partition(Segment.LowerIsCurrentEventPoint, out lowerList, out middleList);

            //3.
            if (upperList.Count + middleList.Count() + lowerList.Count() > 1)
            {
                //4.
                reportedIntersection = new LineSegmentIntersection(
                    eventPoint.Position,
                    upperList.Concat(middleList).Concat(lowerList).Select(segment => segment.Source));
            }

            //5.
            foreach (var lower in lowerList)
            {
                status.Remove(lower);
            }
            foreach (var middle in middleList)
            {
                status.Remove(middle);
            }

            sweepline.BeforeEventPoint = false;

            //6.

            foreach (var middle in middleList)
            {
                status.Add(new RBTreeSetNode <Segment>(middle));
            }

            foreach (var upper in upperList)
            {
                status.Add(new RBTreeSetNode <Segment>(upper));
            }


            //7.
            //Just a comment in the book

            //8.
            if (upperList.IsEmpty() && middleList.IsEmpty())
            {
                //9.
                var predecessorNode = status.FindMax(Segment.IntersectsSweeplineLeftOfEventPoint);
                var successorNode   = status.FindMin(Segment.IntersectsSweeplineRightOfEventPoint);

                //10.
                if (predecessorNode != null && successorNode != null)
                {
                    FindNewEvent(predecessorNode.Key, successorNode.Key, eventPoint, eventQueue);
                }
            }
            else
            {
                //11.
                var leftmostIntersectingNode = status.FindMin(Segment.IntersectsSweeplineRightOfEventPoint);

                //14.
                var rightmostIntersectingNode = status.FindMax(Segment.IntersectsSweeplineLeftOfEventPoint);

                //12.
                var leftmostPredecessorNode = leftmostIntersectingNode.Predecessor;

                //15.
                var rightmostSuccessorNode = rightmostIntersectingNode.Successor;

                //13.
                if (leftmostPredecessorNode != null)
                {
                    //RemoveFutureEvent(leftmostPredecessor, rightmostIntersecting, eventPoint, eventQueue);
                    FindNewEvent(leftmostPredecessorNode.Key, leftmostIntersectingNode.Key, eventPoint, eventQueue);
                }

                //16.
                if (rightmostSuccessorNode != null)
                {
                    //RemoveFutureEvent(leftmostIntersecting, rightmostSuccessor, eventPoint, eventQueue);
                    FindNewEvent(rightmostIntersectingNode.Key, rightmostSuccessorNode.Key, eventPoint, eventQueue);
                }
            }
        }