def VORONOI2(points, Amat=np.zeros((0, 2)), bvec=np.zeros(0)):
    """
    get the voronoi partition of the set { x : A x \leq b } (assume closed),
    generated by points
    """
    # Approach: per point, just get all equations in play...
    # then, do edge enumeration!

    # [DN] get Delaunay neighbors graph
    # [DN.1] triangulate
    tri = spatial.Delaunay(points)
    graph = nx.Graph()
    # [DN.2] find the edges in the triangulation
    indices, seq = tri.vertex_neighbor_vertices
    for i, pt in enumerate(tri.points):
        for j in seq[indices[i] : indices[i + 1]]:
            graph.add_edge(i, j)

    def Abij(i, j):
        # gets the jth row of Ai, bi, describing ith voronoi cell
        xi = np.array(tri.points[i])
        xj = np.array(tri.points[j])
        aij = 2.0 * (xj - xi)
        bij = np.sum(np.power(xj, 2.0)) - np.sum(np.power(xi, 2.0))
        return aij, bij

    def Abi(i):
        # gets (A,b) of the ith voronoi cell
        rows = [Abij(i, j) for j in graph.neighbors_iter(i)]
        AA = np.vstack([a for a, b in rows])
        bb = np.array([b for a, b in rows])

        AA = np.vstack([AA, Amat])  # augment with bbox
        bb = np.hstack([bb, bvec])
        return celim.eliminate_redundant_constraints(AA, bb)

    res = [None for i in xrange(len(points))]
    for i in graph.nodes_iter():
        Ai, bi = Abi(i)
        res[i] = geom2.poly2_topology(*sys)

    return res
def VORONOI2(points, Amat=np.zeros((0, 2)), bvec=np.zeros(0)):
    """
    get the voronoi partition of the set { x : A x \leq b } (assume closed),
    generated by points
    """
    # Approach: per point, just get all equations in play...
    # then, do edge enumeration!

    # [DN] get Delaunay neighbors graph
    # [DN.1] triangulate
    tri = spatial.Delaunay(points)
    graph = nx.Graph()
    # [DN.2] find the edges in the triangulation
    indices, seq = tri.vertex_neighbor_vertices
    for i, pt in enumerate(tri.points):
        for j in seq[indices[i]:indices[i + 1]]:
            graph.add_edge(i, j)

    def Abij(i, j):
        # gets the jth row of Ai, bi, describing ith voronoi cell
        xi = np.array(tri.points[i])
        xj = np.array(tri.points[j])
        aij = 2. * (xj - xi)
        bij = np.sum(np.power(xj, 2.)) - np.sum(np.power(xi, 2.))
        return aij, bij

    def Abi(i):
        # gets (A,b) of the ith voronoi cell
        rows = [Abij(i, j) for j in graph.neighbors_iter(i)]
        AA = np.vstack([a for a, b in rows])
        bb = np.array([b for a, b in rows])

        AA = np.vstack([AA, Amat])  # augment with bbox
        bb = np.hstack([bb, bvec])
        return celim.eliminate_redundant_constraints(AA, bb)

    res = [None for i in xrange(len(points))]
    for i in graph.nodes_iter():
        Ai, bi = Abi(i)
        res[i] = geom2.poly2_topology(*sys)

    return res
if __name__ == "__main__":
    import matplotlib.pyplot as plt

    plt.close("all")

    import geom2

    # generators
    points = [np.random.rand(2) for i in xrange(10)]
    # bounding box
    A, b = geom2.box2()
    # voronoi cell ineq. representations
    sys = VORONOI(points, A, b)
    # topologies
    TOPO = [geom2.poly2_topology(A, b) for A, b in sys]

    plt.figure()

    X, Y = geom2.get_xy(points)
    plt.scatter(X, Y, marker="x")
    for topo in TOPO:
        pos = {}
        for u, data in topo.nodes_iter(data=True):
            pos[u] = data.get("pos")

        nx.draw(topo, pos=pos)

    ax = plt.gca()
    ax.set_aspect("equal")
    plt.show()

if __name__ == '__main__':
    import matplotlib.pyplot as plt
    plt.close('all')

    import geom2

    # generators
    points = [np.random.rand(2) for i in xrange(10)]
    # bounding box
    A, b = geom2.box2()
    # voronoi cell ineq. representations
    sys = VORONOI(points, A, b)
    # topologies
    TOPO = [geom2.poly2_topology(A, b) for A, b in sys]

    plt.figure()

    X, Y = geom2.get_xy(points)
    plt.scatter(X, Y, marker='x')
    for topo in TOPO:
        pos = {}
        for u, data in topo.nodes_iter(data=True):
            pos[u] = data.get('pos')

        nx.draw(topo, pos=pos)

    ax = plt.gca()
    ax.set_aspect('equal')
    plt.show()