Example #1
0
        /// <summary>
        /// Visualization of 2D Voronoi map.
        /// </summary>
        /// <param name="weight">Weight of result image.</param>
        /// <param name="height">Height of result image.</param>
        /// <param name="Datapoints">Array of data points.</param>
        /// <returns>Result bitmap.</returns>
        public static Bitmap GetVoronoyMap(int weight, int height, IEnumerable Datapoints)
        {
            Bitmap       bmp   = new Bitmap(weight, height);
            VoronoiGraph graph = Fortune.ComputeVoronoiGraph(Datapoints);
            Graphics     g     = Graphics.FromImage(bmp);

            foreach (object o in graph.Vertizes)
            {
                Vector3 v = (Vector3)o;
                g.DrawEllipse(Pens.Black, (int)v[0] - 2, (int)v[1] - 2, 4, 4);
            }
            foreach (object o in Datapoints)
            {
                Vector3 v = (Vector3)o;
                g.DrawEllipse(Pens.Red, (int)v[0] - 1, (int)v[1] - 1, 2, 2);
            }
            foreach (object o in graph.Edges)
            {
                VoronoiEdge edge = (VoronoiEdge)o;
                try
                {
                    g.DrawLine(Pens.Brown, (int)edge.VVertexA[0], (int)edge.VVertexA[1], (int)edge.VVertexB[0], (int)edge.VVertexB[1]);
                }
                catch { }
            }
            return(bmp);
        }
Example #2
0
        /// <summary>
        /// Will return the new root (unchanged except in start-up)
        /// </summary>
        public static VNode ProcessDataEvent(VDataEvent e, VNode Root, VoronoiGraph VG, float ys, out VDataNode[] CircleCheckList)
        {
            if (Root == null)
            {
                Root            = new VDataNode(e.DataPoint);
                CircleCheckList = new VDataNode[] { (VDataNode)Root };
                return(Root);
            }
            //1. Find the node to be replaced
            VNode C = VNode.FindDataNode(Root, ys, e.DataPoint[0]);
            //2. Create the subtree (ONE Edge, but two VEdgeNodes)
            VoronoiEdge VE = new VoronoiEdge();

            VE.LeftData  = ((VDataNode)C).DataPoint;
            VE.RightData = e.DataPoint;
            VE.VVertexA  = Fortune.VVUnkown;
            VE.VVertexB  = Fortune.VVUnkown;
            VG.Edges.Add(VE);

            VNode SubRoot;

            if (Math.Abs(VE.LeftData[1] - VE.RightData[1]) < 1e-10)
            {
                if (VE.LeftData[0] < VE.RightData[0])
                {
                    SubRoot       = new VEdgeNode(VE, false);
                    SubRoot.Left  = new VDataNode(VE.LeftData);
                    SubRoot.Right = new VDataNode(VE.RightData);
                }
                else
                {
                    SubRoot       = new VEdgeNode(VE, true);
                    SubRoot.Left  = new VDataNode(VE.RightData);
                    SubRoot.Right = new VDataNode(VE.LeftData);
                }
                CircleCheckList = new VDataNode[] { (VDataNode)SubRoot.Left, (VDataNode)SubRoot.Right };
            }
            else
            {
                SubRoot             = new VEdgeNode(VE, false);
                SubRoot.Left        = new VDataNode(VE.LeftData);
                SubRoot.Right       = new VEdgeNode(VE, true);
                SubRoot.Right.Left  = new VDataNode(VE.RightData);
                SubRoot.Right.Right = new VDataNode(VE.LeftData);
                CircleCheckList     = new VDataNode[] { (VDataNode)SubRoot.Left, (VDataNode)SubRoot.Right.Left, (VDataNode)SubRoot.Right.Right };
            }

            //3. Apply subtree
            if (C.Parent == null)
            {
                return(SubRoot);
            }
            C.Parent.Replace(C, SubRoot);
            return(Root);
        }
