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); } }
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); }
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?!"); } }
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); } } }