Пример #1
0
        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);
        }
Пример #2
0
    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);
    }
Пример #3
0
        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);
            });
        }
Пример #4
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);
    }
Пример #5
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);
        }
Пример #6
0
        /*
         * 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));
        }
Пример #7
0
 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);
     }
 }
Пример #8
0
        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);
                }
            }
        }
Пример #9
0
	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);


    }
Пример #10
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;
	}
Пример #11
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);
            }
        }
    }