Example #3
0
        /// <summary>
        /// Visualization of Delaunay Triangulation
        /// </summary>
        /// <param name="weight">Weight of result image.</param>
        /// <param name="height">Height of result image.</param>
        /// <param name="Datapoints">Result bitmap.</param>
        /// <returns></returns>
        public static List <Triangle> GetDelaunayTriangulation(IEnumerable Datapoints)
        {
            System.Collections.Generic.List <Triangle> list = new System.Collections.Generic.List <Triangle>();
            VoronoiGraph voronoiGraph = Fortune.ComputeVoronoiGraph(Datapoints);
            //Graphics g = Graphics.FromImage(bmp);
            List <Triangle> triangles = new List <Triangle>();

            for (int i = voronoiGraph.Edges.Count - 1; i >= 0; i--)
            {
                VoronoiEdge edge1 = voronoiGraph.Edges[i];
                for (int j = 0; j < i; j++)
                {
                    VoronoiEdge edge2 = voronoiGraph.Edges[j];
                    //if (edge1.LeftData.Index == edge2.LeftData.Index)
                    //{
                    //    triangles.Add(new Triangle(edge1.LeftData.Index, edge1.RightData.Index, edge2.RightData.Index));
                    //}
                    //if (edge1.RightData.Index == edge2.RightData.Index)
                    //{
                    //    triangles.Add(new Triangle(edge1.LeftData.Index, edge1.RightData.Index, edge2.LeftData.Index));
                    //}
                    //if (edge1.RightData.Index == edge2.LeftData.Index)
                    //{
                    //    triangles.Add(new Triangle(edge1.LeftData.Index, edge1.RightData.Index, edge2.RightData.Index));
                    //}
                    //if (edge1.LeftData.Index == edge2.RightData.Index)
                    //{
                    //    triangles.Add(new Triangle(edge1.LeftData.Index, edge1.RightData.Index, edge2.LeftData.Index));
                    //}
                }
                //if ((edge.LeftData[0] == v[0]) & (edge.LeftData[1] == v[1]))
                //{
                //    g.DrawLine(Pens.Black, (int)edge.LeftData[0], (int)edge.LeftData[1], (int)edge.RightData[0], (int)edge.RightData[1]);
                //}
            }


            ////Graphics g = Graphics.FromImage(bmp);
            //foreach (object o in Datapoints)
            //{
            //    Vector3 v = (Vector3)o;
            //    //g.DrawEllipse(Pens.Red, (int)v[0] - 1, (int)v[1] - 1, 2, 2);
            //    foreach (object obj in voronoiGraph.Edges)
            //    {
            //        VoronoiEdge edge = (VoronoiEdge)obj;
            //        if ((edge.LeftData[0] == v[0]) & (edge.LeftData[1] == v[1]))
            //        {
            //            g.DrawLine(Pens.Black, (int)edge.LeftData[0], (int)edge.LeftData[1], (int)edge.RightData[0], (int)edge.RightData[1]);
            //        }
            //    }
            //}
            return(triangles);
        }
Example #4
0
 public VEdgeNode(VoronoiEdge E, bool Flipped)
 {
     this.Edge    = E;
     this.Flipped = Flipped;
 }
