Ejemplo n.º 1
0
        public OA_Sweepline()
        {
            IncidentEventPoint = null;
            BeforeEventPoint   = true;

            Status = new RBTreeSet <OA_Segment>(OA_Segment.Compare);
        }
Ejemplo n.º 2
0
 public DCEL_Subdivision()
 {
     ID            = NextID++;
     Vertices      = new RBTreeSet <DCEL_Vertex>(DCEL_Element.Compare);
     HalfEdges     = new RBTreeSet <DCEL_HalfEdge>(DCEL_Element.Compare);
     Faces         = new RBTreeSet <DCEL_Face>(DCEL_Element.Compare);
     UnboundedFace = new DCEL_Face();
 }
Ejemplo n.º 3
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);
            }
        }
Ejemplo n.º 4
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);
        }
Ejemplo n.º 5
0
        public static LinkedList <LineSegmentIntersection> FindIntersections(IEnumerable <DCEL_HalfEdge> lineSegments)
        {
            LinkedList <LineSegmentIntersection> result = new LinkedList <LineSegmentIntersection>();

            Sweepline sweepline = new Sweepline();
            RBTreeMap <EventPoint, LinkedList <Segment> > eventQueue = new RBTreeMap <EventPoint, LinkedList <Segment> >((x, y) => x.CompareTo(y));

            var segments = lineSegments.Where(lineSegment => lineSegment.Origin.Position != lineSegment.Destination.Position)
                           .Select(lineSegment => new Segment(lineSegment, sweepline));

            //segments = FixOverlappingSegments(segments);

            foreach (var segment in segments)
            {
                var node = eventQueue.Find(segment.Upper);
                LinkedList <Segment> upperList = (node != null ? node.Value : null);
                if (upperList == null)
                {
                    upperList = new LinkedList <Segment>();
                    eventQueue.Add(new RBTreeMapNode <EventPoint, LinkedList <Segment> >(new EventPoint(segment.Upper), upperList));
                }
                upperList.AddLast(segment);

                if (!eventQueue.ContainsKey(segment.Lower))
                {
                    eventQueue.Add(new RBTreeMapNode <EventPoint, LinkedList <Segment> >(new EventPoint(segment.Lower), new LinkedList <Segment>()));
                }
            }

            RBTreeSet <Segment> status = new RBTreeSet <Segment>((x, y) => x.CompareTo(y));

            while (eventQueue.Count > 0)
            {
                var pair = eventQueue.MinNode;
                eventQueue.RemoveMin();

                EventPoint           nextEventPoint = pair.Key;
                LinkedList <Segment> upperList      = pair.Value;

                LineSegmentIntersection reportedIntersection;
                HandleEventPoint(nextEventPoint, upperList, sweepline, eventQueue, status, out reportedIntersection);
                if (reportedIntersection != null)
                {
                    result.AddLast(reportedIntersection);
                }
            }

            return(result);
        }
Ejemplo n.º 6
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);
                }
            }
        }