diff --git a/src/cd.py b/src/cd.py
new file mode 100644
index 0000000000000000000000000000000000000000..f375ee9bc8d96c493910201c1f49d92e601dfa17
--- /dev/null
+++ b/src/cd.py
@@ -0,0 +1,361 @@
+#/usr/bin/python
+
+import math
+from scanutil import ccw
+
+#
+# test to implement convexdivide by Tommy Persson
+#
+
+# Input list of vertices
+
+# list of index for site vertices.
+
+#
+# from http://stackoverflow.com/questions/451426/how-do-i-calculate-the-surface-area-of-a-2d-polygon
+# 
+
+#
+# site thingy when making ccw
+#
+# site info in result? Is it always an index?
+#
+
+def area(p):
+    return 0.5 * abs(sum(x0*y1 - x1*y0
+                         for ((x0, y0), (x1, y1)) in segments(p)))
+
+def segments(p):
+    return zip(p, p[1:] + [p[0]])
+
+#
+# End of area computation
+#
+
+
+#
+# From http://www.toptal.com/python/computational-geometry-in-python-from-theory-to-implementation
+#
+
+#def ccw(A, B, C):
+#    """Tests whether the turn formed by A, B, and C is ccw"""
+#    return (B.x - A.x) * (C.y - A.y) > (B.y - A.y) * (C.x - A.x)
+
+def intersect(a1, b1, a2, b2):
+    """Returns True if line segments a1b1 and a2b2 intersect."""
+    return ccw(a1, b1, a2) != ccw(a1, b1, b2) and ccw(a2, b2, a1) != ccw(a2, b2, b1)
+
+def is_convex(area):
+    res = True
+    for i in range(len(area)):
+        j = (i + 1) % len(area)
+        k = (i + 2) % len(area)
+        print i, j, k
+        if not ccw(area[i], area[j], area[k]):
+            res = False
+    return res
+
+def seg_length(p, i):
+    i1 = (i+1) % len(p)
+    return math.sqrt((p[i][0]-p[i1][0])*(p[i][0]-p[i1][0])+(p[i][1]-p[i1][1])*(p[i][1]-p[i1][1]))
+
+def poly_length(p):
+    res = 0.0
+    for i in range(len(p)):
+        res += seg_length(p, i)
+#        print "POLY_LENGTH:", i, res
+    return res
+
+def point_on_segment(p, i, length):
+    # in ccw direction, p is ccw
+    slen = seg_length(p, i)
+    i1 = (i+1) % len(p)
+    dx = p[i1][0]-p[i][0]
+    dy = p[i1][1]-p[i][1]
+    x = p[i][0] + dx * length/slen
+    y = p[i][1] + dy * length/slen
+    return (x, y)
+
+def move_cw(p, frac):
+    l = poly_length(p)
+    flen = l*frac
+    index = len(p)-1
+    slen = seg_length(p, index)
+#    print "SLEN:", slen, flen, index, l, frac
+    while slen < flen:
+#        print "MOVE_CW", index, slen, flen
+        index -= 1
+        flen -= slen
+        slen = seg_length(p, index)
+#    print "INDEX:", index, flen, slen-flen
+    p1 = point_on_segment(p, index, slen-flen)
+#    print "P1", p1, index
+    return p1, index
+
+def move_ccw(p, frac):
+    l = poly_length(p)
+    flen = l*frac
+    index = 0
+    slen = seg_length(p, index)
+#    print "SLEN:", slen, flen, index, l, frac, p
+    while slen < flen:
+#        print "MOVE_CW", index, slen, flen, p
+        index += 1
+        flen -= slen
+        slen = seg_length(p, index)
+#    print "INDEX:", index, flen, slen
+    p1 = point_on_segment(p, index, flen)
+#    print "P1", p1, index
+    return p1, index
+
+def make_ccw(area, w, s):
+    if ccw(area[0], area[1], area[2]):
+        return area, w, s
+    else:
+        a1 = list(reversed(area))
+        el = a1.pop()
+        a1.insert(0, el)
+        w1 = list(reversed(w))
+        el = w1.pop()
+        s1 = []
+        for site in s:
+            s1.append((len(w)-site) % len(w))
+        s1.sort()
+        w1.insert(0, el)
+        return a1, w1, s1
+
+#
+#
+#
+
+def get_area(w, start, end):
+    p = []
+    for i in range(start, end+1):
+#        print "I:", i
+        p.append(w[i])
+    return area(p)
+
+def get_requested_area(index, areareq, totarea):
+    res = 0.0
+    for i in range(0, index+1):
+        res += areareq[i]*totarea
+    return res
+
+def area_lt(a0, a1):
+    return a0 < a1
+
+def area_gt(a0, a1):
+    return a0 > a1
+
+def area_eq(a0, a1):
+    if math.fabs(a0-a1) < 0.2:
+        return True
+    else:
+        return  False
+
+def get_split_polygon(p, si, new_point, new_point_index):
+#    print "GET_SPLIT_POLYGON P:", p, si, new_point, new_point_index
+    a = p[0:si+1]
+    a.append(new_point)
+    a += p[new_point_index+1:]
+#    print "GET_SPLIT_POLYGON:", a
+    return a
+
+def get_split_polygon_ccw(p, si, new_point, new_point_index):
+#    print "GET_SPLIT_POLYGON CCW:", p, si, new_point, new_point_index
+    a = []
+    a.append(new_point)
+    a += p[new_point_index+1:si+1]
+#    print "GET_SPLIT_POLYGON:", a
+    return a
+
+def get_split_polygon_remain(p, si, new_point, new_point_index):
+#    print "GET_SPLIT_POLYGON P:", p, si, new_point, new_point_index
+    a = p[si:new_point_index+1]
+    a.append(new_point)
+#    print "GET_SPLIT_POLYGON_REMAIN:", a
+    return a
+
+def get_split_polygon_remain_ccw(p, si, new_point, new_point_index):
+#    print "GET_SPLIT_POLYGON_REMAIN_CCW:", p, si, new_point, new_point_index
+    a = p[0:new_point_index+1]
+    a.append(new_point)
+    a += p[si:]
+#    print "GET_SPLIT_POLYGON_REMAIN_CCW:", a
+    return a
+
+#
+# p is ths polygon
+# si is index in p for the endpoint of the line
+# new_point is the new point introduced
+# new point index is the index of the vertice before the new point
+# The area to compute is the one to the right of the line
+#
+#
+def get_splitarea(p, si, new_point, new_point_index):
+    a = get_split_polygon(p, si, new_point, new_point_index)
+    ar = area(a)
+#    print "SPLITAREA", ar, a
+    return ar
+        
+def get_splitarea_ccw(p, si, new_point, new_point_index):
+    a = get_split_polygon_ccw(p, si, new_point, new_point_index)
+    ar = area(a)
+#    print "SPLITAREA", ar, a
+    return ar
+        
+
+def convex_divide(ar, w, sites, areareq, totarea):
+    print "CONVEX_DIVIDE:", ar, w, sites, areareq, totarea
+    #
+    # Result after one iteration in w_r, w_l, sites_r, sites_l
+    #
+    w_r = []
+    w_l = []
+    sites_r = []
+    sites_l = []
+#    print "TOTAREA:", totarea
+    siteindex = 0
+    windex = sites[siteindex]
+    reqarea = get_requested_area(siteindex, areareq, totarea)
+#    print "REQ AREA:", reqarea
+    while get_area(w, 0, windex) < reqarea and windex != sites[-1]:
+#        print "AREA LESS: ", windex, get_area(w, 0, windex), reqarea
+        if windex > 0:
+            if windex in sites:
+                siteindex = sites.index(windex)
+                reqarea = get_requested_area(siteindex, areareq, totarea)
+#                print "REQ AREA CHANGED:", reqarea
+        windex += 1
+#    print "WINDEX:", windex
+    if windex == sites[0] and get_area(w, 0, windex) > reqarea:
+        print "Move L_s CCW along PLR"
+        n = 10000
+        for i in range(n):
+            p, index = move_ccw(ar, i*1.0/n)
+            a = get_splitarea_ccw(ar, sites[0], p, index)
+#            print "RES:", p, index, i*1.0/n, a, reqarea
+            if area_eq(a, reqarea):
+                print "FOUND", a, reqarea, p, index
+                w_r = get_split_polygon_ccw(ar, sites[0], p, index)
+                sites_r = [sites[0]]
+                w_l = get_split_polygon_remain_ccw(ar, sites[0], p, index)
+                sites_l = [x-(sites[0]-index-2) for x in sites[1:]]
+                areq_r = []
+                areq_l = [x/(1-areareq[0]) for x in areareq[1:]]
+                break
+    elif windex == sites[-1] and get_area(w, 0, windex) < reqarea:
+        print "Move L_s CW along PLR"
+        n = 10000
+        for i in range(n):
+            p, index = move_cw(ar, i*1.0/n)
+            a = get_splitarea(ar, sites[-1], p, index)
+#            print "RES:", p, index, i*1.0/n, a, reqarea
+            if area_eq(a, reqarea):
+                print "FOUND", a, reqarea, p, index
+                w_r = get_split_polygon(ar, sites[-1], p, index)
+                sites_r = sites[0:-1]
+                w_l = get_split_polygon_remain(ar, sites[-1], p, index)
+                sites_l = [0]
+                areq_r = [x/(1-areareq[-1]) for x in areareq[:-1]]
+                areq_l = []
+                break
+    else:
+        print "INTERPOLATE"
+        index = windex -1
+        slen = seg_length(w, index)
+        n = 3000
+        for i in range(n):
+            le = (1-i*1.0/n)*slen
+            p = point_on_segment(w, index, le)
+#            print "POINT:", p
+            poly = w[0:index+1]
+            poly.append(p)
+            a = area(poly)
+#            print "RES:", p, index, i*1.0/n, a, reqarea
+            if area_eq(a, reqarea):
+                print "FOUND", a, reqarea, p, index
+                w_r = poly
+                sites_r = sites[0:index-1]
+                w_l = w[0:1]
+                w_l.append(p)
+                w_l += w[index+1:]
+                sites_l = [x-(index-1) for x in sites[index-1:]]
+                areq_r = [x/(1-sum(areareq[index-1:])) for x in areareq[0:index-1:]]
+                areq_l = [x/(1-sum(areareq[0:index-1])) for x in areareq[index-1:]]
+                break
+
+
+    print "w_r - sites_r:", w_r, " - ", sites_r, areq_r
+    print "w_l - sites_l:", w_l, " - ", sites_l, areq_l
+
+    # Fix area request
+
+    if len(sites_r) == 1:
+        right = [w_r, sites_r]
+    else:
+        right = [w_r, sites_r]
+        ##        right = convex_divide(w_r, w_r, sites_r
+
+    if len(sites_l) == 1:
+        left = [w_l, sites_l]
+    else:
+        left = [w_l, sites_l]
+        ##        right = convex_divide(w_r, w_r, sites_r
+
+    return [right, left]
+
+if __name__ == "__main__":
+    p = [(0, 0), (5,1), (5,8), (0,8)]
+    w = [(0, 0), (5,1), (5,8), (0,8)]
+    sites = [0, 2]
+
+    p2 = [(0, 0), (5,1), (5,8), (2.5, 10), (0,8)]
+    w2 = [(0, 0), (5,1), (5,8), (2.5, 10), (0,8)]
+    sites2 = [3, 4]
+
+    p1 = [(0, 0), (0, 8), (5,8), (5,1)]
+    w1 = [(0, 0), (0, 8), (5,8), (5,1)]
+    sites1 = [0, 1]
+
+    print "P1:", p1
+    print "W1:", w1
+    print "S1:", sites1
+
+    p1, w1, sites1 = make_ccw(p1, w1, sites1)
+
+    print "P1:", p1
+    print "W1:", w1
+    print "S1:", sites1
+
+    print "AREA P:", area(p)
+    #print "AREA PR:", area(pr)
+
+
+    print "IS_CONVEX", is_convex(p)
+    #print "IS_CONVEX", is_convex(pr)
+    #print "IS_CONVEX", is_convex(prr)
+
+    line = [[0, 0], [5,0], [8,0]]
+    print "AREA:", area(line)
+    print "IS_CONVEX", is_convex(line)
+
+    print "AREA3", get_area(p, 0, 2)
+
+    res = convex_divide(p, p, [0, 2], [0.5, 0.5], area(p))
+    print "RES:", res
+
+    res = convex_divide(p2, w2, sites2, [0.5, 0.5], area(p2))
+    print "RES:", res
+    
+    res = convex_divide(p1, w1, sites1, [0.5, 0.5], area(p1))
+    print "RES:", res
+
+    p3 =  [(0.0, 0.0), (10.0, 5.0), (7.2457566807008842, 5.6885608298247785), (-2.0, 8.0), (-4.0, 2.0)]
+    res = convex_divide (p3, p3, [0, 2], [0.5, 0.5], area(p3))
+    print "RES:", res
+
+
+    #print "LEN P:", poly_length(p)
+    #p1, index = move_cw(p, 0.5)
+    #print "MOVE_CW:", p1, index
diff --git a/src/genpoint.py b/src/genpoint.py
new file mode 100644
index 0000000000000000000000000000000000000000..c3d7c080e6e872b0c4d139c619264ba8d878c9df
--- /dev/null
+++ b/src/genpoint.py
@@ -0,0 +1,151 @@
+#!/usr/bin/python
+import math
+import matplotlib.pyplot as plt
+import matplotlib.patches as patches
+import matplotlib as mpl
+import numpy as np
+from scipy.optimize import fsolve
+from scipy.optimize import newton
+
+pi = 3.1415926535897932384626433832795028841971
+
+def genpoint(point, theta, line, coverage):
+    #print "THIS IS DEFINITELY HERE, MAYBE"
+   # print "GENPOINT point:", point
+    print "GENPOINT theta:", theta
+    print "GENPOINT line: y = ", line(1)-line(0), '*x+', line(0)
+   # print "GENPOINT coverage:", coverage
+
+    if theta > 2*pi:
+        theta = theta - 2*pi
+    #Gets the angle of the line and adjusts it so it lies in the interval [0,pi]
+    lineangle = math.atan2(line(1)-line(0), 1)
+    if lineangle<0:
+        lineangle = lineangle + pi
+
+    #Generates the path associates with the angle and point and a function for the intersection
+    path = lambda x: math.tan(theta)*(x-point[0]) + point[1]
+    fn = lambda x: path(x) - line(x)
+
+    fnprime = lambda x: fn(1)-fn(0)
+    fnprime2 = lambda x: 0
+    #The intersec coordinates is the intersection of the line and the path
+#    x_intersec = newton(fn, 0, fprime=fnprime, fprime2=fnprime2)
+    x_intersec = newton(fn, 0, fprime=fnprime)
+#    x_intersec = x_intersec[0]
+    y_intersec = line(x_intersec)
+    #print '1st xy-intersec', x_intersec, y_intersec
+
+    #The hypotenuse of the triangles associated with the path-intersection-point and the intersecting corner of the coverage-rectangle.
+    #print "theta: ", theta, "lineangle: ", lineangle
+    if theta==lineangle:
+        print "Lines are parallel! Theta:", theta, 'Lineangle:', lineangle
+    #print "THETA:", theta
+    #print "LINEANGLE:", lineangle
+    lefthyp = coverage[0]/(2*math.sin(theta-lineangle))
+    righthyp = coverage[0]/(2*math.sin(lineangle-theta))
+
+    #print 'righthyp:', righthyp
+
+    #A help function for getting for getting the corner points of the coverage-rectangle at the stopping coordinate.
+    def getcovcorners(corner, x_intersec, y_intersec):
+        if corner == 1:
+            covcorners = [(x_intersec, y_intersec),
+            (x_intersec-math.cos(theta)*coverage[1], y_intersec-math.sin(theta)*coverage[1]),
+            (x_intersec+math.sin(theta)*coverage[0]-math.cos(theta)*coverage[1],
+             y_intersec-math.cos(theta)*coverage[0]-math.sin(theta)*coverage[1]),
+            (x_intersec+math.sin(theta)*coverage[0], y_intersec-math.cos(theta)*coverage[0])]
+        elif corner == 2:
+            #'hello?'
+            covcorners=[(x_intersec, y_intersec),
+            (x_intersec-coverage[0]*math.sin(theta), y_intersec+coverage[0]*math.cos(theta)),
+            (x_intersec-coverage[0]*math.sin(theta)-coverage[1]*math.cos(theta),
+            y_intersec+coverage[0]*math.cos(theta)-math.sin(theta)*coverage[1]),
+            (x_intersec-math.cos(theta)*coverage[1], y_intersec-math.sin(theta)*coverage[1])]
+        else:
+            print "Error, input not allowed"
+        return covcorners
+
+    #If-block that handles the different cases associated with different angles and lines
+    if theta <= pi/2:
+        if lineangle - theta < pi/2 and lineangle - theta > 0:
+            x_intersec, y_intersec = x_intersec+righthyp*math.cos(lineangle), y_intersec+righthyp*math.sin(lineangle)
+            covcorners = getcovcorners(1,x_intersec,y_intersec)
+            #print "11"
+           # print 'xy-intersec, ', x_intersec, y_intersec
+        else:
+            x_intersec, y_intersec = (x_intersec-righthyp*math.cos(lineangle), y_intersec-righthyp*math.sin(lineangle))
+            covcorners = getcovcorners(2,x_intersec,y_intersec)
+            #print "12"
+            #print 'x_intersec, y_intersec', x_intersec, y_intersec
+
+    elif theta <= pi:
+        if lineangle+pi-theta < pi/2 or lineangle + pi - theta > pi:
+            x_intersec, y_intersec = (x_intersec-lefthyp*math.cos(lineangle),y_intersec-lefthyp*math.sin(lineangle))
+            covcorners = getcovcorners(1,x_intersec,y_intersec)
+            #print "21"
+
+        else:
+            x_intersec, y_intersec = (x_intersec-lefthyp*math.cos(lineangle+pi), y_intersec-lefthyp *math.sin(lineangle+pi))
+            covcorners = getcovcorners(2,x_intersec,y_intersec)
+            #print "22"
+
+    elif theta <= 3*pi/2:
+        if lineangle+pi-theta < pi/2 and lineangle+pi-theta > 0:
+            x_intersec, y_intersec = (x_intersec-lefthyp*math.cos(lineangle),y_intersec-lefthyp*math.sin(lineangle))
+            covcorners = getcovcorners(1,x_intersec,y_intersec)
+            #print "31"
+
+        else:
+            x_intersec, y_intersec = (x_intersec-lefthyp*math.cos(lineangle+pi), y_intersec-lefthyp *math.sin(lineangle+pi))
+            covcorners = getcovcorners(2,x_intersec,y_intersec)
+            #print "32"
+
+    elif theta <= 2*pi:
+        if lineangle+pi-theta < -pi/2 or lineangle+pi-theta > 0:
+            x_intersec, y_intersec = x_intersec+righthyp*math.cos(lineangle), y_intersec+righthyp*math.sin(lineangle)
+            covcorners = getcovcorners(1,x_intersec,y_intersec)
+           # print "41"
+
+        else:
+            x_intersec, y_intersec = (x_intersec-righthyp*math.cos(lineangle), y_intersec-righthyp*math.sin(lineangle))
+            covcorners = getcovcorners(2,x_intersec,y_intersec)
+           # print "42"
+
+    else:
+        print "Angle is outside of allowed interval. Angle is :", theta
+
+
+
+    xway=[x[0] for x in covcorners]
+    yway=[y[1] for y in covcorners]
+    waypoint=(sum(xway)/4,sum(yway)/4)
+    print 'GENPOINT, waypoint:_', waypoint
+    return waypoint
+
+"""
+    #Block for testing this function, uncomment to confirm that it works.
+
+    fig = plt.figure()
+    ax = fig.add_subplot(111)
+    plt.plot([point[0], waypoint[0]],[point[1], waypoint[1]])
+    covcorners.append(covcorners[0])
+    plt.plot([x[0] for x in covcorners], [y[1] for y in covcorners])
+    plt.plot(range(-30,30), map(line, range(-30,30)))
+    plt.xlim(min(point[0]-1, waypoint[0]-coverage[0]-1), max(point[1]+1, waypoint[0]+coverage[0]+1))
+    plt.ylim(min(point[1]-1,waypoint[1]-coverage[1]-1), max(point[1]+1, waypoint[1]+coverage[1]+1))
+    plt.xlabel('x')
+    plt.ylabel('y')
+    plt.grid(True)
+    plt.show()
+
+
+
+
+
+pi = 3.1415926535897932384626433832795028841971
+
+#genpoint((0.7749, -1.847), 1.446, lambda x: 0.5*(x-2.0)+6.0, (0.5,0.1))
+
+"""
+
diff --git a/src/line.py b/src/line.py
new file mode 100644
index 0000000000000000000000000000000000000000..f0321d16a5183d4d1308f6c9b58e4ec4a8614466
--- /dev/null
+++ b/src/line.py
@@ -0,0 +1,125 @@
+import math
+
+
+#Returns line on standard form (Ax+By+C = 0)
+def line_from_point(A, B):
+    if A[0] == B[0] and A[1] == B[1]:
+        raise ValueError('A = B in line')
+    #print 'Creating line', A, ', ', B, ',', (A[1]-B[1]), '*x+', (B[0]-A[0]), 'y + ', A[0]*B[1]-A[1]*B[0]
+    return lambda x, y: (A[1]-B[1])*x+(B[0]-A[0])*y + A[0]*B[1]-A[1]*B[0]
+
+def line_from_angle(p, theta):
+    #print 'Used theta:', theta, ' to create', (p[0]+math.cos(theta), p[1]+math.sin(theta)), 'from p:', p
+    return line_from_point(p, (p[0]+math.cos(theta), p[1]+math.sin(theta)))
+
+def line_angle(L):
+    if L(0, 1)==L(0, 0):
+        return math.pi*0.5
+    else:
+        return math.atan(-(L(1, 0)-L(0, 0))/(L(0, 1)-L(0, 0)))
+
+def intersect(L_1, L_2):
+    C_1 = L_1(0, 0)
+    C_2 = L_2(0, 0)
+    A_1 = L_1(1, 0) - C_1
+    A_2 = L_2(1, 0) - C_2
+    B_1 = L_1(0, 1) - C_1
+    B_2 = L_2(0, 1) - C_2
+    #print 'L_1', A_1, B_1, C_1, 'L_2:', A_2, B_2, C_2
+    if A_1*B_2 == A_2*B_1:
+        #print 'Failure in generating intersection: L_1 and L_2 are parallel!'
+        raise ValueError('L_1, L_2 parallel')
+    else:
+        x_intersect = (B_2*C_1-B_1*C_2)/(B_1*A_2-B_2*A_1)
+        y_intersect = (A_2*C_1-A_1*C_2)/(A_1*B_2-A_2*B_1)
+    #print 'Intersection at:, ', (x_intersect, y_intersect)
+    return (x_intersect, y_intersect)
+
+def x_coeff(L):
+    return L(1, 0)-L(0,0)
+
+def y_coeff(L):
+    return L(0, 1)-L(0,0)
+
+
+def y(L):
+    if y_coeff(L) !=0:
+        return lambda x: -(x_coeff(L)/y_coeff(L))*x-L(0,0)/y_coeff(L)
+    else:
+        raise ValueError('Y arbitrary for L')
+
+def x(L):
+    if x_coeff(L) !=0:
+        return lambda y: -(y_coeff(L)/x_coeff(L))*y-L(0,0)/x_coeff(L)
+    else:
+        raise ValueError('X arbitrary for L') 
+
+def distance(a, b):
+    return math.sqrt((a[0]-b[0])**2+(a[1]-b[1])**2)
+
+def distance_squared(a,b):
+    return (a[0]-b[0])**2+(a[1]-b[1])**2
+
+def point_on_line(p, a, b):
+    #print p, a, b
+    epsilon = distance(a,b)*0.000001
+    #print 'POINT ON LINE?:', distance_squared(a,p)+distance_squared(b,p), distance_squared(a,b), epsilon
+    #print abs((distance(a,p)+distance(b,p)) - distance(a,b)) < epsilon
+    return abs((distance(a,p)+distance(b,p)) - distance(a,b)) < epsilon
+
+
+#does not work properly for negative values?
+#point_on_line can be used instead
+def point_approx_in(p, a, b):
+    eps = 0.000001
+    if p[0] <= min((1-eps)*a[0], (1-eps)*b[0], (1+eps)*a[0], (1+eps)*b[0]):
+        return False
+    elif p[0] >= max((1-eps)*a[0], (1-eps)*b[0], (1+eps)*a[0], (1+eps)*b[0]):
+        return False
+    elif p[1] <= min((1-eps)*a[1], (1-eps)*b[1], (1+eps)*a[1], (1+eps)*b[1]):
+        return False
+    elif p[1] >= max((1-eps)*a[1], (1-eps)*b[1], (1+eps)*a[1], (1+eps)*b[1]):
+        return False
+    else:
+        return True
+
+def signed_area(polygon):
+    area = 0
+    for i in range(0, len(polygon)-1):
+        area += 0.5 * (polygon[i+1][0]-polygon[i][0])*(polygon[i+1][1]+polygon[i][0])
+    return area
+
+
+
+def centre(polygon):
+    centre = [0, 0]
+    for i in range(0, len(polygon)):
+        centre[0] += polygon[i][0]/len(polygon)
+        centre[1] += polygon[i][1]/len(polygon)
+    return (centre[0], centre[1])
+
+def angle_from_points(a, b):
+    return math.atan2(a[1]-b[1],a[0]-b[0])
+
+def counterclockwise(polygon):
+    for i in range(0, len(polygon)):
+        p = [polygon[i-2], polygon[i-1], polygon[i]]
+        if signed_area(p) < 0:
+            #print 'not clockwise:', p
+            #print signed_area(p)
+            return False
+    return True
+
+#Sorts a list of coordinates p, if the coordinates are tied to something that can be sorted too
+def sort_ccw(p, something=False):
+    c = centre(p)
+    for i in range(0, len(p)):
+        for j in range(1, len(p)-i):
+            if angle_from_points(p[j], c) < angle_from_points(p[j-1], c):
+                p[j-1], p[j] =  p[j], p[j-1]
+                if something:
+                    something[j-1], something[j] = something[j], something[j-1]
+    if something:
+        return p, something
+    else:
+        return p
diff --git a/src/partitioningclient.py b/src/partitioningclient.py
index 2a46ca0ea626ce9131c6be4fac03958aabf82a49..6284c1fa2a04f633ab4488a484b0e9966a1f93c5 100755
--- a/src/partitioningclient.py
+++ b/src/partitioningclient.py
@@ -5,7 +5,7 @@ import sys
 import time
 import os
 