Example #5
0
        public static VNode ProcessCircleEvent(VCircleEvent e, VNode Root, VoronoiGraph VG, float ys, out VDataNode[] CircleCheckList)
        {
            VDataNode a, b, c;
            VEdgeNode eu, eo;

            b = e.NodeN;
            a = VNode.LeftDataNode(b);
            c = VNode.RightDataNode(b);
            if (a == null || b.Parent == null || c == null || !a.DataPoint.Equals(e.NodeL.DataPoint) || !c.DataPoint.Equals(e.NodeR.DataPoint))
            {
                CircleCheckList = new VDataNode[] {};
                return(Root);                // Abbruch da sich der Graph verändert hat
            }
            eu = (VEdgeNode)b.Parent;
            CircleCheckList = new VDataNode[] { a, c };
            //1. Create the new Vertex
            Vector3 VNew = new Vector3(e.Center[0], e.Center[1], 0);

//			VNew[0] = Fortune.ParabolicCut(a.DataPoint[0],a.DataPoint[1],c.DataPoint[0],c.DataPoint[1],ys);
//			VNew[1] = (ys + a.DataPoint[1])/2 - 1/(2*(ys-a.DataPoint[1]))*(VNew[0]-a.DataPoint[0])*(VNew[0]-a.DataPoint[0]);
            VG.Vertizes.Add(VNew);
            //2. Find out if a or c are in a distand part of the tree (the other is then b's sibling) and assign the new vertex
            if (eu.Left == b)          // c is sibling
            {
                eo = VNode.EdgeToRightDataNode(a);

                // replace eu by eu's Right
                eu.Parent.Replace(eu, eu.Right);
            }
            else             // a is sibling
            {
                eo = VNode.EdgeToRightDataNode(b);

                // replace eu by eu's Left
                eu.Parent.Replace(eu, eu.Left);
            }
            eu.Edge.AddVertex(VNew);
//			///////////////////// uncertain
//			if(eo==eu)
//				return Root;
//			/////////////////////
            eo.Edge.AddVertex(VNew);
            //2. Replace eo by new Edge
            VoronoiEdge VE = new VoronoiEdge();

            VE.LeftData  = a.DataPoint;
            VE.RightData = c.DataPoint;
            VE.AddVertex(VNew);
            VG.Edges.Add(VE);

            VEdgeNode VEN = new VEdgeNode(VE, false);

            VEN.Left  = eo.Left;
            VEN.Right = eo.Right;
            if (eo.Parent == null)
            {
                return(VEN);
            }
            eo.Parent.Replace(eo, VEN);
            return(Root);
        }
Example #6
0
        public static VNode ProcessCircleEvent(VCircleEvent e, VNode root, VoronoiGraph vg, double ys, out VDataNode[] circleCheckList)
        {
            VEdgeNode eo;
            var       b = e.NodeN;
            var       a = LeftDataNode(b);
            var       c = RightDataNode(b);

            if (a == null || b.Parent == null || c == null || a.DataPoint != e.NodeL.DataPoint || c.DataPoint != e.NodeR.DataPoint)
            {
                circleCheckList = new VDataNode[] { };
                return(root); // Abbruch da sich der Graph verändert hat
            }
            var eu = (VEdgeNode)b.Parent;

            circleCheckList = new[] { a, c };
            //1. Create the new Vertex
            var vNew = new Vector(e.Center[0], e.Center[1]);

            //			VNew[0] = Fortune.ParabolicCut(a.DataPoint[0],a.DataPoint[1],c.DataPoint[0],c.DataPoint[1],ys);
            //			VNew[1] = (ys + a.DataPoint[1])/2 - 1/(2*(ys-a.DataPoint[1]))*(VNew[0]-a.DataPoint[0])*(VNew[0]-a.DataPoint[0]);
            vg.Vertizes.Add(vNew);
            //2. Find out if a or c are in a distand part of the tree (the other is then b's sibling) and assign the new vertex
            if (eu.Left == b) // c is sibling
            {
                eo = EdgeToRightDataNode(a);

                // replace eu by eu's Right
                eu.Parent.Replace(eu, eu.Right);
            }
            else   // a is sibling
            {
                eo = EdgeToRightDataNode(b);

                // replace eu by eu's Left
                eu.Parent.Replace(eu, eu.Left);
            }
            eu.Edge.AddVertex(vNew);
            //			///////////////////// uncertain
            //			if(eo==eu)
            //				return Root;
            //			/////////////////////

            //complete & cleanup eo
            eo.Edge.AddVertex(vNew);
            //while(eo.Edge.VVertexB == Fortune.VVUnkown)
            //{
            //    eo.Flipped = !eo.Flipped;
            //    eo.Edge.AddVertex(Fortune.VVInfinite);
            //}
            //if(eo.Flipped)
            //{
            //    Vector T = eo.Edge.LeftData;
            //    eo.Edge.LeftData = eo.Edge.RightData;
            //    eo.Edge.RightData = T;
            //}

            //2. Replace eo by new Edge
            var ve = new VoronoiEdge {
                LeftData  = a.DataPoint,
                RightData = c.DataPoint
            };

            ve.AddVertex(vNew);
            vg.Edges.Add(ve);

            var ven = new VEdgeNode(ve, false)
            {
                Left  = eo.Left,
                Right = eo.Right
            };

            if (eo.Parent == null)
            {
                return(ven);
            }
            eo.Parent.Replace(eo, ven);
            return(root);
        }
