Пример #1
0
def onebend(C):
    """
    Run unpublished Everett et al. one-bend layout.
    """
    G = C.graph
    from math import sqrt, ceil, floor
    from graph import DummyVertex, GraphError
    from utilities import colorsys


    # Position each vertex
    vertices = [x for x in G.vertices if not isinstance(x, DummyVertex)]

    n = len(vertices)
    sqrt_n = int(ceil(sqrt(n)))

    # All the silliness with _a vs. _i is to make the loop syntax cleaner
    # while still running loops from 1 to n rather than 0 to n-1.

    for _a in range(sqrt_n):
        a = _a + 1
        for _i in range(sqrt_n):
            i = _i + 1
            # Check for end of the array if we don't have a perfect
            # square number of vertices.
            if _a * sqrt_n + _i >= len(vertices):
                break
            v = vertices[_a * sqrt_n + _i]

            G.modVertex(v).pos = (20 * a, 10 * (a * sqrt_n + i), 0)
            G.modVertex(v).name = "v [%d, %d]" % (a, i)
            if DEBUG:
                print "positioning vertex %s at %s" % (v.name, [x / 10 for x in v.pos])


    # Connect all the vertices in K[n] with different X-coordinates.
    for _a in range(sqrt_n):
        a = _a + 1
        for _b in range(_a + 1, sqrt_n):
            b = _b + 1
            for _i in range(sqrt_n):
                i = _i + 1
                for _j in range(sqrt_n):
                    j = _j + 1
                    if _a * sqrt_n + _i >= len(vertices):
                        continue
                    if _b * sqrt_n + _j >= len(vertices):
                        continue
                    v = vertices[_a * sqrt_n + _i]
                    u = vertices[_b * sqrt_n + _j]

                    e = G.findEdgeBetween(v, u)
                    if not e:
                        # no edge between these vertices
                        continue
                    e = e[0]

                    z = 0
                    for l in range(sqrt_n - a):  # (- 1) + 1, to sum to the
                        # proper number
                        z = z + (sqrt_n * (2.0 * sqrt_n - 2 * a - 1) / (2 * l + 1))
                    z = z - i

                    bend = G.bendEdge(e,
                                      (
                                      10 * (2 * a + 1),  # 10 * (2 * a + i),
                                      10 * (b * sqrt_n + j),
                                      5 * z
                                      ))
                    # The z coordinates have been scaled down by half
                    # to make the drawing more compact and easier to
                    # navigate. To use "real" coordinates, change this to
                    # "10*z".
                    G.modVertex(bend).name = "e[%d,%d -> %d,%d]" % (a, i, b, j)
                    if DEBUG:
                        print "positioning bend %s at %s" % (bend.name, [x / 10 for x in bend.pos])
                    e = G.findEdgeBetween(v, u)[0]
                    G.modEdge(e).color = colorsys.hsv_to_rgb(float(a) / sqrt_n + float(i) / n,
                                                             (float(j) / sqrt_n) * 0.8 + 0.1, 0.8)

    # Connect all the vertices in K[n] with same X-coordinates.

    # Number of vertices in each chunk
    n_part = sqrt_n * (sqrt_n - 1) / 2

    for _a in range(sqrt_n):
        a = _a + 1
        chain = 0
        # Choose the stride of the chain we're working on
        for stride in range(sqrt_n):
            # Choose the offset of this chain (< stride).
            for offset in range(stride):
                # Traverse the links of the chain and insert
                # bend points in the correct position.
                i = 0
                while True:
                    if offset + i + stride >= sqrt_n:
                        break
                    if _a * sqrt_n + offset + i + stride >= n:
                        break
                    u = vertices[_a * sqrt_n + offset + i]
                    v = vertices[_a * sqrt_n + offset + i + stride]

                    e = G.findEdgeBetween(v, u)
                    if e == []:
                        # no edge between these vertices
                        i = i + stride
                        continue
                    e = e[0]

                    # We might already have bent this edge.
                    if e.type() != "edge":
                        i = i + stride
                        continue

                    bend = G.bendEdge(e, (u.pos[0] + 10, u.pos[1], -10 * chain))

                    G.modVertex(bend).name = "x[%d,%d,%d,%d]" % (a, stride, offset, i)

                    if DEBUG:
                        print "positioning bend %s at %s" % (bend.name, [x / 10 for x in bend.pos])
                    e = G.findEdgeBetween(u, v)[0]
                    G.modEdge(e).color = colorsys.hsv_to_rgb(float(stride) / sqrt_n, 0.8, 0.4)
                    i = i + stride
                chain = chain + 1
    return
