Пример #1
0
        public void Flip(HalfEdge a_HalfEdge)
        {
            HalfEdge h1 = a_HalfEdge;
            HalfEdge h2 = h1.Next;
            HalfEdge h3 = h2.Next;
            HalfEdge h4 = a_HalfEdge.Twin;
            HalfEdge h5 = h4.Next;
            HalfEdge h6 = h5.Next;

            if (h1.Triangle == null || h4.Triangle == null)
            { return; }

            // Remove old triangles
            m_Triangles.Remove(a_HalfEdge.Triangle);
            m_Triangles.Remove(a_HalfEdge.Twin.Triangle);

            h1.Next = h6;
            h6.Prev = h1;
            h6.Next = h2;
            h2.Prev = h6;
            h2.Next = h1;
            h1.Prev = h2;
            h1.Origin = h3.Origin;

            h4.Next = h3;
            h3.Prev = h4;
            h3.Next = h5;
            h5.Prev = h3;
            h5.Next = h4;
            h4.Prev = h5;
            h4.Origin = h6.Origin;

            m_Triangles.Add(new Triangle(h1));
            m_Triangles.Add(new Triangle(h1.Twin));
        }
Пример #2
0
        public Triangle(HalfEdge a_HalfEdge)
        {
            m_Vertices = new Vertex[3];
            m_HalfEdge = a_HalfEdge;
            m_Color = Color.red;

            Vertex v1 = m_HalfEdge.Origin;
            Vertex v2 = m_HalfEdge.Next.Origin;
            Vertex v3 = m_HalfEdge.Next.Next.Origin;
            Vertex v4 = m_HalfEdge.Next.Next.Next.Origin;

            if (v1 == v2 || v2 == v3 || v1 == v3)
            { Debug.LogError("Triangle does not have a correct 3 vertex loop."); }

            if (v1 != v4)
            { Debug.LogError("Triangle does not have a correct 3 vertex loop."); }

            // Fix halfedges to this triangle
            m_HalfEdge.Triangle = this;
            m_HalfEdge.Next.Triangle = this;
            m_HalfEdge.Next.Next.Triangle = this;

            // Add vertices to the array
            m_Vertices[0] = v1;
            m_Vertices[1] = v2;
            m_Vertices[2] = v3;
        }
Пример #3
0
 public HalfEdge(Vertex a_Vertex)
 {
     // Using new here prevents reference equality. Is it really necessary to copy?
     m_Origin = new Vertex(a_Vertex.X, a_Vertex.Y, a_Vertex.Ownership);
     Triangle = null;
     Twin = null;
     Next = null;
     Prev = null;
 }
Пример #4
0
        protected void AddVertex(Triangle a_Triangle, Vertex a_Vertex)
        {
            m_Vertices.Add(a_Vertex);

            m_Triangles.Remove(a_Triangle);

            HalfEdge h1 = a_Triangle.HalfEdge;
            HalfEdge h2 = h1.Next;
            HalfEdge h3 = h2.Next;

            HalfEdge h4 = new HalfEdge(h1.Origin);
            HalfEdge h5 = new HalfEdge(h2.Origin);
            HalfEdge h6 = new HalfEdge(h3.Origin);
            HalfEdge h7 = new HalfEdge(a_Vertex);
            HalfEdge h8 = new HalfEdge(a_Vertex);
            HalfEdge h9 = new HalfEdge(a_Vertex);
            m_HalfEdges.AddRange(new List<HalfEdge>() { h4, h5, h6, h7, h8, h9 });

            h4.Twin = h7;
            h7.Twin = h4;
            h5.Twin = h8;
            h8.Twin = h5;
            h6.Twin = h9;
            h9.Twin = h6;

            // Set all next
            h1.Next = h5;
            h5.Prev = h1;
            h5.Next = h7;
            h7.Prev = h5;
            h7.Next = h1;
            h1.Prev = h7;

            h2.Next = h6;
            h6.Prev = h2;
            h6.Next = h8;
            h8.Prev = h6;
            h8.Next = h2;
            h2.Prev = h8;

            h3.Next = h4;
            h4.Prev = h3;
            h4.Next = h9;
            h9.Prev = h4;
            h9.Next = h3;
            h3.Prev = h9;

            m_Triangles.Add(new Triangle(h1));
            m_Triangles.Add(new Triangle(h2));
            m_Triangles.Add(new Triangle(h3));
        }
Пример #5
0
        private void LegalizeEdge(Vertex a_Vertex, HalfEdge a_HalfEdge, Triangle a_Triangle)
        {
            if (a_Vertex == null || a_HalfEdge == null || a_Triangle == null)
            {
                Debug.LogError("Invalid call to LegalizeEdge");
                return;
            }

            Vertex v1, v2, v3;
            try
            {
                // Points to test
                v1 = a_HalfEdge.Twin.Next.Next.Origin;
                v2 = a_HalfEdge.Next.Twin.Next.Next.Origin;
                v3 = a_HalfEdge.Next.Next.Twin.Next.Next.Origin;
            }
            catch (NullReferenceException)
            {
                Debug.LogError("Null pointers in call to LegalizeEdge");
                return;
            }

            if (v1 == null || v2 == null || v3 == null)
            {
                Debug.LogError("Invalid halfedge in call to LegalizeEdge");
                return;
            }

            if (a_Triangle.InsideCircumcenter(v1) || a_Triangle.InsideCircumcenter(v2) || a_Triangle.InsideCircumcenter(v3))
            {
                HalfEdge h1 = a_HalfEdge.Twin.Next.Twin;
                HalfEdge h2 = a_HalfEdge.Twin.Prev.Twin;

                Flip(a_HalfEdge);

                LegalizeEdge(a_Vertex, h1.Twin, h1.Twin.Triangle);
                LegalizeEdge(a_Vertex, h2.Twin, h2.Twin.Triangle);
            }
        }
