Test association now colours in all sites. The site edges are now sorted in order. Edge has a flip function which reverses left and right site points.
Test association now colours in all sites. The site edges are now sorted in order. Edge has a flip function which reverses left and right site points.

--- a/test-association.py
+++ b/test-association.py
@@ -21,5 +21,5 @@
     y=random.uniform(0,height)
     points.append((x,y))
 
-unittests.run_test_association(points,points[0],width,height)
+unittests.run_test_association(points,points,width,height)
 

--- a/unittests.py
+++ b/unittests.py
@@ -2,6 +2,7 @@
 import voronoi
 import cv,cv2
 import tools
+import random
 
 # Useful functions
 def toint(t2):
@@ -41,23 +42,31 @@
 #  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):
+def run_test_association(points,plot_points,width,height):
     # Init open CV
     cv.NamedWindow('testwin')
 
     img = numpy.zeros((height,width, 1), numpy.uint8)
     
+    v=voronoi.Voronoi(points,width,height)
+
+    for point in plot_points:
+        polygon=[]
+    
+        for edge in v.sites[point]:
+            edge=tools.img_coords(edge,width,height)
+            if edge==None:
+                continue
+
+            polygon.append(edge[0])
+            polygon.append(edge[1])
+
+        color=random.randint(150,255)
+        cv2.fillPoly(img,numpy.array([polygon],'int32'),color)
+
+    # Stuff
     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)

file:a/voronoi.py -> file:b/voronoi.py
--- a/voronoi.py
+++ b/voronoi.py
@@ -1,5 +1,6 @@
 #!/usr/bin/env python
 
+import sys
 import random
 from math import *
 from heapq import *
@@ -44,13 +45,26 @@
         self.normal=(self.normal[0]/A,self.normal[1]/A)
         self.direction=(-self.normal[1],self.normal[0])
 
+    def flip(self):
+        edge=Edge(self.r,self.rp,self.lp)
+        if self.start==None: edge.end=None
+        else: edge.end=-self.start
+        if self.end==None: edge.start=None
+        else: edge.start=-self.end
+
+        return edge
+
     def value(self,t):
         return (self.value_x(t),self.value_y(t))
 
     def value_x(self,t):
+        if t==None:
+            return None
         return self.direction[0]*t+self.r[0]
 
     def value_y(self,t):
+        if t==None:
+            return None
         return self.direction[1]*t+self.r[1]
 
     def intersects_with(self,edge):
@@ -440,6 +454,42 @@
             self.edges.append(edge)
             self.sites[edge.lp].append(edge)
             self.sites[edge.rp].append(edge)
+            
+        new_sites={}
+        for site in self.sites:
+            edges=self.sites[site]
+            new_edges=[]
+            # Step 1: Correctly orient edges such that lp is always the site
+            for edge in edges:
+                if edge.lp!=site:
+                    edge=edge.flip()
+                new_edges.append(edge)
+
+            # Step 2: Find the first edge (aka one that starts at inifinity, or 
+            # random if no such edge exists).
+            first_edge=new_edges[0]
+            for edge in new_edges:
+                if edge.start==None:
+                    first_edge=edge
+                    break
+
+			# Step 3: Find subsequent edges
+            self.sites[site]=[first_edge]
+            new_edges.remove(first_edge)
+            last_end=first_edge.value(first_edge.end)
+            while len(new_edges)!=0:
+                for edge in new_edges:
+                    start=edge.value(edge.start)
+                    if (start[0]-last_end[0])**2+(start[1]-last_end[1])**2<sys.float_info.epsilon:
+                        last_end=edge.value(edge.end)
+                        new_edges.remove(edge)
+                        self.sites[site].append(edge)
+                        break
+
+
+
+            new_sites[site]=new_edges
+            
  
     def remove_event(self,event):
         for entry in self.events: