public EuclideanGraphTriangle <T>[] Subdivide(EuclideanGraphNode <T> point)
 {
     return(new EuclideanGraphTriangle <T>[]
     {
         new EuclideanGraphTriangle <T>(point, Corners[0], Corners[1]),
         new EuclideanGraphTriangle <T>(point, Corners[1], Corners[2]),
         new EuclideanGraphTriangle <T>(point, Corners[2], Corners[0])
     });
 }
Exemplo n.º 2
0
 private void AddEdge(EuclideanGraphNode <T> node1, EuclideanGraphNode <T> node2)
 {
     if (!ContainsEdge(node1, node2))
     {
         EuclideanGraphEdge <T> newEdge = new EuclideanGraphEdge <T>(node1, node2);
         Edges.Add(newEdge);
         node1.Edges.Add(newEdge);
         node2.Edges.Add(newEdge);
     }
 }
Exemplo n.º 3
0
 private bool ContainsEdge(EuclideanGraphNode <T> node1, EuclideanGraphNode <T> node2)
 {
     foreach (EuclideanGraphEdge <T> edge in Edges)
     {
         if ((edge.Nodes[0] == node1 && edge.Nodes[1] == node2) ||
             (edge.Nodes[0] == node2 && edge.Nodes[1] == node1))
         {
             return(true);
         }
     }
     return(false);
 }
        public EuclideanGraphNode <T> GetOppositeCorner(EuclideanGraphNode <T>[] edge)
        {
            EuclideanGraphNode <T> opposite = null;

            foreach (EuclideanGraphNode <T> corner in Corners)
            {
                if (edge[0] != corner && edge[1] != corner)
                {
                    opposite = corner;
                }
            }
            return(opposite);
        }
Exemplo n.º 5
0
        /// <summary>
        /// Attempt to generate the Delaunay triangulation for this graph.
        /// Returns null on success. Otherwise returns the node which could not
        /// be traingulated.
        /// </summary>
        /// <returns></returns>
        private EuclideanGraphNode <T> AttemptDelaunayTriangulation()
        {
            // Create convex hull which spans the data
            EuclideanGraphNode <T> anchor1 = new EuclideanGraphNode <T>(new Vector2(0f, 2f * Radius));
            EuclideanGraphNode <T> anchor2 = new EuclideanGraphNode <T>(new Vector2(Mathf.Sqrt(3f) * Radius, -Radius));
            EuclideanGraphNode <T> anchor3 = new EuclideanGraphNode <T>(new Vector2(-Mathf.Sqrt(3f) * Radius, -Radius));

            DelaunayTree.DelaunayTree <T> tree = new DelaunayTree.DelaunayTree <T>(new EuclideanGraphTriangle <T>(anchor1, anchor2, anchor3));

            int nodesInserted = 0;

            // Insert one node at a time, always updating the delaunay triangulation
            foreach (EuclideanGraphNode <T> node in Nodes)
            {
                ProgressTracker.Instance.PushActivity("Inserting node " + (nodesInserted++).ToString() + "/" + Nodes.Count.ToString());
                EuclideanGraphTriangle <T> entryTriangle = tree.GetTriangle(node.GetPosition());
                if (entryTriangle == null)
                {
                    ProgressTracker.Instance.PopActivity();
                    return(node);
                }
                EuclideanGraphTriangle <T>[] subdivisions = entryTriangle.Subdivide(node);
                tree.Subdivide(entryTriangle, subdivisions);

                Queue <EuclideanGraphNode <T>[]> edgesToVerify = entryTriangle.GetEdges();
                while (edgesToVerify.Count > 0)
                {
                    VerifyNextEdge(tree, edgesToVerify);
                }
                ProgressTracker.Instance.PopActivity();
            }

            ProgressTracker.Instance.PushActivity("Gathering edges");
            // Transfer to edge data structure
            List <EuclideanGraphTriangle <T> > triangles = tree.GetCurrentTriangles();

            foreach (EuclideanGraphTriangle <T> triangle in triangles)
            {
                Queue <EuclideanGraphNode <T>[]> edges = triangle.GetEdges();
                foreach (EuclideanGraphNode <T>[] edge in edges)
                {
                    if (edge[0].HasData && edge[1].HasData)
                    {
                        AddEdge(edge[0], edge[1]);
                    }
                }
            }
            ProgressTracker.Instance.PopActivity();
            return(null);
        }
        public EuclideanGraphNode <T>[][] GetOtherEdges(EuclideanGraphNode <T>[] edge)
        {
            EuclideanGraphNode <T> opposite = GetOppositeCorner(edge);

            EuclideanGraphNode <T>[][] otherEdges = new EuclideanGraphNode <T> [2][];
            otherEdges[0] = new EuclideanGraphNode <T>[]
            {
                opposite,
                edge[0]
            };
            otherEdges[1] = new EuclideanGraphNode <T>[]
            {
                opposite,
                edge[1]
            };
            return(otherEdges);
        }
