Ejemplo n.º 1
0
 public EventPoint(DCEL_Vertex source)
 {
     Source = source;
     if (source != null)
     {
         Position = Source.Position;
     }
 }
Ejemplo n.º 2
0
        private void HandleIntersection_SplittingPhase(OA_EventPoint eventPoint, List <OA_Segment> upperList, List <OA_Segment> middleList, List <OA_Segment> lowerList)
        {
            //if (upperList.Count() + middleList.Count() + lowerList.Count() <= 1)
            if (middleList.Count == 0)
            {
                return;
            }

            //If there are any subdivisions which don't have a vertex at this location,
            //then we will create one momentarily. For the moment, set the
            //(key, value) = (subdivision, null).
            Dictionary <DCEL_Subdivision, DCEL_Vertex> vertexLookup = CreateSourceLookup(eventPoint);

            //Make all segments meet at a vertex here, within each subdivision.
            //HalfEdges associated with segments in the middleList will be transformed
            //into HalfEdges associated with segments in the upperList. (With the associated
            //segments transforming as well.)
            foreach (OA_Segment middle in middleList)
            {
                foreach (OA_Source <DCEL_HalfEdge> source in middle.Source)
                {
                    DCEL_Subdivision subdivision = source.Subdivision;
                    DCEL_HalfEdge    halfEdge    = source.Element;
                    DCEL_Vertex      vertex      = vertexLookup[subdivision];

                    //Create the vertex on-demand if it doesn't exist
                    if (vertex == null)
                    {
                        vertex = new DCEL_Vertex(eventPoint.Position);
                        vertexLookup[subdivision] = vertex;
                        subdivision.Vertices.Add(new RBTreeSetNode <DCEL_Vertex>(vertex));
                    }

                    SplitEdge(subdivision, halfEdge, vertex);

                    if (!eventPoint.Source.Any(OA_Source <DCEL_Vertex> .IsFrom(subdivision)))
                    {
                        eventPoint.Source.Add(new OA_Source <DCEL_Vertex>(subdivision, vertex));
                    }
                }
            }
        }
Ejemplo n.º 3
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));
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Create a subdivision from a single segment (u, v).
        /// </summary>
        public DCEL_Subdivision(VecRat2 u, VecRat2 v)
            : this()
        {
            if (u == v)
            {
                throw new Exception("Tried to create a DCELSubdivision with a segment of length 0.");
            }

            DCEL_Vertex   vertex_u    = new DCEL_Vertex(u);
            DCEL_Vertex   vertex_v    = new DCEL_Vertex(v);
            DCEL_HalfEdge halfedge_uv = new DCEL_HalfEdge();
            DCEL_HalfEdge halfedge_vu = new DCEL_HalfEdge();
            DCEL_Face     face        = new DCEL_Face();

            vertex_u.IncidentEdge = halfedge_uv;
            vertex_v.IncidentEdge = halfedge_vu;

            halfedge_uv.Origin       = vertex_u;
            halfedge_uv.Twin         = halfedge_vu;
            halfedge_uv.IncidentFace = face;
            halfedge_uv.Prev         = halfedge_vu;
            halfedge_uv.Next         = halfedge_vu;

            halfedge_vu.Origin       = vertex_v;
            halfedge_vu.Twin         = halfedge_uv;
            halfedge_vu.IncidentFace = face;
            halfedge_vu.Prev         = halfedge_uv;
            halfedge_vu.Next         = halfedge_uv;

            face.InnerComponents.AddLast(halfedge_uv);

            Vertices.Add(new RBTreeSetNode <DCEL_Vertex>(vertex_u));
            Vertices.Add(new RBTreeSetNode <DCEL_Vertex>(vertex_u));
            HalfEdges.Add(new RBTreeSetNode <DCEL_HalfEdge>(halfedge_uv));
            HalfEdges.Add(new RBTreeSetNode <DCEL_HalfEdge>(halfedge_vu));
            Faces.Add(new RBTreeSetNode <DCEL_Face>(face));

            UnboundedFace = face;
        }
Ejemplo n.º 5
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));
            }
        }
Ejemplo n.º 6
0
 public static void JoinIncidentEdge(DCEL_Vertex e_origin, DCEL_HalfEdge e)
 {
     e_origin.IncidentEdge = e;
     e.Origin = e_origin;
 }