Example #7
0
        /// <summary>
        /// Will return the new root (unchanged except in start-up)
        /// </summary>
        public static VNode ProcessDataEvent(VDataEvent e, VNode root, VoronoiGraph vg, double ys, out VDataNode[] circleCheckList)
        {
            if (root == null)
            {
                root            = new VDataNode(e.DataPoint);
                circleCheckList = new[] { (VDataNode)root };
                return(root);
            }
            //1. Find the node to be replaced
            VNode c = FindDataNode(root, ys, e.DataPoint[0]);
            //2. Create the subtree (ONE Edge, but two VEdgeNodes)
            var ve = new VoronoiEdge {
                LeftData  = ((VDataNode)c).DataPoint,
                RightData = e.DataPoint,
                VVertexA  = Fortune.VvUnkown,
                VVertexB  = Fortune.VvUnkown
            };

            vg.Edges.Add(ve);

            VNode subRoot;

            if (Math.Abs(ve.LeftData[1] - ve.RightData[1]) < 1e-10)
            {
                if (ve.LeftData[0] < ve.RightData[0])
                {
                    subRoot = new VEdgeNode(ve, false)
                    {
                        Left  = new VDataNode(ve.LeftData),
                        Right = new VDataNode(ve.RightData)
                    };
                }
                else
                {
                    subRoot = new VEdgeNode(ve, true)
                    {
                        Left  = new VDataNode(ve.RightData),
                        Right = new VDataNode(ve.LeftData)
                    };
                }
                circleCheckList = new[] { (VDataNode)subRoot.Left, (VDataNode)subRoot.Right };
            }
            else
            {
                subRoot = new VEdgeNode(ve, false)
                {
                    Left  = new VDataNode(ve.LeftData),
                    Right = new VEdgeNode(ve, true)
                    {
                        Left  = new VDataNode(ve.RightData),
                        Right = new VDataNode(ve.LeftData)
                    }
                };
                circleCheckList = new[] { (VDataNode)subRoot.Left, (VDataNode)subRoot.Right.Left, (VDataNode)subRoot.Right.Right };
            }

            //3. Apply subtree
            if (c.Parent == null)
            {
                return(subRoot);
            }
            c.Parent.Replace(c, subRoot);
            return(root);
        }
Example #8
0
        /// <summary>
        /// Will return the new root (unchanged except in start-up)
        /// </summary>
        public static VNode ProcessDataEvent(VDataEvent e, VNode Root, VoronoiGraph VG, double ys, out VDataNode[] CircleCheckList)
        {
            if(Root==null)
            {
                Root = new VDataNode(e.DataPoint);
                CircleCheckList = new VDataNode[] {(VDataNode)Root};
                return Root;
            }
            //1. Find the node to be replaced
            VNode C = VNode.FindDataNode(Root, ys, e.DataPoint.X);
            //2. Create the subtree (ONE Edge, but two VEdgeNodes)
            VoronoiEdge VE = new VoronoiEdge();
            VE.LeftData = ((VDataNode)C).DataPoint;
            VE.RightData = e.DataPoint;
            VE.VVertexA = Fortune.VVUnkown;
            VE.VVertexB = Fortune.VVUnkown;
            VG.Edges.Add(VE);

            VNode SubRoot;
            if(Math.Abs(VE.LeftData.Y-VE.RightData.Y)<1e-10)
            {
                if(VE.LeftData.X<VE.RightData.X)
                {
                    SubRoot = new VEdgeNode(VE,false);
                    SubRoot.Left = new VDataNode(VE.LeftData);
                    SubRoot.Right = new VDataNode(VE.RightData);
                }
                else
                {
                    SubRoot = new VEdgeNode(VE,true);
                    SubRoot.Left = new VDataNode(VE.RightData);
                    SubRoot.Right = new VDataNode(VE.LeftData);
                }
                CircleCheckList = new VDataNode[] {(VDataNode)SubRoot.Left,(VDataNode)SubRoot.Right};
            }
            else
            {
                SubRoot = new VEdgeNode(VE,false);
                SubRoot.Left = new VDataNode(VE.LeftData);
                SubRoot.Right = new VEdgeNode(VE,true);
                SubRoot.Right.Left = new VDataNode(VE.RightData);
                SubRoot.Right.Right = new VDataNode(VE.LeftData);
                CircleCheckList = new VDataNode[] {(VDataNode)SubRoot.Left,(VDataNode)SubRoot.Right.Left,(VDataNode)SubRoot.Right.Right};
            }

            //3. Apply subtree
            if(C.Parent == null)
                return SubRoot;
            C.Parent.Replace(C,SubRoot);
            return Root;
        }
