Voronoi.sites is now a dictionary of edges associated with each point. This can be tested by running test-association.py. Also a few internal API changes.
Voronoi.sites is now a dictionary of edges associated with each point. This can be tested by running test-association.py. Also a few internal API changes.

--- /dev/null
+++ b/test-association.py
@@ -1,1 +1,25 @@
+#!/usr/bin/python
 
+import random
+import time
+
+import unittests
+
+# Config 
+width=1000
+height=1000
+npoints=10
+#seed=1
+seed=int(time.time())
+
+# Voronoi
+points=[]
+random.seed(seed)
+print 'SEED',seed
+for i in range(0,npoints):
+    x=random.uniform(0,width)
+    y=random.uniform(0,height)
+    points.append((x,y))
+
+unittests.run_test_association(points,points[0],width,height)
+

--- a/unittests.py
+++ b/unittests.py
@@ -24,7 +24,6 @@
 
     v=voronoi.Voronoi(points,width,height)
     v.img=img
-    edges=v.edges
     for edge in v.edges:
         edge=tools.img_coords(edge,width,height)
         if edge==None:
@@ -36,3 +35,31 @@
     cv2.imshow("testwin",img)
     cv2.waitKey(0)
 
+# Test the ability to get the edges surrounding a point. It does the following:
+#  1) Creates a CV window named "testwin"
+#  2) Draw the points into it as tiny circles
+#  3) Draws the edges calculated by voronoi for the specified point
+#  4) Waits for a keystroke
+# The testwin is created based on passed width and height
+def run_test_association(points,point,width,height):
+    # Init open CV
+    cv.NamedWindow('testwin')
+
+    img = numpy.zeros((height,width, 1), numpy.uint8)
+    
+    for p in points:
+        cv2.circle(img,toint(p),2,255,-1)
+
+    v=voronoi.Voronoi(points,width,height)
+    v.img=img
+    for edge in v.sites[point]:
+        edge=tools.img_coords(edge,width,height)
+        if edge==None:
+            continue
+
+        cv2.line(img,edge[0],edge[1],255)
+
+    # Show results
+    cv2.imshow("testwin",img)
+    cv2.waitKey(0)
+

file:a/voronoi.py -> file:b/voronoi.py
--- a/voronoi.py
+++ b/voronoi.py
@@ -248,6 +248,10 @@
         self.width=width
         self.height=height
 
+        # Results are stored here
+        self.edges=[]
+        self.sites={}
+
         # Sort the points in x first
         self.points=[]
         for point in points:
@@ -257,10 +261,9 @@
                     insert=idx
                     break
             self.points.insert(insert,point)
+            self.sites[point]=[]
 
         # Run
-        self.edges=[]
-        self.sites={}
         self.run()
 
     def run(self):
@@ -288,7 +291,7 @@
             elif e.type==Event.TYPE_CIRCLE:
                 self.remove_parabola(e.parabola_node)
     
-        self.edges=self.finish_edges()
+        self.finish_edges()
 
     def add_parabola(self,point):
 #        print 'add_parabola',point
@@ -425,7 +428,6 @@
 #        self.root.dump_tree('remove_parabola_%s.dot'%str(parabola_node))
 
     def finish_edges(self):
-        edges=[]
         for edge in self.internal_edges:
             if type(edge)==tuple:
                 tmpedges=edge
@@ -435,8 +437,9 @@
                 else:
                     edge.start=-tmpedges[1].end
 
-            edges.append(edge)
-        return edges
+            self.edges.append(edge)
+            self.sites[edge.lp].append(edge)
+            self.sites[edge.rp].append(edge)
  
     def remove_event(self,event):
         for entry in self.events: