diff --git a/papers/coloring_nested_tire_graphs/experiments/draw_partial_tire_dual_bridge.py b/papers/coloring_nested_tire_graphs/experiments/draw_partial_tire_dual_bridge.py new file mode 100644 index 0000000..eae5039 --- /dev/null +++ b/papers/coloring_nested_tire_graphs/experiments/draw_partial_tire_dual_bridge.py @@ -0,0 +1,264 @@ +"""Draw a partial tire dual D(T) for a tire whose inner outerplanar +graph O has a bridge. + +Tire construction: + - Outer cycle B_out: triangle on {0, 1, 2}. + - Inner outerplanar O on {3, 4, 5, 6}: triangle 3-4-5 plus pendant + edge 5-6 (the bridge of O). + - Annular triangulation with 8 triangles (computed by hand below). + +The bridge 5-6 has both incident faces in the annular region, so in +the partial tire dual it contributes an interior dual edge (not a +leaf). This makes the interior dual subgraph a theta graph rather +than a single cycle: two trivalent vertices (the two annular faces +incident to the bridge) connected by three paths. +""" +import math +import os +import sys +from collections import defaultdict + +import matplotlib.pyplot as plt +import matplotlib.patches as patches + + +# Explicit vertex positions +POS = { + 0: (0.0, 1.0), + 1: (-0.866, -0.5), + 2: (0.866, -0.5), + 3: (0.0, 0.32), + 4: (-0.27, -0.17), + 5: (0.13, -0.17), + 6: (0.52, -0.07), +} + +# Annular triangles (in lattice-path-like order, but here just listed) +TRIANGLES = [ + (0, 1, 4), # T1 -- O-move + (0, 4, 3), # T2 -- has edge 4-3 boundary (inner triangle) + (1, 2, 5), # T3 -- O-move + (1, 5, 4), # T4 -- inner-triangle-edge boundary + (2, 0, 6), # T5 -- O-move + (0, 3, 6), # T6 -- ALL INTERIOR (bridge neighbour) + (3, 5, 6), # T7 -- inner-triangle-edge boundary, contains bridge + (5, 2, 6), # T8 -- ALL INTERIOR (bridge neighbour) +] + +# Tire edges (all) +T_EDGES = [ + # outer cycle (B_out) + (0, 1), (1, 2), (2, 0), + # O: triangle 3-4-5 + (3, 4), (4, 5), (3, 5), + # O: pendant / bridge + (5, 6), + # spokes + (0, 3), (1, 4), (2, 5), + # diagonals from annular triangulation + (0, 4), (1, 5), (0, 6), (2, 6), (3, 6), +] + +# Boundary edges +B_OUT_EDGES = [(0, 1), (1, 2), (2, 0)] +# Edges of O on inner-triangle-face boundary (i.e., NOT the bridge) +B_IN_EDGES = [(3, 4), (4, 5), (3, 5)] +# Bridge edge (interior to annulus) +BRIDGE = (5, 6) + + +def main(): + # Map: edge -> list of triangle indices containing it + edge_to_tris = defaultdict(list) + for i, t in enumerate(TRIANGLES): + for e in (frozenset({t[0], t[1]}), + frozenset({t[1], t[2]}), + frozenset({t[0], t[2]})): + edge_to_tris[e].append(i) + + # Verify each B_out edge is in exactly 1 annular triangle + for u, v in B_OUT_EDGES: + ts = edge_to_tris[frozenset({u, v})] + assert len(ts) == 1, f"B_out edge {u}-{v} in {ts}" + + # Each B_in (= non-bridge O edge) is in exactly 1 annular triangle + for u, v in B_IN_EDGES: + ts = edge_to_tris[frozenset({u, v})] + assert len(ts) == 1, f"B_in edge {u}-{v} in {ts}" + + # Bridge is in exactly 2 annular triangles (interior to annulus) + bts = edge_to_tris[frozenset(BRIDGE)] + print(f"Bridge {BRIDGE} is in annular triangles {bts}") + assert len(bts) == 2 + + # Interior dual subgraph: connect annular triangles sharing an edge + n_tri = len(TRIANGLES) + tri_adj = defaultdict(set) + for e, ts in edge_to_tris.items(): + if len(ts) == 2: + tri_adj[ts[0]].add(ts[1]) + tri_adj[ts[1]].add(ts[0]) + + print("Interior dual subgraph degree sequence:") + for i in range(n_tri): + print(f" T{i+1} ({TRIANGLES[i]}): degree {len(tri_adj[i])}") + + # Centroids of triangles for d_f positions + centroids = [] + for t in TRIANGLES: + cx = (POS[t[0]][0] + POS[t[1]][0] + POS[t[2]][0]) / 3 + cy = (POS[t[0]][1] + POS[t[1]][1] + POS[t[2]][1]) / 3 + centroids.append((cx, cy)) + + # === Plot === + fig, ax = plt.subplots(figsize=(10, 9)) + + # Draw underlying tire edges faintly + outer_set = {0, 1, 2} + inner_set = {3, 4, 5, 6} + for u, v in T_EDGES: + x1, y1 = POS[u]; x2, y2 = POS[v] + if u in outer_set and v in outer_set: + color = '#a8c9e8'; lw = 2.0 + elif u in inner_set and v in inner_set: + # Distinguish bridge (pendant) from triangle edges + if frozenset({u, v}) == frozenset(BRIDGE): + color = '#cc6677'; lw = 2.5 # darker red for bridge + else: + color = '#e8a8a8'; lw = 2.0 + else: + color = '#cccccc'; lw = 1.0 + ax.plot([x1, x2], [y1, y2], color=color, linewidth=lw, zorder=1) + + # Tire vertices + for v in [0, 1, 2]: + x, y = POS[v] + ax.plot(x, y, 'o', color='#a8c9e8', markersize=15, zorder=2) + ax.annotate(str(v), (x, y), color='white', ha='center', va='center', + fontsize=9, fontweight='bold', zorder=3) + for v in [3, 4, 5, 6]: + x, y = POS[v] + ax.plot(x, y, 'o', color='#e8a8a8', markersize=13, zorder=2) + ax.annotate(str(v), (x, y), color='white', ha='center', va='center', + fontsize=8, fontweight='bold', zorder=3) + + DUAL_COLOR = '#7d3c98' + LEAF_COLOR = '#e67e22' + BRIDGE_DUAL_COLOR = '#cc4444' # color the bridge's dual edge differently + + # Interior dual edges + for i in range(n_tri): + for j in tri_adj[i]: + if j <= i: + continue + x1, y1 = centroids[i]; x2, y2 = centroids[j] + # Find shared edge to colour-code bridge edge + ti_es = {frozenset({TRIANGLES[i][a], TRIANGLES[i][b]}) + for a, b in [(0, 1), (1, 2), (0, 2)]} + tj_es = {frozenset({TRIANGLES[j][a], TRIANGLES[j][b]}) + for a, b in [(0, 1), (1, 2), (0, 2)]} + shared = (ti_es & tj_es).pop() + if shared == frozenset(BRIDGE): + ec, lw = BRIDGE_DUAL_COLOR, 3.0 + else: + ec, lw = DUAL_COLOR, 2.0 + ax.plot([x1, x2], [y1, y2], color=ec, linewidth=lw, zorder=4) + + # Leaves for B_out edges + for u, v in B_OUT_EDGES: + ti = edge_to_tris[frozenset({u, v})][0] + midx = (POS[u][0] + POS[v][0]) / 2 + midy = (POS[u][1] + POS[v][1]) / 2 + d = math.sqrt(midx**2 + midy**2) + push = 1.20 + lpos = (midx * push / d, midy * push / d) + cx, cy = centroids[ti] + ax.plot([cx, lpos[0]], [cy, lpos[1]], color=LEAF_COLOR, + linewidth=1.5, linestyle='--', zorder=4) + ax.plot(lpos[0], lpos[1], 'D', color=LEAF_COLOR, markersize=11, + zorder=5) + ax.annotate(f"$\\ell^{{\\mathrm{{out}}}}_{{{u},{v}}}$", lpos, + color='white', ha='center', va='center', fontsize=6, + fontweight='bold', zorder=6) + + # Leaves for non-bridge B_in edges (= the 3 inner triangle edges) + for u, v in B_IN_EDGES: + ti = edge_to_tris[frozenset({u, v})][0] + midx = (POS[u][0] + POS[v][0]) / 2 + midy = (POS[u][1] + POS[v][1]) / 2 + cx, cy = centroids[ti] + vx, vy = midx - cx, midy - cy + norm = math.sqrt(vx*vx + vy*vy) + offset = 0.10 + if norm > 1e-9: + nx, ny = vx / norm, vy / norm + else: + nx, ny = 0, -1 + lpos = (midx + nx * offset, midy + ny * offset) + ax.plot([cx, lpos[0]], [cy, lpos[1]], color=LEAF_COLOR, + linewidth=1.5, linestyle='--', zorder=4) + ax.plot(lpos[0], lpos[1], 'D', color=LEAF_COLOR, markersize=11, + zorder=5) + ax.annotate(f"$\\ell^{{\\mathrm{{in}}}}_{{{u},{v}}}$", lpos, + color='white', ha='center', va='center', fontsize=6, + fontweight='bold', zorder=6) + + # Interior dual vertices d_f, highlighting the two degree-3 + # vertices in a darker color (these are the trivalent vertices + # of the theta graph that the interior dual forms). + for ti, (cx, cy) in enumerate(centroids): + is_deg3 = (len(tri_adj[ti]) == 3) + marker_color = '#5a2273' if is_deg3 else DUAL_COLOR + ax.plot(cx, cy, 's', color=marker_color, markersize=15, zorder=5) + ax.annotate(f"$d_{{{ti}}}$", (cx, cy), color='white', ha='center', + va='center', fontsize=7, fontweight='bold', zorder=6) + + # Legend + legend_items = [ + plt.Line2D([], [], marker='o', color='w', markerfacecolor='#a8c9e8', + markersize=12, label='$B_{\\mathrm{out}}$ vertex'), + plt.Line2D([], [], marker='o', color='w', markerfacecolor='#e8a8a8', + markersize=11, label='$V(O)$ vertex'), + plt.Line2D([], [], color='#a8c9e8', linewidth=2.0, + label='$B_{\\mathrm{out}}$ edge'), + plt.Line2D([], [], color='#e8a8a8', linewidth=2.0, + label='triangle edge of $O$'), + plt.Line2D([], [], color='#cc6677', linewidth=2.5, + label='bridge of $O$ (= pendant)'), + plt.Line2D([], [], marker='s', color='w', markerfacecolor=DUAL_COLOR, + markersize=12, label='$d_f$ (degree 2 in interior dual)'), + plt.Line2D([], [], marker='s', color='w', markerfacecolor='#5a2273', + markersize=12, + label='$d_f$ (degree 3 -- theta-graph trivalent)'), + plt.Line2D([], [], marker='D', color='w', markerfacecolor=LEAF_COLOR, + markersize=10, label='leaf'), + plt.Line2D([], [], color=DUAL_COLOR, linewidth=2.0, + label='interior dual edge'), + plt.Line2D([], [], color=BRIDGE_DUAL_COLOR, linewidth=3.0, + label='dual of the bridge'), + plt.Line2D([], [], color=LEAF_COLOR, linewidth=1.5, linestyle='--', + label='leaf edge'), + ] + ax.legend(handles=legend_items, loc='upper left', + bbox_to_anchor=(1.02, 1.0), fontsize=8, frameon=False) + + ax.set_xlim(-1.30, 1.50) + ax.set_ylim(-1.20, 1.20) + ax.set_aspect('equal') + ax.axis('off') + ax.set_title( + 'Partial tire dual $D(T)$ when $O$ has a bridge\n' + '$O$ = triangle $\\{3,4,5\\}$ + pendant edge $5$--$6$;\n' + 'interior dual is a theta graph (2 deg-3 vertices + 3 paths), ' + 'not a cycle.', + fontsize=11) + + HERE = os.path.dirname(os.path.abspath(__file__)) + out = os.path.join(HERE, 'partial_tire_dual_bridge.png') + plt.savefig(out, dpi=160, bbox_inches='tight') + plt.close() + print(f"wrote {out}") + + +if __name__ == '__main__': + main() diff --git a/papers/coloring_nested_tire_graphs/experiments/partial_tire_dual_bridge.png b/papers/coloring_nested_tire_graphs/experiments/partial_tire_dual_bridge.png new file mode 100644 index 0000000..3b96c05 Binary files /dev/null and b/papers/coloring_nested_tire_graphs/experiments/partial_tire_dual_bridge.png differ diff --git a/papers/coloring_nested_tire_graphs/fig_partial_tire_dual_bridge.png b/papers/coloring_nested_tire_graphs/fig_partial_tire_dual_bridge.png new file mode 100644 index 0000000..3b96c05 Binary files /dev/null and b/papers/coloring_nested_tire_graphs/fig_partial_tire_dual_bridge.png differ diff --git a/papers/coloring_nested_tire_graphs/paper.aux b/papers/coloring_nested_tire_graphs/paper.aux index aad7195..67c5c55 100644 --- a/papers/coloring_nested_tire_graphs/paper.aux +++ b/papers/coloring_nested_tire_graphs/paper.aux @@ -11,19 +11,21 @@ \@writefile{lof}{\contentsline {figure}{\numberline {3}{\ignorespaces The partial tire dual $D(T)$ (purple squares + orange diamonds) drawn on top of a small tire graph $T$ (faint) with $m = 6$ and $k = 4$. The ten interior vertices $d_f$ at the centroids of the annular triangles form a single $10$-cycle (solid purple); each boundary edge of the annular region (either of $B_{\mathrm {out}}$ or of $B_{\mathrm {in}}$) contributes a degree-$1$ leaf (orange diamond) attached to the unique annular face incident to it (dashed orange), giving the structure $C_{10} \circ K_1$ of Proposition\nonbreakingspace 1.8\hbox {}.}}{4}{}\protected@file@percent } \newlabel{fig:partial-tire-dual-example}{{3}{4}} \newlabel{prop:partial-tire-dual-structure}{{1.8}{4}} +\@writefile{lof}{\contentsline {figure}{\numberline {4}{\ignorespaces Partial tire dual $D(T)$ when the inner outerplanar graph $O$ has a bridge. Here $B_{\mathrm {out}}$ is a triangle on $\{0,1,2\}$ and $O$ is a triangle $\{3,4,5\}$ with a pendant edge $5$--$6$ (the bridge of $O$). Because both faces incident to the bridge are annular triangles, the bridge contributes an \emph {interior dual edge} (highlighted in red) rather than two leaves; consequently the interior dual subgraph is no longer the single $(n+m)$-cycle of Proposition\nonbreakingspace 1.8\hbox {}, but a theta graph (two trivalent vertices $d_5, d_7$ connected by three internally vertex-disjoint paths in $D(T)$). Leaves come only from $B_{\mathrm {out}}$ ($n = 3$ leaves) and from the three non-bridge edges of $O$ (the three triangle edges of the inner triangle).}}{5}{}\protected@file@percent } +\newlabel{fig:partial-tire-dual-bridge}{{4}{5}} \newlabel{prop:no-level-d-pinch}{{1.9}{5}} -\newlabel{lem:tire-component}{{1.10}{5}} \citation{bauerfeld-pds} +\newlabel{lem:tire-component}{{1.10}{6}} \citation{bauerfeld-pds} \newlabel{rem:tire-component-degenerate}{{1.11}{7}} -\newlabel{rem:tire-no-extra-hypotheses}{{1.12}{7}} -\newlabel{prop:edge-vertex-bijection}{{1.13}{7}} +\newlabel{rem:tire-no-extra-hypotheses}{{1.12}{8}} +\newlabel{prop:edge-vertex-bijection}{{1.13}{8}} +\newlabel{rem:edge-vertex-corollary}{{1.14}{8}} \bibcite{bauerfeld-pds}{1} \newlabel{tocindent-1}{0pt} \newlabel{tocindent0}{12.7778pt} \newlabel{tocindent1}{17.77782pt} \newlabel{tocindent2}{0pt} \newlabel{tocindent3}{0pt} -\newlabel{rem:edge-vertex-corollary}{{1.14}{8}} -\@writefile{toc}{\contentsline {section}{\tocsection {}{}{References}}{8}{}\protected@file@percent } -\gdef \@abspage@last{8} +\@writefile{toc}{\contentsline {section}{\tocsection {}{}{References}}{9}{}\protected@file@percent } +\gdef \@abspage@last{9} diff --git a/papers/coloring_nested_tire_graphs/paper.log b/papers/coloring_nested_tire_graphs/paper.log index 05af7d5..11c1f35 100644 --- a/papers/coloring_nested_tire_graphs/paper.log +++ b/papers/coloring_nested_tire_graphs/paper.log @@ -1,4 +1,4 @@ -This is pdfTeX, Version 3.141592653-2.6-1.40.24 (TeX Live 2022) (preloaded format=pdflatex 2022.10.5) 25 MAY 2026 19:52 +This is pdfTeX, Version 3.141592653-2.6-1.40.24 (TeX Live 2022) (preloaded format=pdflatex 2022.10.5) 25 MAY 2026 20:43 entering extended mode restricted \write18 enabled. %&-line parsing enabled. @@ -213,36 +213,51 @@ File: fig_partial_tire_dual.png Graphic file (type png) Package pdftex.def Info: fig_partial_tire_dual.png used on input line 225. (pdftex.def) Requested size: 280.79956pt x 233.36552pt. - [4 <./fig_partial_tire_dual.png>] [5] [6] [7] [8] (./paper.aux) ) + +File: fig_partial_tire_dual_bridge.png Graphic file (type png) + +Package pdftex.def Info: fig_partial_tire_dual_bridge.png used on input line 2 +40. +(pdftex.def) Requested size: 280.79956pt x 198.95839pt. + + +LaTeX Warning: `h' float specifier changed to `ht'. + +[4 <./fig_partial_tire_dual.png>] [5 <./fig_partial_tire_dual_bridge.png>] +[6] +Underfull \vbox (badness 1043) has occurred while \output is active [] + + [7] +[8] [9] (./paper.aux) ) Here is how much of TeX's memory you used: - 3020 strings out of 478268 - 42387 string characters out of 5846347 - 345229 words of memory out of 5000000 - 21066 multiletter control sequences out of 15000+600000 + 3028 strings out of 478268 + 42672 string characters out of 5846347 + 344237 words of memory out of 5000000 + 21073 multiletter control sequences out of 15000+600000 475666 words of font info for 53 fonts, out of 8000000 for 9000 1302 hyphenation exceptions out of 8191 - 69i,8n,76p,687b,316s stack positions out of 10000i,1000n,20000p,200000b,200000s - -Output written on paper.pdf (8 pages, 622907 bytes). + 69i,8n,76p,907b,316s stack positions out of 10000i,1000n,20000p,200000b,200000s + +< +/usr/local/texlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmti8.pfb> +Output written on paper.pdf (9 pages, 748857 bytes). PDF statistics: - 118 PDF objects out of 1000 (max. 8388607) - 69 compressed objects within 1 object stream + 123 PDF objects out of 1000 (max. 8388607) + 71 compressed objects within 1 object stream 0 named destinations out of 1000 (max. 500000) - 16 words of extra memory for PDF output out of 10000 (max. 10000000) + 21 words of extra memory for PDF output out of 10000 (max. 10000000) diff --git a/papers/coloring_nested_tire_graphs/paper.pdf b/papers/coloring_nested_tire_graphs/paper.pdf index c9814c2..8ad0408 100644 Binary files a/papers/coloring_nested_tire_graphs/paper.pdf and b/papers/coloring_nested_tire_graphs/paper.pdf differ diff --git a/papers/coloring_nested_tire_graphs/paper.tex b/papers/coloring_nested_tire_graphs/paper.tex index 661c879..8db7cfc 100644 --- a/papers/coloring_nested_tire_graphs/paper.tex +++ b/papers/coloring_nested_tire_graphs/paper.tex @@ -235,6 +235,25 @@ Proposition~\ref{prop:partial-tire-dual-structure}.} \label{fig:partial-tire-dual-example} \end{figure} +\begin{figure}[h] +\centering +\includegraphics[width=0.78\textwidth]{fig_partial_tire_dual_bridge.png} +\caption{Partial tire dual $D(T)$ when the inner outerplanar graph +$O$ has a bridge. Here $B_{\mathrm{out}}$ is a triangle on +$\{0,1,2\}$ and $O$ is a triangle $\{3,4,5\}$ with a pendant edge +$5$--$6$ (the bridge of $O$). Because both faces incident to the +bridge are annular triangles, the bridge contributes an +\emph{interior dual edge} (highlighted in red) rather than two +leaves; consequently the interior dual subgraph is no longer the +single $(n+m)$-cycle of +Proposition~\ref{prop:partial-tire-dual-structure}, but a theta +graph (two trivalent vertices $d_5, d_7$ connected by three +internally vertex-disjoint paths in $D(T)$). Leaves come only from +$B_{\mathrm{out}}$ ($n = 3$ leaves) and from the three non-bridge +edges of $O$ (the three triangle edges of the inner triangle).} +\label{fig:partial-tire-dual-bridge} +\end{figure} + \begin{proposition}[Structure of $D(T)$ when the annular triangulation is spoke-only] \label{prop:partial-tire-dual-structure}