Example #1
0
        /// <summary>
        /// halfEdge should be Upper->Lower so that the persistent half edges become:
        ///  o halfEdge         (Upper->Lower) ==> (vertex->Lower)
        ///  o halfEdge.Twin    (Lower->Upper) ==> (Lower->vertex)
        /// And the two newly created half edges are (vertex->Upper) and (Upper->vertex).
        /// </summary>
        private static void SplitEdge(DCEL_Subdivision subdivision, DCEL_HalfEdge halfEdge, DCEL_Vertex vertex)
        {
            Debug.Assert(VecRat2.CompareReadingOrder(halfEdge.Origin.Position, halfEdge.Destination.Position) < 0);

            DCEL_HalfEdge e1 = halfEdge;
            DCEL_HalfEdge e2 = e1.Twin;

            DCEL_HalfEdge e1_prev = e1.Prev;
            DCEL_HalfEdge e2_next = e2.Next;

            DCEL_Vertex e1_origin = e1.Origin;

            DCEL_HalfEdge e1_top = new DCEL_HalfEdge();
            DCEL_HalfEdge e2_top = new DCEL_HalfEdge();

            DCEL_Helper.JoinTwin(e1_top, e2_top);
            e1_top.IncidentFace = e1.IncidentFace;
            e2_top.IncidentFace = e2.IncidentFace;

            DCEL_Helper.JoinIncidentEdge(vertex, e2_top);
            DCEL_Helper.JoinIncidentEdge(vertex, e1);
            DCEL_Helper.JoinIncidentEdge(e1_origin, e1_top);

            if (e2_next == e1)
            {
                DCEL_Helper.JoinNext(e2, e2_top);
                DCEL_Helper.JoinNext(e2_top, e1_top);
                DCEL_Helper.JoinNext(e1_top, e1);
            }
            else
            {
                DCEL_Helper.JoinPrevNext(e2, e2_top, e2_next);
                DCEL_Helper.JoinPrevNext(e1_prev, e1_top, e1);
            }

            if (subdivision != null)
            {
                subdivision.HalfEdges.Add(new RBTreeSetNode <DCEL_HalfEdge>(e1_top));
                subdivision.HalfEdges.Add(new RBTreeSetNode <DCEL_HalfEdge>(e2_top));
            }
        }
Example #2
0
        private void HandleIntersection_MergingPhase(OA_EventPoint eventPoint, List <OA_Segment> upperList, List <OA_Segment> middleList, List <OA_Segment> lowerList)
        {
            if (middleList.Count != 0)
            {
                throw new Exception("MergingPhase: Something went wrong in the SplittingPhase, because there is an intersection with nonempty middleList.");
            }

            //Dictionary<DCEL_Subdivision, DCEL_Vertex> vertexLookup = CreateSourceLookup(eventPoint);
            //DCEL_Vertex mergedVertex = vertexLookup.Values.First();

            DCEL_Vertex mergedVertex = eventPoint.Source.First().Element;

            lowerList.Sort(AngleComparisonLowerList(mergedVertex.Position));
            upperList.Sort(AngleComparisonUpperList(mergedVertex.Position));

            //JoinNext all consecutive pairs around circle, and join origins to mergedVertex
            {
                //Outgoing half edges in CCW order
                List <DCEL_HalfEdge> bothList = new List <DCEL_HalfEdge>();
                bothList.AddRange(lowerList.Select(segment => segment.Source.First().Element.Twin));
                bothList.AddRange(upperList.Select(segment => segment.Source.First().Element));

                if (bothList.Count > 1)
                {
                    DCEL_HalfEdge e, e_next;
                    for (int i = 1; i < bothList.Count; i++)
                    {
                        e      = bothList[i].Twin;
                        e_next = bothList[i - 1];
                        DCEL_Helper.JoinNext(e, e_next);
                    }

                    e      = bothList.First().Twin;
                    e_next = bothList.Last();
                    DCEL_Helper.JoinNext(e, e_next);
                }
                else
                {
                    DCEL_HalfEdge e      = bothList[0].Twin;
                    DCEL_HalfEdge e_next = e.Twin;
                    DCEL_Helper.JoinNext(e, e_next);
                }

                //Set the origins to the mergedVertex
                foreach (DCEL_HalfEdge e in bothList)
                {
                    e.Origin = mergedVertex;
                }
                mergedVertex.IncidentEdge = bothList.First();
            }

            outputSubdivision.Vertices.Add(new RBTreeSetNode <DCEL_Vertex>(mergedVertex));

            foreach (OA_Segment upper in upperList)
            {
                DCEL_HalfEdge e = upper.Source.First().Element;
                outputSubdivision.HalfEdges.Add(new RBTreeSetNode <DCEL_HalfEdge>(e));
                outputSubdivision.HalfEdges.Add(new RBTreeSetNode <DCEL_HalfEdge>(e.Twin));

                //HACK?/////////////////////////////////////////
                e.IncidentFace      = null;
                e.Twin.IncidentFace = null;
                //HACK?/////////////////////////////////////////
            }

            //Store the left pick for the mergedVertex
            if (eventPoint.LeftPick != null)
            {
                leftPicksMap.Add(new RBTreeMapNode <DCEL_Vertex, DCEL_HalfEdge>(mergedVertex, eventPoint.LeftPick.Source.First().Element));
            }
            else
            {
                leftPicksMap.Add(new RBTreeMapNode <DCEL_Vertex, DCEL_HalfEdge>(mergedVertex, null));
            }
        }