public int CompareTo(Site s1) { int returnValue = Voronoi.CompareByYThenX(this, s1); int tempIndex; if (returnValue == -1) { if (this.siteIndex > s1.SiteIndex) { tempIndex = this.SiteIndex; this.SiteIndex = s1.SiteIndex; s1.SiteIndex = tempIndex; } } else if (returnValue == 1) { if (s1.SiteIndex > this.SiteIndex) { tempIndex = s1.SiteIndex; s1.SiteIndex = this.SiteIndex; this.SiteIndex = tempIndex; } } return(returnValue); }
public void go(string pointType) { /* Place points... */ reset(); if (pointType == "Relaxed") { points = pointSelector.generateRelaxed(numPoints); } if (pointType == "Square") { points = pointSelector.generateSquare(numPoints); } if (pointType == "Hex") { points = pointSelector.generateHex(numPoints); } /* Build Graph... */ var voronoi = new csDelaunay.Voronoi(points, new Rectf(0, 0, SIZE, SIZE)); buildGraph(points, voronoi); voronoi.Dispose(); voronoi = null; points = null; improveCorners(); recalcGraph(true); }
public static void SortSites(List <Site> sites) { sites.Sort(delegate(Site s0, Site s1) { int returnValue = Voronoi.CompareByYThenX(s0, s1); int tempIndex; if (returnValue == -1) { if (s0.siteIndex > s1.SiteIndex) { tempIndex = s0.SiteIndex; s0.SiteIndex = s1.SiteIndex; s1.SiteIndex = tempIndex; } } else if (returnValue == 1) { if (s1.SiteIndex > s0.SiteIndex) { tempIndex = s1.SiteIndex; s1.SiteIndex = s0.SiteIndex; s0.SiteIndex = tempIndex; } } return(returnValue); }); }
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); }
/* * This is the only way to make a Vertex * * @param halfedge0 * @param halfedge1 * @return * */ public static Vertex Intersect(Halfedge halfedge0, Halfedge halfedge1) { Edge edge, edge0, edge1; Halfedge halfedge; float determinant, intersectionX, intersectionY; bool rightOfSite; edge0 = halfedge0.edge; edge1 = halfedge1.edge; if (edge0 == null || edge1 == null) { return(null); } if (edge0.RightSite == edge1.RightSite) { return(null); } determinant = edge0.a * edge1.b - edge0.b * edge1.a; if (Math.Pow(-1.0, 10) < determinant && determinant < Math.Pow(1.0, -10)) { // The edges are parallel return(null); } intersectionX = (edge0.c * edge1.b - edge1.c * edge0.b) / determinant; intersectionY = (edge1.c * edge0.a - edge0.c * edge1.a) / determinant; if (Voronoi.CompareByYThenX(edge0.RightSite, edge1.RightSite) < 0) { halfedge = halfedge0; edge = edge0; } else { halfedge = halfedge1; edge = edge1; } rightOfSite = intersectionX >= edge.RightSite.x; if ((rightOfSite && halfedge.leftRight == LR.LEFT) || (!rightOfSite && halfedge.leftRight == LR.RIGHT)) { return(null); } return(Vertex.Create(intersectionX, intersectionY)); }
static void Main() { for (int i = 0; i < 3; ++i) { List<Vector2f> vertices = new List<Vector2f>(); Random r = new Random(); for (int f = 0; f < 100000; ++f) { vertices.Add(new Vector2f(r.NextDouble() * 100, r.NextDouble() * 100)); } Stopwatch s = new Stopwatch(); s.Start(); var n = new Voronoi(vertices, new Rectf(0, 0, 100, 100), 1); s.Stop(); Console.WriteLine(s.ElapsedMilliseconds); } }
public void CalculatePolygons() { results.Clear(); // generate random points for Voronoi var points = new List<Vector2f>(); for (int i = 0; i < nPoints; ++i) { points.Add(new Vector2f(Random.Range(-maxSize, maxSize), Random.Range(-maxSize, maxSize))); } // perform Voronoi space division var voronoi = new Voronoi(points, new Rectf(-maxSize, -maxSize, maxSize * 2.0f, maxSize * 2.0f), lloydIters); // for each site (polygon) foreach (var kv in voronoi.SitesIndexedByLocation) { var location = kv.Key; var site = kv.Value; var distance = location.magnitude / maxSize; // if too far from the center -discard it if (DiscardByDistance(distance)) continue; // convert Site to Polygon var polygon = new Polygon(site); if (polygon.valid) { // make streets polygon.ShrinkAbs(streetWidthMid * 0.5f); var quartars = QuarterlyDivide(polygon); results.AddRange(quartars); } } }
public void go(string pointType){ /* Place points... */ reset(); if (pointType == "Relaxed") points = pointSelector.generateRelaxed(numPoints); if (pointType == "Square") points = pointSelector.generateSquare(numPoints); if (pointType == "Hex") points = pointSelector.generateHex(numPoints); /* Build Graph... */ var voronoi = new csDelaunay.Voronoi(points,new Rectf(0,0,SIZE,SIZE)); buildGraph(points, voronoi); voronoi.Dispose(); voronoi = null; points = null; improveCorners(); recalcGraph(true); }
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); } } }