/// <summary>
        /// Get an image of a graph described by a Delaunay tree
        /// </summary>
        /// <param name="tree"></param>
        /// <returns></returns>
        private Texture2D GetDebugImage(DelaunayTree.DelaunayTree <T> tree)
        {
            Texture2D texture = new Texture2D(1024, 1024);

            List <EuclideanGraphTriangle <T> > triangles = tree.GetCurrentTriangles();

            foreach (EuclideanGraphTriangle <T> triangle in triangles)
            {
                EuclideanGraphNode <T>[] corners = triangle.GetCorners();
                foreach (EuclideanGraphNode <T> corner in corners)
                {
                    Vector2 position = corner.Position * (1024 / (4 * Radius)) + new Vector2(1024 / 2, 1024 / 2);
                    Drawing.DrawCircle(texture, position, 10, Color.red);
                }

                Queue <EuclideanGraphNode <T>[]> edges = triangle.GetEdges();
                foreach (EuclideanGraphNode <T>[] edge in edges)
                {
                    Vector2 position1 = edge[0].Position * (1024 / (4 * Radius)) + new Vector2(1024 / 2, 1024 / 2);
                    Vector2 position2 = edge[1].Position * (1024 / (4 * Radius)) + new Vector2(1024 / 2, 1024 / 2);
                    Drawing.DrawLine(texture, position1, position2, Color.black);
                }
            }

            return(texture);
        }
        /// <summary>
        /// Save an image of the given Delaunay tree to the specified file
        /// location
        /// </summary>
        /// <param name="fileName"></param>
        /// <param name="tree"></param>
        private void SaveSnapshot(string fileName, DelaunayTree.DelaunayTree <T> tree)
        {
            Texture2D texture = GetDebugImage(tree);

            byte[] bytes = texture.EncodeToPNG();
            string path  = Application.dataPath + "/../GraphSnapshots";

            Directory.CreateDirectory(path);
            File.WriteAllBytes(path + "/" + fileName + ".png", bytes);
        }
        /// <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);
        }
        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);
            }
        }