예제 #1
0
    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);
    }
예제 #2
0
        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);
        }
예제 #3
0
    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;
	}
예제 #4
0
    // 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);
            }
        }
    }