Example #9
0
        public static VNode ProcessCircleEvent(VCircleEvent e, VNode Root, VoronoiGraph VG, double ys, out VDataNode[] CircleCheckList)
        {
            VDataNode a,b,c;
            VEdgeNode eu,eo;
            b = e.NodeN;
            a = VNode.LeftDataNode(b);
            c = VNode.RightDataNode(b);
            if(a==null || b.Parent==null || c==null || !a.DataPoint.Equals(e.NodeL.DataPoint) || !c.DataPoint.Equals(e.NodeR.DataPoint))
            {
                CircleCheckList = new VDataNode[]{};
                return Root; // Abbruch da sich der Graph verändert hat
            }
            eu = (VEdgeNode)b.Parent;
            CircleCheckList = new VDataNode[] {a,c};
            //1. Create the new Vertex
            Point VNew = new Point(e.Center.X,e.Center.Y);
            //			VNew.X = Fortune.ParabolicCut(a.DataPoint.X,a.DataPoint.Y,c.DataPoint.X,c.DataPoint.Y,ys);
            //			VNew.Y = (ys + a.DataPoint.Y)/2 - 1/(2*(ys-a.DataPoint.Y))*(VNew.X-a.DataPoint.X)*(VNew.X-a.DataPoint.X);
            VG.Vertizes.Add(VNew);
            //2. Find out if a or c are in a distand part of the tree (the other is then b's sibling) and assign the new vertex
            if(eu.Left==b) // c is sibling
            {
                eo = VNode.EdgeToRightDataNode(a);

                // replace eu by eu's Right
                eu.Parent.Replace(eu,eu.Right);
            }
            else // a is sibling
            {
                eo = VNode.EdgeToRightDataNode(b);

                // replace eu by eu's Left
                eu.Parent.Replace(eu,eu.Left);
            }
            eu.Edge.AddVertex(VNew);
            //			///////////////////// uncertain
            //			if(eo==eu)
            //				return Root;
            //			/////////////////////

            //complete & cleanup eo
            eo.Edge.AddVertex(VNew);
            //while(eo.Edge.VVertexB == Fortune.VVUnkown)
            //{
            //    eo.Flipped = !eo.Flipped;
            //    eo.Edge.AddVertex(Fortune.VVInfinite);
            //}
            //if(eo.Flipped)
            //{
            //    Vector T = eo.Edge.LeftData;
            //    eo.Edge.LeftData = eo.Edge.RightData;
            //    eo.Edge.RightData = T;
            //}

            //2. Replace eo by new Edge
            VoronoiEdge VE = new VoronoiEdge();
            VE.LeftData = a.DataPoint;
            VE.RightData = c.DataPoint;
            VE.AddVertex(VNew);
            VG.Edges.Add(VE);

            VEdgeNode VEN = new VEdgeNode(VE, false);
            VEN.Left = eo.Left;
            VEN.Right = eo.Right;
            if(eo.Parent == null)
                return VEN;
            eo.Parent.Replace(eo,VEN);
            return Root;
        }
