Example #1
0
 public void Generate(List<Vector2> points, int width, int height)
 {
     mapWidth = width;
     mapHeight = height;        
     graph = gen.ComputeVoronoiGraph(points, width, height);
     edges = graph.Edges.ToList();
     sitePolygons = new List<Polygon>();
 }
Example #2
0
 public MapGenerator(GraphicsDevice device, SpriteBatch spriteBatch)
 {
     gen = new Fortune();
     graph = new VoronoiGraph();
     edges = new List<VoronoiEdge>();
     sitePolygons = new List<Polygon>();
     this.device = device;
     this.spriteBatch = spriteBatch;
 }
Example #3
0
 public static VoronoiGraph ComputeVoronoiGraph(IEnumerable Datapoints)
 {
     BinaryPriorityQueue PQ = new BinaryPriorityQueue();
     Hashtable CurrentCircles = new Hashtable();
     VoronoiGraph VG = new VoronoiGraph();
     VNode RootNode = null;
     foreach(Vector V in Datapoints)
     {
         PQ.Push(new VDataEvent(V));
     }
     while(PQ.Count>0)
     {
         VEvent VE = PQ.Pop() as VEvent;
         VDataNode[] CircleCheckList;
         if(VE is VDataEvent)
         {
             RootNode = VNode.ProcessDataEvent(VE as VDataEvent,RootNode,VG,VE.Y,out CircleCheckList);
         }
         else if(VE is VCircleEvent)
         {
             CurrentCircles.Remove(((VCircleEvent)VE).NodeN);
             if(!((VCircleEvent)VE).Valid)
                 continue;
             RootNode = VNode.ProcessCircleEvent(VE as VCircleEvent,RootNode,VG,VE.Y,out CircleCheckList);
         }
         else throw new Exception("Got event of type "+VE.GetType().ToString()+"!");
         foreach(VDataNode VD in CircleCheckList)
         {
             if(CurrentCircles.ContainsKey(VD))
             {
                 ((VCircleEvent)CurrentCircles[VD]).Valid=false;
                 CurrentCircles.Remove(VD);
             }
             VCircleEvent VCE = VNode.CircleCheckDataNode(VD,VE.Y);
             if(VCE!=null)
             {
                 PQ.Push(VCE);
                 CurrentCircles[VD]=VCE;
             }
         }
         if(VE is VDataEvent)
         {
             Vector DP = ((VDataEvent)VE).DataPoint;
             foreach(VCircleEvent VCE in CurrentCircles.Values)
             {
                 if(MathTools.Dist(DP[0],DP[1],VCE.Center[0],VCE.Center[1])<VCE.Y-VCE.Center[1] && Math.Abs(MathTools.Dist(DP[0],DP[1],VCE.Center[0],VCE.Center[1])-(VCE.Y-VCE.Center[1]))>1e-10)
                     VCE.Valid = false;
             }
         }
     }
     return VG;
 }
        public static VoronoiGraph FilterVG(VoronoiGraph VG, double minLeftRightDist)
        {
            VoronoiGraph VGErg = new VoronoiGraph();

            foreach (VoronoiEdge VE in VG.Edges)
            {
                if (Math.Sqrt(Vector.Dist(VE.LeftData, VE.RightData)) >= minLeftRightDist)
                {
                    VGErg.Edges.Add(VE);
                }
            }
            foreach (VoronoiEdge VE in VGErg.Edges)
            {
                VGErg.Vertizes.Add(VE.VVertexA);
                VGErg.Vertizes.Add(VE.VVertexB);
            }
            return(VGErg);
        }
