def mirror(link): """ Create the mirror image of the link, preserving link orientations and component order. """ # Basically, we just mirror every crossing, but the particular data # structures used make this a little involved. new_crossings = dict() for C in link.crossings: C_new = Crossing(label=C.label) C_new.sign = -C.sign new_crossings[C] = C_new def convert(C, c): """ Go from a crossing to the mirror, which requires the a rotation of the entry points; the direction of rotation depends on the sign of the crossing. """ return new_crossings[C], (c + C.sign) % 4 for A in link.crossings: entry_points = [CEP.entry_point for CEP in A.entry_points()] for a in entry_points: B, b = A.adjacent[a] B_new, b_new = convert(B, b) B_new[b_new] = convert(A, a) new_link = Link(new_crossings.values(), check_planarity=False, build=False) # Build the link components, starting in the same place as # the original link. component_starts = [] for component in link.link_components: C_new, c_new = convert(*component[0]) component_starts.append( CrossingEntryPoint(C_new, c_new) ) new_link._build_components(component_starts) return new_link
def link(self): G = self.fat_graph crossing_dict, slot_dict = {}, {} for v in G.vertices: c = Crossing(v[0]) c.make_tail(0) if G.sign(v) == 1: c.make_tail(3) else: c.make_tail(1) c.orient() crossing_dict[v] = c if v.upper_pair() == (0, 2): slot_dict[v] = (3, 0, 1, 2) else: slot_dict[v] = (2, 3, 0, 1) if G.flipped(v) else (0, 1, 2, 3) for edge in G.edges: v0, v1 = edge s0, s1 = edge.slots a0, a1 = slot_dict[v0][s0], slot_dict[v1][s1] c0, c1 = crossing_dict[v0], crossing_dict[v1] c0[a0] = c1[a1] link = Link(list(crossing_dict.values()), check_planarity=False, build=False) assert link.all_crossings_oriented() component_starts = [] i = 1 for comp in self.code: c = self[i] if i == c[0]: e = slot_dict[c][2] if G.flipped(c) else slot_dict[c][0] else: e = slot_dict[c][1] ce = CrossingEntryPoint(crossing_dict[c], e) component_starts.append(ce) i += 2 * len(comp) link._build_components(component_starts) if not link.is_planar(): raise ValueError( 'DT code does not seem to define a *planar* diagram') return link