Пример #6
0
    private static void ProcessHalfEdge(HalfEdge a_H1, Dictionary<Vertex, HashSet<Vertex>> a_VoronoiEdges,
										Dictionary<Vertex, HashSet<Vertex>> a_InternalEdges,
										Dictionary<Vertex, HashSet<Vertex>> a_VoronoiToInternalEdges)
    {
        if (a_H1.Twin == null)
        { return; }

        Triangle t1 = a_H1.Triangle;
        Triangle t2 = a_H1.Twin.Triangle;

        if (t1 != null && t2 != null)
        {
            Vertex voronoiVertex = t1.Circumcenter;
            Vertex voronoiVertex2 = t2.Circumcenter;
            HashSet<Vertex> existingVoronoiEdges;

            if (a_VoronoiEdges.TryGetValue(voronoiVertex, out existingVoronoiEdges))
            { existingVoronoiEdges.Add(voronoiVertex2); }
            else
            { a_VoronoiEdges.Add(voronoiVertex, new HashSet<Vertex>{voronoiVertex2}); }

            if (a_VoronoiEdges.TryGetValue (voronoiVertex2, out existingVoronoiEdges))
            { existingVoronoiEdges.Add(voronoiVertex); }
            else
            { a_VoronoiEdges.Add(voronoiVertex2, new HashSet<Vertex>{voronoiVertex}); }

            foreach (Vertex inputVertex in t1.Vertices)
            {
                HashSet<Vertex> existingValue;
                if (a_InternalEdges.TryGetValue(inputVertex, out existingValue))
                { existingValue.Add(voronoiVertex); }
                else
                { a_InternalEdges.Add(inputVertex, new HashSet<Vertex>{voronoiVertex}); }
            }
            HashSet<Vertex> inputVertices = new HashSet<Vertex>(t1.Vertices);
            HashSet<Vertex> existingInputVertices;
            if (a_VoronoiToInternalEdges.TryGetValue(voronoiVertex, out existingInputVertices))
            { existingInputVertices.UnionWith(inputVertices); }
            else
            { a_VoronoiToInternalEdges.Add(voronoiVertex, inputVertices); }
            // Yes, yes, code duplication is bad.
            foreach (Vertex inputVertex in t2.Vertices)
            {
                HashSet<Vertex> existingValue;
                if (a_InternalEdges.TryGetValue(inputVertex, out existingValue))
                { existingValue.Add(voronoiVertex2); }
                else
                { a_InternalEdges.Add(inputVertex, new HashSet<Vertex>{voronoiVertex2}); }
            }
            inputVertices = new HashSet<Vertex>(t2.Vertices);
            existingInputVertices = null;
            if (a_VoronoiToInternalEdges.TryGetValue(voronoiVertex2, out existingInputVertices))
            { existingInputVertices.UnionWith(inputVertices); }
            else
            { a_VoronoiToInternalEdges.Add(voronoiVertex2, inputVertices); }
        }
    }
Пример #7
0
        public void Create()
        {
            Vertex v1 = new Vertex(-500000, -500000);
            Vertex v2 = new Vertex(500000, 500000);
            Vertex v3 = new Vertex(-500000, 500000);
            Vertex v4 = new Vertex(500000, -500000);
            m_Vertices.AddRange(new List<Vertex>() { v1, v2, v3, v4 });

            HalfEdge h1 = new HalfEdge(v1);
            HalfEdge h2 = new HalfEdge(v2);
            HalfEdge h3 = new HalfEdge(v3);
            m_HalfEdges.AddRange(new List<HalfEdge>() { h1, h2, h3 });

            h1.Next = h2;
            h2.Next = h3;
            h3.Next = h1;

            h2.Prev = h1;
            h3.Prev = h2;
            h1.Prev = h3;

            HalfEdge h4 = new HalfEdge(v2);
            HalfEdge h5 = new HalfEdge(v1);
            HalfEdge h6 = new HalfEdge(v4);
            m_HalfEdges.AddRange(new List<HalfEdge>() { h4, h5, h6 });

            h4.Twin = h1;
            h1.Twin = h4;

            h4.Next = h5;
            h5.Next = h6;
            h6.Next = h4;

            h5.Prev = h4;
            h6.Prev = h5;
            h4.Prev = h6;

            HalfEdge h7 = new HalfEdge(v1);
            HalfEdge h8 = new HalfEdge(v2);
            HalfEdge h9 = new HalfEdge(v3);
            HalfEdge h10 = new HalfEdge(v4);
            m_HalfEdges.AddRange(new List<HalfEdge>() { h7, h8, h9, h10 });

            h10.Next = h7;
            h7.Prev = h10;
            h8.Next = h10;
            h10.Prev = h8;
            h9.Next = h8;
            h8.Prev = h9;
            h7.Next = h9;
            h9.Prev = h7;

            h3.Twin = h7;
            h7.Twin = h3;
            h8.Twin = h6;
            h6.Twin = h8;
            h2.Twin = h9;
            h9.Twin = h2;

            h10.Twin = h5;
            h5.Twin = h10;

            m_Triangles.Add(new Triangle(h1));
            m_Triangles.Add(new Triangle(h4));
        }
Пример #8
0
 /// <summary>
 ///     Deletes HalfEdge. This delete routine cannot reclaim the node, since
 ///     hash table pointers may still be present.
 /// </summary>
 /// <param name="he">node to delete</param>
 internal void Delete(HalfEdge he)
 {
     he.Left.Right = he.Right;
     he.Right.Left = he.Left;
     he.Edge       = null;
 }