Пример #2
0
def onebend(C):
    """
    Run one-bend layout.
    As per "Three-Dimensional 1-Bend Graph Drawings", Morin and Wood (2004)
    """
    G = C.graph
    from math import ceil, floor, log, pow
    from graph import DummyVertex, GraphError
    from utilities import colorsys


    # Grab a list of regular vertices.
    vertices = [x for x in G.vertices if not isinstance(x, DummyVertex)]

    n = len(vertices)

    # Calculate P and Q.
    P = ceil(log(n, 4))
    Q = int(ceil(n / P))
    P = int(P)
    print "P: %d Q: %d" % (P, Q)

    # All the silliness with _a vs. _i is to make the loop syntax cleaner
    # while still running loops from 1 to n rather than 0 to n-1.

    for _a in range(P):
        a = _a + 1
        for _i in range(Q):
            i = _i + 1
            # Check for end of the array if we don't have exactly enough
            # vertices
            if _a * Q + _i >= len(vertices):
                break
            v = vertices[_a * Q + _i]

            G.modVertex(v).pos = (20 * a, 10 * (a * Q + i), 0)
            G.modVertex(v).name = "v [%d, %d]" % (a, i)
            if DEBUG:
                print "positioning vertex %s at %s" % (v.name, [x / 10 for x in v.pos])


    # Connect all the vertices with different X-coordinates.
    for _a in range(P):
        a = _a + 1
        for _b in range(_a + 1, P):
            b = _b + 1
            print "a: %d, b: %d\n" % (a, b)
            for _i in range(Q):
                i = _i + 1
                for _j in range(Q):
                    j = _j + 1
                    print "i: %d, j: %d\n" % (i, j)
                    if _a * Q + _i >= len(vertices):
                        continue
                    if _b * Q + _j >= len(vertices):
                        continue
                    v = vertices[_a * Q + _i]
                    u = vertices[_b * Q + _j]

                    e = G.findEdgeBetween(v, u)
                    if not e:
                        # no edge between these vertices
                        continue
                    e = e[0]
                    print "v: %s\nu: %s\ne: %s\n" % (v, u, e)

                    bend = G.bendEdge(e,
                                      (
                                      10 * (2 * a + 1),
                                      10 * (b * Q + j),
                                      5 * (pow(4, P - a) * Q - i)
                                      ))
                    # The z coordinates have been scaled down by half
                    # to make the drawing more compact and easier to
                    # navigate. To use "real" coordinates, change this to
                    # "10 * (pow(...".
                    G.modVertex(bend).name = "r[%d,%d -> %d,%d]" % (a, i, b, j)
                    if DEBUG:
                        print "positioning bend %s at %s" % (bend.name, [x / 10 for x in bend.pos])
                    e = G.findEdgeBetween(v, u)[0]
                    G.modEdge(e).color = colorsys.hsv_to_rgb(float(a) / P + float(i) / n, (float(j) / Q) * 0.8 + 0.1,
                                                             0.8)

    # Connect all the vertices with same X-coordinates.

    for _a in range(P):
        a = _a + 1
        chain = 0
        # Choose the stride of the chain we're working on
        for stride in range(Q):
            # Choose the offset of this chain (< stride).
            for offset in range(stride):
                # Traverse the links of the chain and insert
                # bend points in the correct position.
                i = 0
                while True:
                    if offset + i + stride >= Q:
                        break
                    if _a * Q + offset + i + stride >= n:
                        break
                    u = vertices[_a * Q + offset + i]
                    v = vertices[_a * Q + offset + i + stride]

                    e = G.findEdgeBetween(v, u)
                    if e == []:
                        # no edge between these vertices
                        i = i + stride
                        continue
                    e = e[0]

                    # We might already have bent this edge.
                    if e.type() != "edge":
                        i = i + stride
                        continue

                    bend = G.bendEdge(e, (u.pos[0] + 10, u.pos[1], -10 * chain))

                    G.modVertex(bend).name = "x[%d,%d,%d,%d]" % (a, stride, offset, i)

                    if DEBUG:
                        print "positioning bend %s at %s" % (bend.name, [x / 10 for x in bend.pos])
                    e = G.findEdgeBetween(u, v)[0]
                    G.modEdge(e).color = colorsys.hsv_to_rgb(float(stride) / Q, 0.8, 0.4)
                    i = i + stride
                chain = chain + 1
    return