Example #5
0
				private int NumberOfSites = 512; // Number of seed points to generate for the voronoi diagram, the higher the number the more tesselated the map will be.		

				private bool BuildGraph ()
				{
						
						Sites_World = GenerateRandom (Seed, NumberOfSites, 0, Max);
						Profiler.BeginSample ("Fortune Compute VoronoiGraph");
						Graph_World = Fortune.ComputeVoronoiGraph (Sites_World);
						Profiler.EndSample ();
						if (Relax) {
								// Lloyd Relax the points here to get more even distribution.
								// First we need to know the N number of Voronoi Verts that make up each cell.
								// Then we can find the centroid of each of those Cells, and move the Site that created this cell to that centroid.
								// Finally we replace our existing Voronoi graph with a new one made from these centered sites.
								// This will be computationally expensive so we don't want to do it too many times, 2 max??
								for (int i = 0; i < RelaxSteps; i++) {
										Sites_World = LloydRelax (Sites_World, Graph_World);
										Graph_World = Fortune.ComputeVoronoiGraph (Sites_World);
								}
						}
						// now you have all the voronoi vertices in graph.Vertices and all the voronoi edges in Relsult.Edges
						//Debug.Log ("Number of Sites: " + sites.Length); 
						//Debug.Log ("graph.Verts Length: " + graph.Vertizes.Count);
						
						if (GenerateCells) {
								Debug.Log ("Starting Generating Cells in the BuildGraph, Max is: " + Max);
								//Convert Voronoi to Cells
								for (int j =0; j < Sites_World.Length; j++) {					
										Vector v = Sites_World [j];
										Cell c = new Cell (v);
										
										c.max = Max;
										c.border = false;
										List<VoronoiEdge> currentBorders = new List<VoronoiEdge> ();
										// Find Cell VoronoiEdges
										foreach (VoronoiEdge edge in Graph_World.Edges) {
												if (edge.LeftData == v || edge.RightData == v) {
														if (edge.IsInfinite) {
																c.IsBorder ();
																Vector AdjustedVec = edge.FixedPoint;
																edge.VVertexA = AdjustedVec;
																edge.VVertexB = AdjustedVec + (edge.DirectionVector * InfinityLength);
														} else if (edge.IsPartlyInfinite) {
																c.IsBorder ();
													
																Vector AdjustedVec = edge.FixedPoint;
																
																if (edge.VVertexA == Fortune.VVInfinite) {
																		edge.VVertexA = AdjustedVec;
																} 
																if (edge.VVertexB == Fortune.VVInfinite) {
																		edge.VVertexB = AdjustedVec;
																}
														}

														BorderCellMax = Max - Border;
														BorderCellMin = Border;

														if (edge.VVertexA [0] < BorderCellMin || edge.VVertexA [0] > BorderCellMax || edge.VVertexA [1] < BorderCellMin || edge.VVertexA [1] > BorderCellMax ||
																edge.VVertexB [0] < BorderCellMin || edge.VVertexB [0] > BorderCellMax || edge.VVertexB [1] < BorderCellMin || edge.VVertexB [1] > BorderCellMax) {
																c.IsBorder ();
														}

														if (!currentBorders.Contains (edge)) {
																currentBorders.Add (edge);
														}

														if (!c.neighborCells.Contains (edge.RightData)) {
																c.neighborCells.Add (edge.RightData);
														}
												} else if (edge.RightData == v) {
							
														if (!c.neighborCells.Contains (edge.LeftData)) {
																c.neighborCells.Add (edge.LeftData);
														}
												}
				
										}
										c.voronoiEdges = currentBorders;
										CellGraph.Add (v, c);
								}
						}

						//TODO make exceptions to handle errors during graph creation.
						if (CellGraph.Count > 0) {
								return true;
						} else {
								return false;
						}
				}
Example #6
0
				public void Restart ()
				{
						// Reset the System Random seed.
						r = new System.Random (Seed);
						Sites_World = null;
						Graph_World = null;
						CellGraph.Clear ();
				}