Example #10
0
 public VEdgeNode(VoronoiEdge E, bool Flipped)
 {
     this.Edge = E;
     this.Flipped = Flipped;
 }
Example #11
0
    void Start()
    {
        var meshFilter = gameObject.AddComponent<MeshFilter>();

        var edges = CellData.Edges.Select(e =>
        {
            var vA = e.VVertexA;
            var vB = e.VVertexB;
            var dA = vA - CellData.Site;
            var dB = vB - CellData.Site;
            var atanA = Mathf.Atan2((float)dA.Y, (float)dA.X);
            var atanB = Mathf.Atan2((float)dB.Y, (float)dB.X);

            VoronoiEdge edge;
            if (atanA > 0f)
            {
                if (atanA < atanB)
                {
                    edge = new VoronoiEdge { VVertexA = vB - CellData.Site, VVertexB = vA - CellData.Site };
                }
                else
                {
                    if (atanA - atanB > Mathf.PI)
                    {
                        edge = new VoronoiEdge { VVertexA = vB - CellData.Site, VVertexB = vA - CellData.Site };
                    }
                    else
                    {
                        edge = new VoronoiEdge { VVertexA = vA - CellData.Site, VVertexB = vB - CellData.Site };
                    }
                }
            }
            else
            {
                if (atanA > atanB)
                {
                    edge = new VoronoiEdge { VVertexA = vA - CellData.Site, VVertexB = vB - CellData.Site };
                }
                else
                {
                    if (atanB - atanA > Mathf.PI)
                    {
                        edge = new VoronoiEdge { VVertexA = vA - CellData.Site, VVertexB = vB - CellData.Site };
                    }
                    else
                    {
                        edge = new VoronoiEdge { VVertexA = vB - CellData.Site, VVertexB = vA - CellData.Site };
                    }
                }
            }

            return edge;
        }).ToArray();

        var maxDistFromCenter = edges.Max(e => Mathf.Max((float)e.VVertexA.Length, (float)e.VVertexB.Length));
        if (edges[0].VVertexA.Length > maxDistFromCenter)
        {
            maxDistFromCenter = (float)edges[0].VVertexA.Length;
        }
        maxDistFromCenter *= 2; // To make sure that UV coords will be in [-0.5; 0.5] range

        Mesh mesh = new Mesh();
        mesh.name = "cellMesh";

        var cellCorners = new Vector3[edges.Length * 2 + 1];
        var triangles = new int[edges.Length * 3];
        var uvs = new Vector2[edges.Length * 2 + 1];

        cellCorners[0] = Vector3.zero;   // Placing Cell Center at Origin of new GameObjects

        //verts [1] = new Vector3 (edges [0].Start.x, edges [0].Start.y, 0f);

        var shift = new Vector2(0.5f, 0.5f); // Shifting texture coords origin
        uvs[0] = shift;
        uvs[1] = new Vector2(((float)edges[0].VVertexA.X + shift.x) / maxDistFromCenter, ((float)edges[0].VVertexA.Y + shift.y) / maxDistFromCenter);

        for (int i = 0; i < edges.Length; i++)
        {
            var edge = edges[i];

            cellCorners[2 * i + 1] = new Vector3((float)edges[i].VVertexA.X, (float)edges[i].VVertexA.Y, 0f);
            cellCorners[2 * i + 2] = new Vector3((float)edges[i].VVertexB.X, (float)edges[i].VVertexB.Y, 0f);

            var uvStart = shift + new Vector2((float)edge.VVertexA.X / maxDistFromCenter, (float)edge.VVertexA.Y / maxDistFromCenter);
            var uvEnd = shift + new Vector2((float)edge.VVertexB.X / maxDistFromCenter, (float)edge.VVertexB.Y / maxDistFromCenter);
            uvs[2 * i + 1] = new Vector3(uvStart.x, uvStart.y, 0f);
            uvs[2 * i + 2] = new Vector3(uvEnd.x, uvEnd.y, 0f);

            triangles[3 * i] = 0;
            triangles[3 * i + 1] = 2 * i + 1;
            triangles[3 * i + 2] = 2 * i + 2;
        }

        mesh.vertices = cellCorners;
        mesh.uv = uvs;
        mesh.triangles = triangles;

        mesh.RecalculateNormals();
        mesh.RecalculateBounds();
        mesh.Optimize();
        mesh.RecalculateTangents();

        meshFilter.sharedMesh = mesh;

        var meshRenderer = gameObject.AddComponent<MeshRenderer>();

        if (MeshMaterial == null)
        {
            meshRenderer.material.color = Color.green;
        }
        else
        {
            meshRenderer.material = MeshMaterial;
        }

        var polyCollider = gameObject.AddComponent<EdgeCollider2D>();

        polyCollider.points = cellCorners.Skip(1).Select(c => new Vector2(c.x, c.y)).ToArray();
    }
