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
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