Example #7
0
				// Lloyd Relax the points here to get more even distribution.
				// First we need to know the N number of Voronoi Verts that make up each cell.
				// Then we can find the centroid of each of those cells, and move the Site that created this cell to that centroid.
				public Vector[] LloydRelax (Vector[] sites, VoronoiGraph graph)
				{
						List<Vector> RelaxedSites = new List<Vector> ();
						for (int s =0; s < sites.Length; s++) {
								List<Vector> cellVerts = new List<Vector> ();

								foreach (VoronoiEdge edge in graph.Edges) {
										if (edge.LeftData == sites [s]) {
												// Check if one or more of the edge verts is infinity
												if (edge.IsPartlyInfinite) {
														if (edge.VVertexA == Fortune.VVInfinite) {
																edge.VVertexA = (edge.FixedPoint + (edge.DirectionVector * InfinityLength));
														}
														if (edge.VVertexB == Fortune.VVInfinite) {
																edge.VVertexB = (edge.FixedPoint + (edge.DirectionVector * InfinityLength));
														}
												}
												edge.Clamp (Border, Max - Border);
												cellVerts.Add (edge.VVertexA);
												cellVerts.Add (edge.VVertexB);
										}

										// If we didn't find a LeftData for this edge just put that site back uncentered.
										Vector centroid = sites [s];
										if (cellVerts.Count > 0) {
												centroid = math_utilities.Compute2DPolygonCentroid (cellVerts);
												centroid.Clamp (Border, Max - Border);// lets hope this works better.
										}
				
										if (!RelaxedSites.Contains (centroid)) {
												RelaxedSites.Add (centroid);
										}
								}
						}
						return RelaxedSites.ToArray ();
				}
		public static VoronoiGraph FilterVG(VoronoiGraph VG, double minLeftRightDist)
		{
			VoronoiGraph VGErg = new VoronoiGraph();
			foreach(VoronoiEdge VE in VG.Edges)
			{
				if(Math.Sqrt(Vector.Dist(VE.LeftData,VE.RightData))>=minLeftRightDist)
					VGErg.Edges.Add(VE);
			}
			foreach(VoronoiEdge VE in VGErg.Edges)
			{
				VGErg.Vertizes.Add(VE.VVertexA);
				VGErg.Vertizes.Add(VE.VVertexB);
			}
			return VGErg;
		}
Example #9
0
        private void Canvas1_OnMouseDown(object sender, MouseButtonEventArgs e)
        {
            var rand = new Random();
            var result = new List<int>();
            var check = new HashSet<int>();
            for (int i = 0; i < 2000; i++)
            {
                Int32 curValue = rand.Next(0, 4000);
                while (check.Contains(curValue))
                {
                    curValue = rand.Next(0, 4000);
                }
                result.Add(curValue);
                check.Add(curValue);
            }

            //generate points inside our rectangle for our voronoi generator
            var datapointlist = new List<Vector>();

            for (int i = 0; i < 1000; i++)
            {
                datapointlist.Add(new Vector(result[i],result[i+1000]));
            }

            IEnumerable<Vector> datapoints = datapointlist;

            var vgraph = new VoronoiGraph();
            vgraph = Fortune.ComputeVoronoiGraph(datapoints);

            foreach (var vertex in vgraph.Vertizes)
            {

            }

            var R = 0;
            var G = 0;
            var B = 0;

            foreach (var edge in vgraph.Edges)
            {

                if (R < 255)
                    R++;
                if (R == 255 && G < 255)
                    G++;
                if (R == 255 && G == 255 && B < 255)
                    B++;

                var brush = new SolidColorBrush(Color.FromArgb(255, (byte)R, (byte)G, (byte)B));

                var poly = new Line()
                {
                    X1 = edge.LeftData[0],
                    Y1 = edge.LeftData[1],
                    X2 = edge.RightData[0],
                    Y2 = edge.RightData[1],
                    Stroke = brush,
                    StrokeThickness = 1
                };

                canvas1.Children.Add(poly);

                canvas1.InvalidateVisual();
                canvas1.UpdateLayout();
            }
        }
        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
            Vector 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.Vertices.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 #11
0
 private void AddEdges (VoronoiGraph g)
 {
     foreach (VoronoiEdge e in g.Edges)
     {
         if (EdgeBelongsToTile(e)) { AddEdge(e); }
     }
 }
Example #12
0
        public static VoronoiGraph ComputeVoronoiGraph(IEnumerable Datapoints)
        {
            BinaryPriorityQueue PQ             = new BinaryPriorityQueue();
            Hashtable           CurrentCircles = new Hashtable();
            VoronoiGraph        VG             = new VoronoiGraph();
            VNode RootNode = null;

            foreach (Vector V in Datapoints)
            {
                PQ.Push(new VDataEvent(V));
            }
            while (PQ.Count > 0)
            {
                VEvent      VE = PQ.Pop() as VEvent;
                VDataNode[] CircleCheckList;
                if (VE is VDataEvent)
                {
                    RootNode = VNode.ProcessDataEvent(VE as VDataEvent, RootNode, VG, VE.Y, out CircleCheckList);
                }
                else if (VE is VCircleEvent)
                {
                    CurrentCircles.Remove(((VCircleEvent)VE).NodeN);
                    if (!((VCircleEvent)VE).Valid)
                    {
                        continue;
                    }
                    RootNode = VNode.ProcessCircleEvent(VE as VCircleEvent, RootNode, VG, VE.Y, out CircleCheckList);
                }
                else
                {
                    throw new Exception("Got event of type " + VE.GetType().ToString() + "!");
                }
                foreach (VDataNode VD in CircleCheckList)
                {
                    if (CurrentCircles.ContainsKey(VD))
                    {
                        ((VCircleEvent)CurrentCircles[VD]).Valid = false;
                        CurrentCircles.Remove(VD);
                    }
                    VCircleEvent VCE = VNode.CircleCheckDataNode(VD, VE.Y);
                    if (VCE != null)
                    {
                        PQ.Push(VCE);
                        CurrentCircles[VD] = VCE;
                    }
                }
                if (VE is VDataEvent)
                {
                    Vector DP = ((VDataEvent)VE).DataPoint;
                    foreach (VCircleEvent VCE in CurrentCircles.Values)
                    {
                        if (MathTools.Dist(DP[0], DP[1], VCE.Center[0], VCE.Center[1]) < VCE.Y - VCE.Center[1] && Math.Abs(MathTools.Dist(DP[0], DP[1], VCE.Center[0], VCE.Center[1]) - (VCE.Y - VCE.Center[1])) > 1e-10)
                        {
                            VCE.Valid = false;
                        }
                    }
                }
            }

            VG.Regions = new Dictionary <Vector, VoronoiRegion>();

            foreach (VoronoiEdge e in VG.Edges)
            {
                if (e.VVertexA == VVUnkown || e.VVertexB == VVUnkown)
                {
                    continue;
                }

                for (int i = 0; i < 2; ++i)
                {
                    VoronoiRegion r;
                    Vector        key   = i == 0 ? e.LeftData : e.RightData;
                    bool          exist = VG.Regions.TryGetValue(key, out r);

                    if (exist)
                    {
                    }
                    else
                    {
                        r = new VoronoiRegion();
                    }
                    if (r.Coners.IndexOf(e.VVertexA) == -1)
                    {
                        r.Coners.Add(e.VVertexA);
                    }
                    if (r.Coners.IndexOf(e.VVertexB) == -1)
                    {
                        r.Coners.Add(e.VVertexB);
                    }

                    r.Edges.Add(e);

                    if (exist)
                    {
                    }
                    else
                    {
                        VG.Regions.Add(key, r);
                    }
                }
            }

            return(VG);
        }
Example #13
0
    public VoronoiGraph RefineGraph(VoronoiGraph g)
    {
        // Removes out of bound edges from a graph
        VoronoiGraph VGErg = new VoronoiGraph();
        
        foreach(VoronoiEdge e in g.Edges)
        {
            if (EdgeInBounds(e)) { VGErg.Edges.Add(e); }
        }

        foreach(VoronoiEdge VE in VGErg.Edges)
        {
            VGErg.Vertizes.Add(VE.VVertexA);
            VGErg.Vertizes.Add(VE.VVertexB);
        }

        return VGErg;
    }