Example #12
0
 public VEdgeNode(VoronoiEdge e, bool flipped)
 {
     Edge    = e;
     Flipped = flipped;
 }
Example #13
0
        public static VNode ProcessCircleEvent(VCircleEvent e, VNode Root, VoronoiGraph VG, double ys, out VDataNode[] CircleCheckList)
        {
            VDataNode a, b, c;
            VEdgeNode eu, eo;

            b = e.NodeN;
            a = VNode.LeftDataNode(b);
            c = VNode.RightDataNode(b);
            if (a == null || b.Parent == null || c == null || !a.DataPoint.Equals(e.NodeL.DataPoint) || !c.DataPoint.Equals(e.NodeR.DataPoint))
            {
                CircleCheckList = new VDataNode[] {};
                return(Root);                // Abbruch da sich der Graph verändert hat
            }
            eu = (VEdgeNode)b.Parent;
            CircleCheckList = new VDataNode[] { a, c };
            //1. Create the new Vertex
            Point VNew = new Point(e.Center.X, e.Center.Y);

//			VNew.X = Fortune.ParabolicCut(a.DataPoint.X,a.DataPoint.Y,c.DataPoint.X,c.DataPoint.Y,ys);
//			VNew.Y = (ys + a.DataPoint.Y)/2 - 1/(2*(ys-a.DataPoint.Y))*(VNew.X-a.DataPoint.X)*(VNew.X-a.DataPoint.X);
            VG.Vertizes.Add(VNew);
            //2. Find out if a or c are in a distand part of the tree (the other is then b's sibling) and assign the new vertex
            if (eu.Left == b)          // c is sibling
            {
                eo = VNode.EdgeToRightDataNode(a);

                // replace eu by eu's Right
                eu.Parent.Replace(eu, eu.Right);
            }
            else             // a is sibling
            {
                eo = VNode.EdgeToRightDataNode(b);

                // replace eu by eu's Left
                eu.Parent.Replace(eu, eu.Left);
            }
            eu.Edge.AddVertex(VNew);
//			///////////////////// uncertain
//			if(eo==eu)
//				return Root;
//			/////////////////////

            //complete & cleanup eo
            eo.Edge.AddVertex(VNew);
            //while(eo.Edge.VVertexB == Fortune.VVUnkown)
            //{
            //    eo.Flipped = !eo.Flipped;
            //    eo.Edge.AddVertex(Fortune.VVInfinite);
            //}
            //if(eo.Flipped)
            //{
            //    Vector T = eo.Edge.LeftData;
            //    eo.Edge.LeftData = eo.Edge.RightData;
            //    eo.Edge.RightData = T;
            //}


            //2. Replace eo by new Edge
            VoronoiEdge VE = new VoronoiEdge();

            VE.LeftData  = a.DataPoint;
            VE.RightData = c.DataPoint;
            VE.AddVertex(VNew);
            VG.Edges.Add(VE);

            VEdgeNode VEN = new VEdgeNode(VE, false);

            VEN.Left  = eo.Left;
            VEN.Right = eo.Right;
            if (eo.Parent == null)
            {
                return(VEN);
            }
            eo.Parent.Replace(eo, VEN);
            return(Root);
        }