Voronoi Fun



  • I'm translating some existing codes to Drawbot to generate custom Voronoi SVG, and am looking for suggestions. I'm starting with bezier paths or polygons. What would you use? (Don't give away the answer yet! I may still ask for more help later in the week.)



  • Ok, maybe I need a bit more assistance. Not sure how the PIL library codes can be translated to drawbot's methods of creating images.
    https://rosettacode.org/wiki/Voronoi_diagram#Python

    This the the sample code I'm trying to translate to Drawbot:

    from PIL import Image
    import random
    import math
     
    def generate_voronoi_diagram(width, height, num_cells):
    	image = Image.new("RGB", (width, height))
    	putpixel = image.putpixel
    	imgx, imgy = image.size
    	nx = []
    	ny = []
    	nr = []
    	ng = []
    	nb = []
    	for i in range(num_cells):
    		nx.append(random.randrange(imgx))
    		ny.append(random.randrange(imgy))
    		nr.append(random.randrange(256))
    		ng.append(random.randrange(256))
    		nb.append(random.randrange(256))
    	for y in range(imgy):
    		for x in range(imgx):
    			dmin = math.hypot(imgx-1, imgy-1)
    			j = -1
    			for i in range(num_cells):
    				d = math.hypot(nx[i]-x, ny[i]-y)
    				if d < dmin:
    					dmin = d
    					j = i
    			putpixel((x, y), (nr[j], ng[j], nb[j]))
    	image.save("VoronoiDiagram.png", "PNG")
            image.show()
     
    generate_voronoi_diagram(500, 500, 25)
    


  • hello @bic,

    the PIL example in your second post creates a Voronoi diagram as a raster image. in DrawBot, raster images can be created from scratch using ImageObject.

    don’t forget that color coordinates in DrawBot are expressed as floats between 0.0 and 1.0, not as integers between 0 and 255 like in PIL. (so you’ll need to use random() instead of randrange(256) to generate the RGB color values)

    VoronoiDiagram.png

    it works 🙂 give it a try!



  • @gferreira Thanks! I was actually trying to generate a custom sized eps. Maybe this is the wrong approach. Matplotlib generates something similar very easily with the scipy.spatial libary...but ugly....



  • Voronoi is a lot of fun indeed. I gave scipy.spatial.Voronoi a try, and got it to work (sort of; some polygons are missing):

    voronoi-drawbot-2.png

    # based on http://stackoverflow.com/questions/27548363/from-voronoi-tessellation-to-shapely-polygons
    
    from random import randrange
    from scipy.spatial import Voronoi
    
    size(600, 300)
    
    pointsAmount = 160
    points = [(randrange(width()), randrange(height())) for i in range(pointsAmount)]
    
    V = Voronoi(points)
    regions = [V.vertices[line] for line in V.regions if -1 not in line]
    
    stroke(1)
    strokeWidth(2)
    for R in regions:
        pts = [(float(x), float(y)) for x, y in R]
        if len(pts):
            fill(random(), random(), 0.7, 0.7)
            polygon(*pts)
    
    r = 1
    stroke(None)
    fill(0)
    for x, y in points:
        oval(x-r, y-r, r*2, r*2)
    
    saveImage('voronoi-drawbot-2.png')
    

    and here is the bitmap version ported from PIL

    happy voronoiing!