Exemplo n.º 7
0
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        public void GenerateDelaunayTriangulation()
        {
            ProgressTracker.Instance.PushActivity("Triangulating");

            EuclideanGraphNode <T> node = AttemptDelaunayTriangulation();
            int attempt = 2;

            while (node != null)
            {
                ProgressTracker.Instance.PushActivity("Attempt " + attempt++);
                Nodes.Remove(node);
                Nodes.AddFirst(node);
                node = AttemptDelaunayTriangulation();
                ProgressTracker.Instance.PopActivity();
            }

            ProgressTracker.Instance.PopActivity();
        }
Exemplo n.º 8
0
        private void VerifyNextEdge(DelaunayTree.DelaunayTree <T> delaunayTree, Queue <EuclideanGraphNode <T>[]> edgesToVerify)
        {
            EuclideanGraphNode <T>[] edge = edgesToVerify.Dequeue();

            EuclideanGraphTriangle <T> triangle1 = null;
            EuclideanGraphTriangle <T> triangle2 = null;

            delaunayTree.GetTrianglesOnEdge(edge, ref triangle1, ref triangle2);

            //There is only one triangle on an edge between anchor points (which cannot be flipped)
            if (triangle2 == null)
            {
                return;
            }

            float alpha = triangle1.GetOppositeAngle(edge);
            float beta  = triangle2.GetOppositeAngle(edge);

            // If the sum of opposite angles is > 180 we need to flip
            if (alpha + beta > 180f)
            {
                // Enqueue other edges which may need to be flipped as a result of this flip
                EuclideanGraphNode <T>[][] otherEdges = triangle1.GetOtherEdges(edge);
                edgesToVerify.Enqueue(otherEdges[0]);
                edgesToVerify.Enqueue(otherEdges[1]);
                otherEdges = triangle2.GetOtherEdges(edge);
                edgesToVerify.Enqueue(otherEdges[0]);
                edgesToVerify.Enqueue(otherEdges[1]);

                // Create two new triangles
                EuclideanGraphNode <T>     corner1      = triangle1.GetOppositeCorner(edge);
                EuclideanGraphNode <T>     corner2      = triangle2.GetOppositeCorner(edge);
                EuclideanGraphTriangle <T> newTriangle1 = new EuclideanGraphTriangle <T>(corner1, corner2, edge[0]);
                EuclideanGraphTriangle <T> newTriangle2 = new EuclideanGraphTriangle <T>(corner1, corner2, edge[1]);

                // Update the Delaunay Tree
                delaunayTree.Replace(triangle1, triangle2, newTriangle1, newTriangle2);
            }
        }
Exemplo n.º 9
0
        private int PathLength(EuclideanGraphNode <T> node1, EuclideanGraphNode <T> node2, int maxIterations = int.MaxValue)
        {
            List <EuclideanGraphNode <T> > visited      = new List <EuclideanGraphNode <T> >();
            List <EuclideanGraphNode <T> > toVisitNow   = new List <EuclideanGraphNode <T> >();
            List <EuclideanGraphNode <T> > toVisitLater = new List <EuclideanGraphNode <T> >();

            toVisitNow.Add(node1);
            int iterations = 0;

            while (toVisitNow.Count > 0 && iterations < maxIterations)
            {
                foreach (EuclideanGraphNode <T> node in toVisitNow)
                {
                    if (node == node2)
                    {
                        return(iterations);
                    }
                    else
                    {
                        foreach (EuclideanGraphNode <T> neighbor in node.GetNeighbors())
                        {
                            if (!visited.Contains(neighbor))
                            {
                                toVisitLater.Add(neighbor);
                            }
                        }
                    }
                }

                iterations++;
                visited.AddRange(toVisitNow);
                toVisitNow   = toVisitLater;
                toVisitLater = new List <EuclideanGraphNode <T> >();
            }

            return(-1);
        }
 public EuclideanGraphTriangle(EuclideanGraphNode <T> corner1, EuclideanGraphNode <T> corner2, EuclideanGraphNode <T> corner3)
 {
     Corners = new EuclideanGraphNode <T>[] { corner1, corner2, corner3 };
 }
        public float GetOppositeAngle(EuclideanGraphNode <T>[] edge)
        {
            EuclideanGraphNode <T> opposite = GetOppositeCorner(edge);

            return(Vector2.Angle(edge[0].GetPosition() - opposite.GetPosition(), edge[1].GetPosition() - opposite.GetPosition()));
        }
Exemplo n.º 12
0
 public EuclideanGraphEdge(EuclideanGraphNode <T> node1, EuclideanGraphNode <T> node2)
 {
     Active = true;
     Nodes  = new EuclideanGraphNode <T>[] { node1, node2 };
 }