Example #14
0
    public void GenerateGraph ()
    {
        Random.seed = seed;

        islandNoise = world.GetNoiseAt(islandPosition);
        cellVectors = RandomVectorList(voronoiCells);
        vGraph      = GenerateRelaxedGraph(cellVectors, relaxationIterations-1);
    }
Example #15
0
 void Reset ()
 {
     islandGenerated = false;
     islandTiles     = null;
     vGraph          = null;
     subIslands      = null;
     cellVectors     = null;
 }
        private void ImproveMapData(VoronoiGraph voronoiMap, bool fix = false)
        {
            IFactory fact = new MapItemFactory();

            foreach (VoronoiEdge edge in voronoiMap.Edges)
            {
                if (fix)
                {
                    if (!FixPoints(edge))
                        continue;
                }

                Corner c1 = fact.CornerFactory(edge.VVertexA[0], edge.VVertexA[1]);
                Corner c2 = fact.CornerFactory(edge.VVertexB[0], edge.VVertexB[1]);
                Center cntrLeft = fact.CenterFactory(edge.LeftData[0], edge.LeftData[1]);
                Center cntrRight = fact.CenterFactory(edge.RightData[0], edge.RightData[1]);

                if(c1 == null || c2 == null)
                {

                }

                c1.AddAdjacent(c2);
                c2.AddAdjacent(c1);

                cntrRight.Corners.Add(c1);
                cntrRight.Corners.Add(c2);

                cntrLeft.Corners.Add(c1);
                cntrLeft.Corners.Add(c2);

                Edge e = fact.EdgeFactory(c1, c2, cntrLeft, cntrRight);

                cntrLeft.Borders.Add(e);
                cntrRight.Borders.Add(e);

                cntrLeft.Neighbours.Add(cntrRight);
                cntrRight.Neighbours.Add(cntrLeft);

                c1.AddProtrudes(e);
                c2.AddProtrudes(e);
                c1.AddTouches(cntrLeft);
                c1.AddTouches(cntrRight);
                c2.AddTouches(cntrLeft);
                c2.AddTouches(cntrRight);
            }

            foreach (Corner q in App.AppMap.Corners.Values)
            {
                if (!q.Border)
                {
                    var point = new Point(0, 0);
                    foreach (Center c in q.Touches)
                    {
                        point.X += c.Point.X;
                        point.Y += c.Point.Y;
                    }
                    point.X = point.X / q.Touches.Count;
                    point.Y = point.Y / q.Touches.Count;
                    q.Point = point;
                }
            }

            //foreach (var c in App.AppMap.Centers)
            //{
            //    c.Value.FixBorders();
            //    c.SetEdgeAreas();
            //    c.Value.OrderCorners();
            //}

            IslandHandler.CreateIsland();
        }
Example #17
0
    public IslandTile (Vector c, VoronoiGraph g, Island isl)
    {
        island = isl;
        center = c;

        AddEdges(g);
    }
		/// <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[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 #19
0
        private void ImproveMapData(VoronoiGraph voronoiMap, bool fix = false)
        {
            IFactory fact = new MapItemFactory();

            foreach (VoronoiEdge edge in voronoiMap.Edges)
            {
                if (fix)
                {
                    if (!newFix(edge))
                        continue;
                }

                Corner c1 = fact.CornerFactory(edge.VVertexA[0], edge.VVertexA[1]);
                Corner c2 = fact.CornerFactory(edge.VVertexB[0], edge.VVertexB[1]);
                Center cntrLeft = fact.CenterFactory(edge.LeftData[0], edge.LeftData[1]);
                Center cntrRight = fact.CenterFactory(edge.RightData[0], edge.RightData[1]);

                c1.AddAdjacent(c2);
                c2.AddAdjacent(c1);

                cntrRight.AddCorner(c1);
                cntrRight.AddCorner(c2);

                cntrLeft.AddCorner(c1);
                cntrLeft.AddCorner(c2);

                Edge e = fact.EdgeFactory(c1, c2, cntrLeft, cntrRight);

                cntrLeft.AddBorder(e);
                cntrRight.AddBorder(e);

                cntrLeft.AddNeighbour(cntrRight);
                cntrRight.AddNeighbour(cntrLeft);

                c1.AddProtrudes(e);
                c2.AddProtrudes(e);
                c1.AddTouches(cntrLeft);
                c1.AddTouches(cntrRight);
                c2.AddTouches(cntrLeft);
                c2.AddTouches(cntrRight);
            }

            foreach (var c in App.AppMap.Centers)
            {
                c.Value.FixBorders();
                //c.SetEdgeAreas();
                c.Value.OrderCorners();
            }

            //IslandHandler.CreateIsland();
        }
		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
			Vector 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 = 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;
		}
        public static VoronoiGraph ComputeVoronoiGraph(IEnumerable Datapoints)
        {
            BinaryPriorityQueue PQ             = new BinaryPriorityQueue();
            Hashtable           CurrentCircles = new Hashtable();
            VoronoiGraph        VG             = new VoronoiGraph();
            VNode RootNode = null;

            foreach (Vector V in Datapoints)
            {
                PQ.Push(new VDataEvent(V));
            }
            while (PQ.Count > 0)
            {
                VEvent      VE = PQ.Pop() as VEvent;
                VDataNode[] CircleCheckList;
                if (VE is VDataEvent)
                {
                    RootNode = VNode.ProcessDataEvent(VE as VDataEvent, RootNode, VG, VE.Y, out CircleCheckList);
                }
                else if (VE is VCircleEvent)
                {
                    CurrentCircles.Remove(((VCircleEvent)VE).NodeN);
                    if (!((VCircleEvent)VE).Valid)
                    {
                        continue;
                    }
                    RootNode = VNode.ProcessCircleEvent(VE as VCircleEvent, RootNode, VG, VE.Y, out CircleCheckList);
                }
                else
                {
                    throw new Exception("Got event of type " + VE.GetType().ToString() + "!");
                }
                foreach (VDataNode VD in CircleCheckList)
                {
                    if (CurrentCircles.ContainsKey(VD))
                    {
                        ((VCircleEvent)CurrentCircles[VD]).Valid = false;
                        CurrentCircles.Remove(VD);
                    }
                    VCircleEvent VCE = VNode.CircleCheckDataNode(VD, VE.Y);
                    if (VCE != null)
                    {
                        PQ.Push(VCE);
                        CurrentCircles[VD] = VCE;
                    }
                }
                if (VE is VDataEvent)
                {
                    Vector DP = ((VDataEvent)VE).DataPoint;
                    foreach (VCircleEvent VCE in CurrentCircles.Values)
                    {
                        if (MathTools.Dist(DP[0], DP[1], VCE.Center[0], VCE.Center[1]) < VCE.Y - VCE.Center[1] && Math.Abs(MathTools.Dist(DP[0], DP[1], VCE.Center[0], VCE.Center[1]) - (VCE.Y - VCE.Center[1])) > 1e-10)
                        {
                            VCE.Valid = false;
                        }
                    }
                }
            }
            VNode.CleanUpTree(RootNode);
            foreach (VoronoiEdge VE in VG.Edges)
            {
                if (VE.Done)
                {
                    continue;
                }
                if (VE.VVertexB == Fortune.VVUnkown)
                {
                    VE.AddVertex(Fortune.VVInfinite);
                    if (Math.Abs(VE.LeftData[1] - VE.RightData[1]) < 1e-10 && VE.LeftData[0] < VE.RightData[0])
                    {
                        Vector T = VE.LeftData;
                        VE.LeftData  = VE.RightData;
                        VE.RightData = T;
                    }
                }
            }

            ArrayList MinuteEdges = new ArrayList();

            foreach (VoronoiEdge VE in VG.Edges)
            {
                if (!VE.IsPartlyInfinite && VE.VVertexA.Equals(VE.VVertexB))
                {
                    MinuteEdges.Add(VE);
                    // prevent rounding errors from expanding to holes
                    foreach (VoronoiEdge VE2 in VG.Edges)
                    {
                        if (VE2.VVertexA.Equals(VE.VVertexA))
                        {
                            VE2.VVertexA = VE.VVertexA;
                        }
                        if (VE2.VVertexB.Equals(VE.VVertexA))
                        {
                            VE2.VVertexB = VE.VVertexA;
                        }
                    }
                }
            }
            foreach (VoronoiEdge VE in MinuteEdges)
            {
                VG.Edges.Remove(VE);
            }

            return(VG);
        }
		public static VoronoiGraph ComputeVoronoiGraph(IEnumerable Datapoints)
		{
			BinaryPriorityQueue PQ = new BinaryPriorityQueue();
			Hashtable CurrentCircles = new Hashtable();
			VoronoiGraph VG = new VoronoiGraph();
			VNode RootNode = null;
			foreach(Vector V in Datapoints)
			{
				PQ.Push(new VDataEvent(V));
			}
			while(PQ.Count>0)
			{
				VEvent VE = PQ.Pop() as VEvent;
				VDataNode[] CircleCheckList;
				if(VE is VDataEvent)
				{
					RootNode = VNode.ProcessDataEvent(VE as VDataEvent,RootNode,VG,VE.Y,out CircleCheckList);
				}
				else if(VE is VCircleEvent)
				{
					CurrentCircles.Remove(((VCircleEvent)VE).NodeN);
					if(!((VCircleEvent)VE).Valid)
						continue;
					RootNode = VNode.ProcessCircleEvent(VE as VCircleEvent,RootNode,VG,VE.Y,out CircleCheckList);
				}
				else throw new Exception("Got event of type "+VE.GetType().ToString()+"!");
				foreach(VDataNode VD in CircleCheckList)
				{
					if(CurrentCircles.ContainsKey(VD))
					{
						((VCircleEvent)CurrentCircles[VD]).Valid=false;
						CurrentCircles.Remove(VD);
					}
					VCircleEvent VCE = VNode.CircleCheckDataNode(VD,VE.Y);
					if(VCE!=null)
					{
						PQ.Push(VCE);
						CurrentCircles[VD]=VCE;
					}
				}
				if(VE is VDataEvent)
				{
					Vector DP = ((VDataEvent)VE).DataPoint;
					foreach(VCircleEvent VCE in CurrentCircles.Values)
					{
						if(MathTools.Dist(DP[0],DP[1],VCE.Center[0],VCE.Center[1])<VCE.Y-VCE.Center[1] && Math.Abs(MathTools.Dist(DP[0],DP[1],VCE.Center[0],VCE.Center[1])-(VCE.Y-VCE.Center[1]))>1e-10)
							VCE.Valid = false;
					}
				}
			}
			VNode.CleanUpTree(RootNode);
			foreach(VoronoiEdge VE in VG.Edges)
			{
				if(VE.Done)
					continue;
				if(VE.VVertexB == Fortune.VVUnkown)
				{
					VE.AddVertex(Fortune.VVInfinite);
					if(Math.Abs(VE.LeftData[1]-VE.RightData[1])<1e-10 && VE.LeftData[0]<VE.RightData[0])
					{
						Vector T = VE.LeftData;
						VE.LeftData = VE.RightData;
						VE.RightData = T;
					}
				}
			}
			
			ArrayList MinuteEdges = new ArrayList();
			foreach(VoronoiEdge VE in VG.Edges)
			{
				if(!VE.IsPartlyInfinite && VE.VVertexA.Equals(VE.VVertexB))
				{
					MinuteEdges.Add(VE);
					// prevent rounding errors from expanding to holes
					foreach(VoronoiEdge VE2 in VG.Edges)
					{
						if(VE2.VVertexA.Equals(VE.VVertexA))
							VE2.VVertexA = VE.VVertexA;
						if(VE2.VVertexB.Equals(VE.VVertexA))
							VE2.VVertexB = VE.VVertexA;
					}
				}
			}
			foreach(VoronoiEdge VE in MinuteEdges)
				VG.Edges.Remove(VE);

			return VG;
		}