Sunflowers and traffic lights
It occurred to me the other day while looking at a set of LED traffic lights that they could be improved quite easily. The layout of the LEDs in all the ones I've seen seems to favour some radial directions over others and/or result in a higher concentration of bulbs at some radii than at others.
My solution involves placing LEDs a increasing distances from the centre and as each LED is placed rotating by the golden angle. This ensures that no radial direction is preferred over any other. In addition to this, setting $r_n = \sqrt{n}$ ensures that each bulb covers a roughly similar area.
By "area covered" I am referring to the portion of space which is closer to that bulb than to any other. This is the Voronoi cell generated by a point belonging to a set of points. The picture above shows the Voronoi cells generated by a set of LEDs placed in the manner described, and the code below shows how I obtained it. I think it would make a pretty stain glass window!
#!/usr/bin/env python2 import matplotlib.colors import matplotlib.cm import matplotlib.pyplot as plt import matplotlib.patches as patches from scipy.spatial import Voronoi from math import sin, cos, pi from random import random # Define the constants found in nature phi = .5+.5*(5**.5) theta_golden = 2*pi/(phi**2) # Find leaf centres which are used as Voronoi cell generators leaf_centres = [] for i in range(1,400): # r should be sqrt(i) so that each cell is roughly same area r = i**.5 #r = i theta = theta_golden * i x,y = r*cos(theta), r*sin(theta) leaf_centres.append((x,y)) # Set up the plot parameters plt.ion() ax = plt.gca() ax.set_aspect('equal') plt.tick_params(axis='x', which='both', bottom=False, top=False, labelbottom=False) plt.tick_params(axis='y', which='both', left=False, right=False, labelleft=False) xs = map(lambda (x,y):x, leaf_centres) ys = map(lambda (x,y):y, leaf_centres) xlim = (min(xs) * 1.1, max(xs) * 1.1) ylim = (min(ys) * 1.1, max(ys) * 1.1) ax.set_xlim(*xlim) ax.set_ylim(*ylim) # Calculate the Voronoi cells v = Voronoi(leaf_centres) # Plot cells using a random colours from the 'hot_r' heatmap norm = matplotlib.colors.Normalize(vmin=-.5,vmax=2,clip=True) cmap = matplotlib.cm.cmap_d['hot_r'] for region in v.regions: # Skip cells around the outside which are open and so not polygons if -1 in region: continue # Skip region if it has too few vertices to be a polygon if len(region) < 3: continue # Find vertices of polygon region.append(region[0]) xs = v.vertices[region,0] ys = v.vertices[region,1] # Skip outside polygon if too far from the centre rs = (xs*xs + ys*ys)**.5 if max(rs) > xlim[1] or max(rs) > ylim[1]: continue # Plot polygon with black outline and random fill colour vs = zip(xs,ys) rgb = cmap(norm(random())) poly = patches.Polygon(vs, color=rgb) ax.add_patch(poly) plt.plot(xs, ys, lw=1, color='black') # hang around raw_input('Press any key to close')
The following picture shows what you get if you replace the $r_n = \sqrt{n}$ rule with $r_n = n$. The cell sizes now get larger as you go further out, but the spiral arms are easier to see. I'm not sure which I prefer...
There's an anecdote about Voronoi cells which I find quite interesting. Apparently the 19th century statistician John Snow used these to demonstrate that the vector for Cholera was infected drinking water. He used the set of public water pumps in London as the cell generators and showed that the affected population corresponded to those living or working within certain cell boundaries. He explained this by saying that a) in general everyone travels to the nearest pump to drink, and b) it was drinking from an infected pump that caused people to contract the disease.
POST-POSTSCRIPT
I wondered what the fixed cell area design would look like if it was painted onto a globe rather than printed onto a flat surface. The answer is obtained by replacing $r$ in the program with $\psi$, the angle from the pole. And the rule $r_n = \sqrt{n}$ becomes $\psi_n = cos^ {-1}\left(\frac{N-2n}{N}\right)$ where $N$ is the number of cells wanted. Projecting the result onto a 2D surface, with the pole centre, and generating Voronoi cells gives you a nice Sun like image:
Comments
Post a Comment