public List <Vector2> generateRelaxed(int numPoints) { List <Vector2> points = new List <Vector2>(); //var mapRandom = new System.Random (seed); for (var i = 0; i < numPoints; i++) { points.Add(new Vector2(UnityEngine.Random.Range(10F, size - 10F), UnityEngine.Random.Range(10F, size - 10F))); } for (var i = 0; i < LOYDRELAXATIONS; i++) { var voronoi = new csDelaunay.Voronoi(points, new Rectf(0, 0, size, size)); for (var j = 0; j < points.Count; j++) { Vector2 p = points[j]; var region = voronoi.Region(p); float x = 0F; float y = 0F; foreach (Vector2 c in region) { x += c.x; y += c.y; } x /= region.Count; y /= region.Count; p.x = x; p.y = y; points[j] = p; } } return(points); }
public static List <Vector2f> RelaxPoints(List <Vector2f> startingPoints, Rectf rectf) { Voronoi v = new Voronoi(startingPoints, rectf); List <Vector2f> points = new List <Vector2f>(); for (int i = 0; i < startingPoints.Count; i++) { Vector2f point = startingPoints[i]; var region = v.Region(point); point.x = 0f; point.y = 0f; foreach (var r in region) { point.x = point.x + r.x; point.y = point.y + r.y; } point.x = point.x / region.Count; point.y = point.y / region.Count; points.Add(point); } return(points); }
public List<Vector2> generateRelaxed(int numPoints){ List<Vector2> points = new List<Vector2>(); //var mapRandom = new System.Random (seed); for (var i = 0; i < numPoints; i++) { points.Add(new Vector2(UnityEngine.Random.Range(10F, size-10F), UnityEngine.Random.Range(10F, size-10F))); } for (var i = 0; i < LOYDRELAXATIONS; i++) { var voronoi = new csDelaunay.Voronoi(points,new Rectf(0,0,size,size)); for (var j = 0; j < points.Count; j++){ Vector2 p = points[j]; var region = voronoi.Region(p); float x = 0F; float y = 0F; foreach (Vector2 c in region){ x += c.x; y += c.y; } x /= region.Count; y /= region.Count; p.x = x; p.y = y; points[j] = p; } } return points; }
// Build graph data structure in 'edges', 'centers', 'corners', // based on information in the Voronoi results: point.neighbors // will be a list of neighboring points of the same type (corner // or center); point.edges will be a list of edges that include // that point. Each edge connects to four points: the Voronoi edge // edge.{v0,v1} and its dual Delaunay triangle edge edge.{d0,d1}. // For boundary polygons, the Delaunay edge will have one null // point, and the Voronoi edge may be null. public void buildGraph(List <Vector2> points, csDelaunay.Voronoi voronoi) { Center p; var centerLookup = new Dictionary <Vector2, Center> (); var libedges = voronoi.Edges; // Build Center objects for each of the points, and a lookup map // to find those Center objects again as we build the graph foreach (var point in points) { p = new Center(); p.index = centers.Count; p.point = point; p.neighbors = new List <Center>(); p.borders = new List <Edge>(); p.corners = new List <Corner>(); centers.Add(p); centerLookup[point] = p; } // Workaround for Voronoi lib bug: we need to call region() before Edges or neighboringSites are available foreach (var c in centers) { voronoi.Region(c.point); } // The Voronoi library generates multiple Point objects for // corners, and we need to canonicalize to one Corner object. // To make lookup fast, we keep an array of Points, bucketed by // x value, and then we only have to look at other Points in // nearby buckets. When we fail to find one, we'll create a new // Corner object. var _cornerMap = new Dictionary <int, List <Corner> > (); Func <Vector2, Corner> makeCorner = delegate(Vector2 point) { int bucket; if (point == Vector2.zero) { return(null); } for (bucket = (int)(point.x) - 1; bucket <= (int)(point.x) + 1; bucket++) { if (_cornerMap.ContainsKey(bucket)) { foreach (var c in _cornerMap[bucket]) { var dx = point.x - c.point.x; var dy = point.y - c.point.y; if (dx * dx + dy * dy < 1e-6F) { return(c); } } } } bucket = (int)point.x; if (!_cornerMap.ContainsKey(bucket)) { _cornerMap.Add(bucket, null); } if (_cornerMap[bucket] == null) { _cornerMap[bucket] = new List <Corner>(); } var q = new Corner(); q.index = corners.Count; corners.Add(q); q.point = point; q.border = (point.x == 0F || point.x == SIZE || point.y == 0F || point.y == SIZE); q.touches = new List <Center> (); q.protrudes = new List <Edge> (); q.adjacent = new List <Corner> (); _cornerMap[bucket].Add(q); return(q); }; // Helper functions for the following for loop; Action <List <Corner>, Corner> addToCornerList = delegate(List <Corner> v, Corner x) { if (x != null && v.IndexOf(x) < 0) { v.Add(x); } }; Action <List <Center>, Center> addToCenterList = delegate(List <Center> v, Center x) { if (x != null && v.IndexOf(x) < 0) { v.Add(x); } }; foreach (var libedge in libedges) { var dedge = libedge.delaunayLine(); var vedge = libedge.voronoiEdge(); var edge = new Edge(); edge.index = edges.Count; edge.river = 0; edges.Add(edge); if (vedge.p0 != Vector2.zero && vedge.p1 != Vector2.zero) { edge.midpoint = Vector2.Lerp(vedge.p0, vedge.p1, 0.5F); } edge.v0 = makeCorner(vedge.p0); edge.v1 = makeCorner(vedge.p1); edge.d0 = centerLookup[dedge.p0]; edge.d1 = centerLookup[dedge.p1]; if (edge.d0 != null) { edge.d0.borders.Add(edge); } if (edge.d1 != null) { edge.d1.borders.Add(edge); } if (edge.v0 != null) { edge.v0.protrudes.Add(edge); } if (edge.v1 != null) { edge.v1.protrudes.Add(edge); } if (edge.d0 != null && edge.d1 != null) { addToCenterList(edge.d0.neighbors, edge.d1); addToCenterList(edge.d1.neighbors, edge.d0); } if (edge.v0 != null && edge.v1 != null) { addToCornerList(edge.v0.adjacent, edge.v1); addToCornerList(edge.v1.adjacent, edge.v0); } if (edge.d0 != null) { addToCornerList(edge.d0.corners, edge.v0); addToCornerList(edge.d0.corners, edge.v1); } if (edge.d1 != null) { addToCornerList(edge.d1.corners, edge.v0); addToCornerList(edge.d1.corners, edge.v1); } if (edge.v0 != null) { addToCenterList(edge.v0.touches, edge.d0); addToCenterList(edge.v0.touches, edge.d1); } if (edge.v1 != null) { addToCenterList(edge.v1.touches, edge.d0); addToCenterList(edge.v1.touches, edge.d1); } } }