-from lrs_srvs.srv import *
+from lrs_scan_msgs.srv import *
 from geometry_msgs.msg import *
 
 from optparse import OptionParser
@@ -16,7 +16,7 @@ parser.add_option ("-t", "--test", action="store", type="int", dest="testcase",
 
 def get_partitioning (ns, polygon, sites, area_req):
     try:
-        client = rospy.ServiceProxy(ns + "scanserver/get_partitioning", SPGetPartitioning)
+        client = rospy.ServiceProxy(ns + "partitioningserver/get_partitioning", SPGetPartitioning)
         resp = client (polygon, sites, area_req)
     except rospy.ServiceException, e:
         print "Service call failed: %s"%e
diff --git a/src/partitioningserver.py b/src/partitioningserver.py
index 036224390d7f7371c9c4a2804b9d6e31fe72101c..4fbcdbcfd7886f55aeaa7666a4827d652751e80d 100755
--- a/src/partitioningserver.py
+++ b/src/partitioningserver.py
@@ -79,14 +79,14 @@ def get_partitioning(data):
     polygon = [(p.x, p.y) for p in data.polygon]
     sites = [(p.x, p.y) for p in data.sites]
     areareq = [x for x in data.area_request]
-    print "scanserver POLYGON", polygon
-    print "scanserver SITES", sites
-    print "scanserver AREAREQ", areareq
+    print "partitioningserver POLYGON", polygon
+    print "partitioningserver SITES", sites
+    print "partitioningserver AREAREQ", areareq
     part.set_polygon (polygon)
     part.set_sites(sites)
 #    return SPGetPartitioningResponse([], True, 0, "")
     areas = part.partition(areareq)
-    print "scanserver AREAS", areas
+    print "partitioningserver AREAS", areas
     res = []
     for a in areas:
         pa = PointArray()
@@ -111,7 +111,7 @@ if __name__ == "__main__":
 
     ns = rospy.get_namespace ()
 
-    s = rospy.Service('scanserver/get_partitioning', SPGetPartitioning, get_partitioning)
+    s = rospy.Service('partitioningserver/get_partitioning', SPGetPartitioning, get_partitioning)
 
     print "Partitioning server spinning..."
 
diff --git a/src/robust_convexdivide.py b/src/robust_convexdivide.py
new file mode 100644
index 0000000000000000000000000000000000000000..adc82c16b0b6692508d58f577c1b81a5ec5b237a
--- /dev/null
+++ b/src/robust_convexdivide.py
@@ -0,0 +1,357 @@
+'''
+Created on Jul 14, 2014
+
+@author: aleer
+
+Algorithm developed by Susan Hert.  See her paper called Polygon Area
+Decomposition for Multiple-Robot workspace division for more details.
+
+'''
+
+from copy import *
+from scanutil import check_and_fix, index_of_point
+import matplotlib.pyplot as plt
+import matplotlib.patches as patches
+import matplotlib as mpl
+import copy
+from line import *
+from scipy.optimize import fsolve as fsolve
+
+
+#Gets the area of a set of points (ordered in counterclockwise order)
+#that make up a polygon. If the points are in a clockwise order the
+#area returned is negative, so this function can be used to determine
+#the orientation of the points
+def getarea(poly):
+    poly.append(poly[0])
+    area=0
+    for i in range(0, len(poly)-1):
+        area = area+(poly[i][0]*poly[i+1][1]-poly[i][1]*poly[i+1][0])/2.0
+    del poly[len(poly)-1]
+    #print 'GETPOLY points:', poly, 'with area:', area
+    return area
+
+
+#Helperfunction that calculates the new unknown shared cornerpoint for the smaller polygons
+def getpolypoint(points, maxindex, reqarea, change):
+##    points = check_and_fix(points0)
+    #print "CONVEXDIVIDE GETPOLYPOINT:", points, maxindex, reqarea, change
+    g=0
+    within = False
+    while not within:
+        if change == 'ccw':
+            #print 'ccw'
+            g = g+1
+            #y = lambda x: (points[g][1]-points[g-1][1])/(points[g][0]-points[g-1][0])*(x-points[g-1][0])+points[g-1][1]
+            l = line_from_point(points[g], points[g-1])
+
+            #function that helps us generate the areafunction by
+            #calculating the area of the known points
+            ahelp = 0
+            for i in range(g+1, maxindex+1):
+                ahelp = ahelp + points[i-1][0]*points[i][1] - points[i-1][1]*points[i][0]
+
+            #Generates the area function, with an unknown point that
+            #is then calculated using the desired area.
+            if abs(y_coeff(l)) > 0.001: 
+                area = lambda x: (x*points[g][1] - y(l)(x)*points[g][0] + points[maxindex][0]*y(l)(x) - points[maxindex][1]*x + ahelp)/2.0 - reqarea
+                intersect = (fsolve(area, 1)[0], y(l)(fsolve(area, 1)[0]))
+                if (intersect[0] >= min(points[g][0], points[g-1][0]) and intersect[0] <= max(points[g][0], points[g-1][0])):
+                    within = True
+            else:
+                #print '\n !!!!!---THAT JUST HAPPENED: ccw---!!!!! \n'
+                area = lambda y: (-l(0,0)/x_coeff(l)*points[g][1] - y*points[g][0] + points[maxindex][0]*y + points[maxindex][1]*l(0,0)/x_coeff(l)+ahelp)/2.0-reqarea
+                intersect = (-l(0,0)/x_coeff(l), fsolve(area, 1)[0])
+                if (intersect[1] >= min(points[g][1], points[g-1][1]) and intersect[1] <= max(points[g][1], points[g-1][1])):
+                    within = True
+           
+            #print 'intersect!: ', intersect, 'points!: ', points[g], points[g-1]
+            
+
+            #print 'g', g, within
+
+        elif change == 'cw':
+            #print 'cw'
+            g = g-1
+            #y = lambda x: (points[g][1]-points[g+1][1])/(points[g][0]-points[g+1][0])*(x-points[g+1][0])+points[g+1][1]
+            #print 'g', g, g+1, len(points)
+            l = line_from_point(points[g], points[g+1])
+
+            ahelp = 0
+            for i in range(g+2, maxindex+1):
+                ahelp = ahelp + points[i-1][0]*points[i][1] - points[i-1][1]*points[i][0]
+            #print 'ahelp, maxindex:', ahelp/2.0, maxindex
+            if abs(y_coeff(l)) > 0.001:
+                area = lambda x: (x*points[g+1][1] - y(l)(x)*points[g+1][0] + points[maxindex][0]*y(l)(x) - points[maxindex][1]*x + ahelp)/2.0 - reqarea
+                intersect = (fsolve(area, 1)[0], y(l)(fsolve(area, 1)[0]))
+                #print 'y(l)(fsol...):', y(l)(fsolve(area,1)[0])
+                #print area(intersect[0])
+                if (intersect[0] >= min(points[g][0], points[g+1][0]) and intersect[0] <= max(points[g][0], points[g+1][0])):
+                    within = True
+                    #print l, 'reqarea', reqarea
+                    #print (lambda x: area(x)+reqarea)(intersect[0])
+            else:
+                #print '\n !!!!!---THAT JUST HAPPENED: cw---!!!!! \n'
+                area = lambda y: (-l(0,0)/x_coeff(l)*points[g+1][1] - y*points[g+1][0] + points[maxindex][0]*y + points[maxindex][1]*l(0,0)/x_coeff(l)+ahelp)/2.0-reqarea
+                intersect = (-l(0,0)/x_coeff(l), fsolve(area, 1)[0])
+                if (intersect[1] >= min(points[g][1], points[g+1][1]) and intersect[1] <= max(points[g][1], points[g+1][1])):
+                    within = True
+                    #print l, 'reqarea', reqarea
+                    #print (lambda x: area(x)+reqarea)(intersect[0])
+                
+            #print 'intersect!: ', intersect, 'points!: ', points[g], points[g+1], l
+            
+
+        elif change == 'line0':
+            #print 'l0'
+            #y = lambda x: (points[maxindex][1]-points[maxindex+1][1])/(points[maxindex][0]-points[maxindex+1][0])*(x-points[maxindex+1][0])+points[maxindex+1][1]
+            l = line_from_point(points[maxindex], points[maxindex+1])
+            #print '---L0---', points[maxindex], points[maxindex+1], y_coeff(l)
+            #print (points[maxindex][1]-points[maxindex+1][1])/(points[maxindex][0]-points[maxindex+1][0]), '*(x-', points[maxindex+1][0], ')+', points[maxindex+1][1]
+            ahelp = 0
+            for i in range(1, maxindex+1):
+                ahelp = ahelp + points[i-1][0]*points[i][1] - points[i-1][1]*points[i][0]
+            if abs(y_coeff(l)) > 0.00001:
+                area = lambda x: (x*points[0][1] - y(l)(x)*points[0][0] + points[maxindex][0]*y(l)(x) - points[maxindex][1]*x + ahelp)/2.0 - reqarea
+                intersect = (fsolve(area, 1)[0], y(l)(fsolve(area, 1)[0]))
+            else:
+                #print '\n !!!!!---THAT JUST HAPPENED: l0---!!!!! \n'
+                area = lambda y: (-l(0,0)/x_coeff(l)*points[0][1] - y*points[0][0] + points[maxindex][0]*y + points[maxindex][1]*l(0,0)/x_coeff(l)+ahelp)/2.0-reqarea
+                intersect = (-l(0,0)/x_coeff(l), fsolve(area, 1)[0])
+            
+
+            #print 'intersect!: ', intersect, 'points!: ', points[maxindex], points[maxindex+1]
+            within=True
+
+
+        else:
+            print 'Invalid change-input.'
+    #print "CONVEXDIVIDE GETPOLYPOINT:", points, maxindex, reqarea, change, " -> ", intersect, g
+    return intersect, g
+
+def remove_non_vertices(polygon):
+    p = deepcopy(polygon)
+    for i in range(len(p)-1, -1, -1):
+        if p[i][0] == p[i-1][0] and p[i][1] == p[i-1][1]:
+            #print 'removing:', p[i], 'because equal to', p[i-1]
+            p.pop(i)
+        elif point_on_line(p[i-1], p[i], p[i-2]):
+            #print 'removing:', p[i-1], 'because on linesegment(', p[i], ',', p[i-2], ')'
+            p.pop(i-1)
+    return p
+    
+
+
+def convexdividesub(points0, sites0, areareq):
+    points = [(x[0], x[1]) for x in points0]
+    siteindex = [index_of_point(points, sites0[i]) for i in range(0, len(sites0))]
+    #points = check_and_fix(points)
+    sites = [points[s] for s in siteindex]
+
+    #print 'POINTS:', points, 'SITES:', sites
+    k = points.index(sites[0])
+    print 'k and stuff', k, sites, 'points\n\n', points, 'siteindex', siteindex
+    ## k = index_of_point(points, sites[0])
+    line = (points[0], points[k])
+    rightsites = [sites.index(sites[0]),]
+    polyright = points[0:k+1]
+    polyleft = points[k:]
+    polyleft.append(points[0])
+    # for h in range(0, len(areareq)):
+    #        areareq[h] = areareq[h] * getarea(points)
+
+    #plt.plot([x[0] for x in points], [y[1] for y in points])
+    #plt.plot([points[0][0], points[k][0]], [points[0][1], points[k][1]])
+        #plt.plot([x[0] for x in polyright] +[polyright[0][0]] + [x[0] for x in polyleft] + [polyleft[0][0]], \
+        #         [y[1] for y in polyright] + [polyright[0][1]] + [y[1] for y in polyleft] + [polyleft[0][1]])
+    #plt.show()
+    #We create a line with endpoints in the first vertex and the first
+    #site, we then move the second endpoint around the polygon until
+    #either the area on the right side of the line is larger than the
+    #desired area or we can no longer sweep any further without
+    #getting all the sites on the same side of the line.
+    while getarea(polyright) < sum([areareq[item] for item in rightsites]) and not (points[k]==sites[len(sites)-1]):
+        """print 'CHECKING IF', points[k-1], 'IN RIGHTSITES'
+        if (k > 1) and (points[k-1] in sites) and not sites.index(points[k-1]) in rightsites:
+            rightsites.append(sites.index(points[k-1]))
+            print 'APPENDING ', points[k-1], 'TO RIGHTSITES'"""
+
+        k = k + 1
+        #print 'CHECKING IF', points[k-1], 'IN RIGHTSITES'
+        if (k > 1) and (points[k-1] in sites) and not sites.index(points[k-1]) in rightsites:
+            rightsites.append(sites.index(points[k-1]))
+            #print 'APPENDING ', points[k-1], 'TO RIGHTSITES'
+
+        line = (points[0], points[k])
+        #print line[1]
+        polyright = points[0:k+1]
+        #print 'polyright', polyright
+        polyleft = points[k:]
+        polyleft.append(points[0])
+        #plt.plot([x[0] for x in points], [y[1] for y in points])
+        #plt.plot([points[0][0], points[k][0]], [points[0][1], points[k][1]])
+        #plt.plot([x[0] for x in polyright] +[polyright[0][0]] + [x[0] for x in polyleft] + [polyleft[0][0]], \
+        #         [y[1] for y in polyright] + [polyright[0][1]] + [y[1] for y in polyleft] + [polyleft[0][1]])
+        #plt.show()
+    
+
+    #If the area of the side to the right of the line is greater than
+    #the desired area we instead sweep by moving the first point in a
+    #counter-clockwise order.
+    if line[1] == sites[0] and getarea(polyright) > sum([areareq[item] for item in rightsites]):
+        print 'ccw, sites, points', sites, points
+        intersect, offset = getpolypoint(points, points.index(sites[0]), sum([areareq[item] for item in rightsites]), 'ccw')
+        for l in range(1, offset):
+            polyleft.append(polyright[l])
+        print 'deleting:', polyright[0:offset]
+        del polyright[0:offset]
+        #print 'ccw', offset
+        polyright.insert(0, intersect)
+        polyleft.append(intersect)
+
+    #If the second point on the line is the same as the last site and
+    #the area to the right of the line is lesser than the desired area
+    #we move the first point clockwise around the polygon.
+    elif line[1] == sites[len(sites)-1] and getarea(polyright) < sum([areareq[item] for item in rightsites]):
+        print 'cw, sites, rareq, points: ', sites,[areareq[item] for item in rightsites],  points
+        #print 'l0', line[0]
+        intersect, offset = getpolypoint(points, points.index(sites[len(sites)-1]), sum([areareq[item] for item in rightsites]), 'cw')
+        offset = (-1)*offset
+        polyleft.pop()
+        for l in range(1, offset):
+            polyright.insert(0, polyleft.pop())
+        polyright.insert(0, intersect)
+        #print 'cw, left, right', offset, polyleft, polyright
+        polyleft.append(intersect)
+
+    #If we are not in any of the above cases the area to the right of
+    #the line is greater than desired, and there exist a point between
+    #point[k] and [k-1] such that if we replace the second point of
+    #the line with it we get the desired area.
+    else:
+        intersect, _ = getpolypoint(points, points.index(line[1])-1, sum([areareq[item] for item in rightsites]), 'line0')
+        #print polyright, rightsites
+        if intersect not in polyright:
+            polyright[k] = intersect
+        #print polyright
+        print 'l0, sites, points', sites, points
+        #print 'line0'
+        #print polyleft
+        if intersect not in polyleft:
+            polyleft.insert(0, intersect)
+        #print polyleft
+
+    rareareq = [areareq[item] for item in rightsites]
+
+
+    #Up until now we stored the indexes of the sites in rightsites,
+    #but as an output we'd rather just give the actual site backs.
+    #print "NEWSITES rightsites index:", rightsites, sites
+    rightsites = [sites[item] for item in rightsites]
+    leftsites = [sites[item] for item in range(0, len(sites)) if not sites[item] in rightsites]
+    lareareq = [areareq[item] for item in range(0, len(sites)) if not sites[item] in rightsites]
+
+    #print 'NEWSITES LEFT AND RIGHT SITES', leftsites, rightsites
+    #We restore the area requirement to the way it was input in and
+    #divide it into two sets, one for each new polygon.  for j in
+    #range(0, len(areareq)): areareq[j]=areareq[j] / getarea(points)
+    #print 'PLEFT LSITES LAREAREQ', polyleft, leftsites, lareareq,
+    #print 'RRIGHT RSITES RAREAREQ', polyright, rightsites, rareareq
+
+    print 'leftsites:\n', leftsites, 'rightsites:\n', rightsites
+    return polyleft, polyright, leftsites, rightsites, lareareq, rareareq
+
+
+#takes a set of points in counterclockwise order (the vertices and the
+#sites), the sites in counterclockwise order and the arearequirements
+#of the sites as an input. Returns the input split into two.
+
+def convexdivide(points0, sites0, areareq_in):
+    points = [(x[0], x[1]) for x in copy.deepcopy(points0)]
+    for i in range(len(points)-1, -1, -1):
+        if (points[i] == points[i-1]):
+            points.pop(i)
+
+    sites = copy.deepcopy(sites0)
+    print 'cd input:', points0, sites0, areareq_in
+
+    totarea = getarea(points)
+    areareq = copy.deepcopy(areareq_in)
+    for h in range(0, len(areareq)):
+        areareq[h] = areareq[h]*totarea
+
+    #main
+    newsites = [deepcopy(sites)]
+    newpoints = [deepcopy(points)]
+    newareq = [deepcopy(areareq)]
+
+    while len(newsites)<(len(sites)):
+        for j in range(0, len(newsites)):
+            if len(newsites[j])>1:
+                pleft, pright, sleft, sright, lareareq, rareareq = convexdividesub(newpoints[j], newsites[j], newareq[j])
+
+                newsites[j] = sright
+                newsites.insert(j+1, sleft)
+
+                newpoints[j] = pright
+                newpoints.insert(j+1, pleft)
+                newareq[j] = rareareq
+                newareq.insert(j+1, lareareq)
+
+    try:
+        newsites = [item[0] for item in newsites]
+    except:
+        print 'Newsites failure:', newsites
+        print '\n\npoints:', points0
+        print '\n\nsites:', sites0
+        raise ValueError('FODA-SE')
+
+    parts = []
+    for i in range(0, len(newpoints)):
+        parts.append(remove_non_vertices(newpoints[i]))
+    print 'newsites', newsites
+    return parts, newsites
+
+#polygon = [(0.0, 0.0), (3.0, 2.0), (2.0, 5.0), (-3.0, 4.0), (-4.0, 3.0), (-2, 1.0)]
+
+"""
+points =  [[0.0, 0.0], [10.0, 5.0], [-2.0, 8.0], [-4.0, 2.0]]
+sites = [[0.0, 0.0], [10.0, 5.0]]
+areareq = [0.5, 0.5]
+
+
+
+newpoints, newsites, areareq = convexdivide(points, sites, areareq)
+
+print newpoints
+
+#print 'newpoints:', newpoints,
+#print 'newsites:', newsites, 'newpoints', newpoints
+
+for h in range(0, len(areareq)):
+    print areareq[h], getarea(newpoints[h])
+
+fig = plt.figure()
+ax = fig.add_subplot(111)
+#pright.append(pright[0])
+#pleft.append(pleft[0])
+
+points.append(points[0])
+plt.plot([x[0] for x in points], [y[1] for y in points])
+
+for k in range(0, len(newpoints)):
+    newpoints[k].append(newpoints[k][0])
+    plt.plot([x[0] for x in newpoints[k]], [y[1] for y in newpoints[k]])
+#plt.plot([x[0] for x in pright], [y[1] for y in pright], [x[0] for x in pleft], [y[1] for y in pleft])
+
+
+#plt.plot(range(-30,30), map(line, range(-30,30)))
+#plt.xlim(min(point[0]-1, waypoint[0]-coverage[0]-1), max(point[1]+1, waypoint[0]+coverage[0]+1))
+#plt.ylim(min(point[1]-1,waypoint[1]-coverage[1]-1), max(point[1]+1, waypoint[1]+coverage[1]+1))
+plt.xlabel('x')
+plt.ylabel('y')
+plt.grid(True)
+plt.show()
+
+"""
+
diff --git a/src/scan/__init__.py b/src/scan/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..ba30b7a0d117066d866ee2a82f432da499b44ecd
--- /dev/null
+++ b/src/scan/__init__.py
@@ -0,0 +1 @@
+__all__ = ["partition"]
diff --git a/src/scanutil.py b/src/scanutil.py
new file mode 100644
index 0000000000000000000000000000000000000000..98b0599da3539060d6b7187edc2de6238b40b2ed
--- /dev/null
+++ b/src/scanutil.py
@@ -0,0 +1,150 @@
+import copy
+
+import numpy as np
+import math
+
+def check_and_fix(poly):
+    #Fixes div-by-zero errors
+    polygon = copy.deepcopy(poly)
+    for i in range(0, len(polygon)):
+        if polygon[i][0] == 0 and polygon[i-1] == 0:
+            polygon[i][0] = 0.001
+        elif polygon[i][0] == polygon[i-1][0]:
+            print 'addressing divzero for, polygon[', i,']', polygon[i]
+            polygon[i] = (polygon[i][0]*1.0001, polygon[i][1])
+            #print 'polygon[',i,'] is now', polygon[i]
+    return polygon
+
+def ccw(A, B, C):
+    """Tests whether the turn formed by A, B, and C is ccw"""
+    return (B[0] - A[0]) * (C[1] - A[1]) > (B[1] - A[1]) * (C[0] - A[0])
+
+# true if p is betweem p0 and p1
+# def ccw_between(p0, p1, p):
+
+# project vector a on vector b
+# proj.x = ( (a.x*b.x + a.y*b.y) / (b.x*b.x + b.y*b.y) ) * b.x;
+# proj.y = ( (a.x*b.x + a.y*b.y) / (b.x*b.x + b.y*b.y) ) * b.y;
+# http://en.wikipedia.org/wiki/Dot_product
+# http://en.wikipedia.org/wiki/Vector_projection
+
+def project_point_on_line(p0, p1, p):
+    a = (p[0]-p0[0], p[1]-p0[1])
+    b = (p1[0]-p0[0], p1[1]-p0[1])
+#    print "A, B:", a, b
+    dot = (float(a[0]*b[0] + a[1]*b[1])) / float((b[0]*b[0] + b[1]*b[1]))
+#    print "DOT:", dot
+    x = dot * b[0]
+    y = dot * b[1]
+#    print "X, Y:", x, y
+    return (x + p0[0], y + p0[1])
+
+def is_point_on_segment(p0, p1, p):
+    x0 = min(p0[0], p1[0])
+    y0 = min(p0[1], p1[1])
+    x1 = max(p0[0], p1[0])
+    y1 = max(p0[1], p1[1])
+#    print "IS_POINT_ON_SEGMENT:", x0, x
+    if (p[0] >= x0) and (p[0] <= x1) and (p[1] >= y0) and (p[1] <= y1):
+        return True
+    else:
+        return False
+
+def get_nearest_corner(polygon, p):
+##    print "PROJJJJ: get_nearest_corner:", polygon, p
+    dists = []
+    for point in polygon:
+        dists.append ((p[0]-point[0])*(p[0]-point[0])+(p[1]-point[1])*(p[1]-point[1]))
+    i = np.argmin(dists)
+    return polygon[i], i
+
+def snap_point_to_corner(polygon, p):
+    p, i = get_nearest_corner(polygon, p)
+    return p
+
+def project_point_with_index(poly0, point):
+    poly = [(float(x[0]), float(x[1])) for x in poly0]
+    points = []
+    dists = []
+    index = []
+    for i in range(0,len(poly)):
+        j = (i + 1) % len(poly)
+        p = project_point_on_line(poly[i], poly[j], point)
+##        print "PROJJJJ:", i, poly[i], poly[j], p
+        if is_point_on_segment(poly[i], poly[j], p):
+##            print "PROJJJJ POINT ON SEGMENT:", i, poly[i], poly[j], p
+            points.append (p)
+            dists.append ((p[0]-point[0])*(p[0]-point[0])+(p[1]-point[1])*(p[1]-point[1]))
+            index.append(i)
+
+    if len(points) > 0:
+##        print "PROJJJJ: POINTS, DISTS, INDEX:", point, dists, index
+        i = np.argmin(dists)
+        return points[i], index[i]
+    else:
+        return get_nearest_corner(poly, point)
+
+def project_point(poly, point):
+    p, index = project_point_with_index(poly, point)
+    return p
+
+def near_equal(x, y):
+    return math.fabs(x-y)<0.00000001
+
+def equal_points(p0, p1):
+    return near_equal(p0[0], p1[0]) and near_equal(p0[1], p1[1])
+
+def index_of_point(l, p):
+    for i, pp in enumerate(l):
+        if equal_points(p, pp):
+            return i
+    return -1
+
+def remove_point(l, p):
+    i = index_of_point(l, p)
+    if i >= 0:
+        l.pop(i)
+
+def count_point_occ(l, p):
+    res = 0
+    for pp in l:
+        if equal_points(p, pp):
+            res += 1
+    return res
+
+def merge_polygon_sites(poly, startp):
+    polygon = [(x[0], x[1]) for x in poly]
+    startpoints = [(x[0], x[1]) for x in startp]
+
+    sites = []
+    sites_index = []
+
+    verbose = False
+
+    if verbose:
+        print "MERGE_POLYGON_SITES polygon", polygon
+        print "MERGE_POLYGON_SITES start points", startpoints
+
+    # original code removed an element if previous element was the same from polygon
+    # can that happen?
+
+    for uav in range(len(startpoints)):
+        #            p, i = projectpoint_with_index(sitehelp, startpoints[uav], False)
+        p, i = project_point_with_index(polygon, startpoints[uav])
+        sites.append(p)
+        sites_index.append(i)
+
+    if verbose:
+        print "MERGE SITES (projected startpoints):", sites
+        print "MERGE SITES_INDEX (projected startpoints):", sites_index
+
+    offset = 0
+    for si, i in enumerate(sites_index):
+        polygon.insert(i+offset+1, sites[si])
+        offset += 1
+    if verbose:
+        print "MERGED POLYGON", polygon
+
+    return polygon, sites
+
+