coloring_nested_tire_graphs: add figure of the complete tire dual D*(T)
Adds fig_complete_tire_dual.png next to Definition 1.13 of the complete tire dual. The figure uses the same m=6, k=4 spoke-only tire as the partial-tire-dual figure (so the two figures can be directly compared), with the n=6 outer leaves merged into a single outer-face vertex v_out (blue hexagon, drawn outside the tire) of degree 6, and the m=4 inner leaves merged into a single inner-face vertex v_in (red hexagon, drawn at the centre of the inner cycle) of degree 4. Generator: experiments/draw_complete_tire_dual.py. Paper grows from 8 to 9 pages. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 151 KiB |
@@ -0,0 +1,199 @@
|
||||
"""Draw the complete tire dual D*(T) on top of a small tire graph.
|
||||
|
||||
For a spoke-only tire with 2-connected O = C_k (no chords), D*(T) is
|
||||
obtained from D(T) by merging:
|
||||
- all B_out-leaves into a single outer-face vertex v_out (degree n);
|
||||
- the B_in-leaves into a single inner-face vertex v_in (degree k),
|
||||
because O has exactly one bounded interior face.
|
||||
|
||||
Equivalently, D*(T) is the planar dual of T.
|
||||
"""
|
||||
import math
|
||||
import os
|
||||
import sys
|
||||
|
||||
HERE = os.path.dirname(os.path.abspath(__file__))
|
||||
sys.path.insert(0, HERE)
|
||||
|
||||
import matplotlib.pyplot as plt
|
||||
import matplotlib.patches as patches
|
||||
|
||||
from tire_graph import random_tire, planar_positions
|
||||
|
||||
|
||||
def draw_complete_tire_dual(tire, filename):
|
||||
m, k = tire['m'], tire['k']
|
||||
outer, inner = tire['outer'], tire['inner']
|
||||
triangles = tire['triangles']
|
||||
|
||||
R_out, R_in = 1.0, 0.45
|
||||
pos = planar_positions(tire, R_out=R_out, R_in=R_in)
|
||||
|
||||
fig, ax = plt.subplots(figsize=(9, 9))
|
||||
|
||||
# === Draw underlying tire graph faintly ===
|
||||
outer_set = set(outer)
|
||||
inner_set = set(inner)
|
||||
for u, v in tire['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:
|
||||
color = '#e8a8a8'; lw = 2.0
|
||||
else:
|
||||
color = '#cccccc'; lw = 1.0
|
||||
ax.plot([x1, x2], [y1, y2], color=color, linewidth=lw, zorder=1)
|
||||
for v in outer:
|
||||
x, y = pos[v]
|
||||
ax.plot(x, y, 'o', color='#a8c9e8', markersize=14, zorder=2)
|
||||
ax.annotate(str(v), (x, y), color='white', ha='center', va='center',
|
||||
fontsize=8, fontweight='bold', zorder=3)
|
||||
for v in inner:
|
||||
x, y = pos[v]
|
||||
ax.plot(x, y, 'o', color='#e8a8a8', markersize=12, zorder=2)
|
||||
ax.annotate(str(v), (x, y), color='white', ha='center', va='center',
|
||||
fontsize=7, fontweight='bold', zorder=3)
|
||||
|
||||
n_tri = len(triangles)
|
||||
centroids = []
|
||||
for tri in triangles:
|
||||
v1, v2, v3 = tri
|
||||
cx = (pos[v1][0] + pos[v2][0] + pos[v3][0]) / 3
|
||||
cy = (pos[v1][1] + pos[v2][1] + pos[v3][1]) / 3
|
||||
centroids.append((cx, cy))
|
||||
|
||||
# Identify which triangles are incident to a B_out edge (O-move type)
|
||||
# vs incident to a B_in edge (I-move type).
|
||||
from collections import defaultdict
|
||||
bout_edges = {frozenset({outer[i], outer[(i+1) % m]}) for i in range(m)}
|
||||
bin_edges = {frozenset({inner[j], inner[(j+1) % k]}) for j in range(k)}
|
||||
|
||||
bout_incident = [] # triangles incident to a B_out edge
|
||||
bin_incident = [] # triangles incident to a B_in edge
|
||||
for t_idx, tri in enumerate(triangles):
|
||||
tri_edges = {frozenset({tri[0], tri[1]}),
|
||||
frozenset({tri[1], tri[2]}),
|
||||
frozenset({tri[0], tri[2]})}
|
||||
if tri_edges & bout_edges:
|
||||
bout_incident.append(t_idx)
|
||||
if tri_edges & bin_edges:
|
||||
bin_incident.append(t_idx)
|
||||
|
||||
print(f"O-move triangles (B_out incident): {bout_incident}")
|
||||
print(f"I-move triangles (B_in incident): {bin_incident}")
|
||||
|
||||
# Place v_out outside the outer cycle (far to the upper right)
|
||||
# and v_in at the origin (centroid of inner cycle).
|
||||
v_out_pos = (1.55, 0.0) # well outside the outer cycle
|
||||
v_in_pos = (0.0, 0.0) # center of inner cycle
|
||||
|
||||
# Identify dual cycle (interior dual edges)
|
||||
edge_to_tris = defaultdict(list)
|
||||
for t_idx, tri in enumerate(triangles):
|
||||
e1 = frozenset({tri[0], tri[1]})
|
||||
e2 = frozenset({tri[1], tri[2]})
|
||||
e3 = frozenset({tri[0], tri[2]})
|
||||
for e in (e1, e2, e3):
|
||||
edge_to_tris[e].append(t_idx)
|
||||
|
||||
tri_adj = defaultdict(set)
|
||||
for e, ts in edge_to_tris.items():
|
||||
if len(ts) == 2:
|
||||
t1, t2 = ts
|
||||
tri_adj[t1].add(t2)
|
||||
tri_adj[t2].add(t1)
|
||||
|
||||
# === Draw complete tire dual ===
|
||||
DUAL_COLOR = '#7d3c98' # purple
|
||||
OUT_COLOR = '#1f77b4' # blue (for v_out edges)
|
||||
IN_COLOR = '#d62728' # red (for v_in edges)
|
||||
|
||||
# Interior dual edges (d_f to d_f)
|
||||
for t1 in range(n_tri):
|
||||
for t2 in tri_adj[t1]:
|
||||
if t2 <= t1:
|
||||
continue
|
||||
x1, y1 = centroids[t1]
|
||||
x2, y2 = centroids[t2]
|
||||
ax.plot([x1, x2], [y1, y2], color=DUAL_COLOR, linewidth=2.0,
|
||||
zorder=4)
|
||||
|
||||
# v_out edges (to all O-move d_f's)
|
||||
for t_idx in bout_incident:
|
||||
cx, cy = centroids[t_idx]
|
||||
ax.plot([cx, v_out_pos[0]], [cy, v_out_pos[1]],
|
||||
color=OUT_COLOR, linewidth=1.6, linestyle='--', zorder=4)
|
||||
|
||||
# v_in edges (to all I-move d_f's)
|
||||
for t_idx in bin_incident:
|
||||
cx, cy = centroids[t_idx]
|
||||
ax.plot([cx, v_in_pos[0]], [cy, v_in_pos[1]],
|
||||
color=IN_COLOR, linewidth=1.6, linestyle='--', zorder=4)
|
||||
|
||||
# Interior dual vertices d_f
|
||||
for t_idx, (cx, cy) in enumerate(centroids):
|
||||
ax.plot(cx, cy, 's', color=DUAL_COLOR, markersize=14, zorder=5)
|
||||
ax.annotate(f"$d_{{{t_idx}}}$", (cx, cy), color='white',
|
||||
ha='center', va='center', fontsize=7, fontweight='bold',
|
||||
zorder=6)
|
||||
|
||||
# v_out (outer-face vertex)
|
||||
ax.plot(v_out_pos[0], v_out_pos[1], 'h', color=OUT_COLOR,
|
||||
markersize=20, zorder=5)
|
||||
ax.annotate("$v_{\\mathrm{out}}$", v_out_pos, color='white',
|
||||
ha='center', va='center', fontsize=9, fontweight='bold',
|
||||
zorder=6)
|
||||
|
||||
# v_in (inner-face vertex)
|
||||
ax.plot(v_in_pos[0], v_in_pos[1], 'h', color=IN_COLOR,
|
||||
markersize=18, zorder=5)
|
||||
ax.annotate("$v_{\\mathrm{in}}$", v_in_pos, color='white',
|
||||
ha='center', va='center', fontsize=8, fontweight='bold',
|
||||
zorder=6)
|
||||
|
||||
# Legend
|
||||
legend_items = [
|
||||
plt.Line2D([], [], marker='o', color='w', markerfacecolor='#a8c9e8',
|
||||
markersize=12, label='$B_{\\mathrm{out}}$ vertex (tire)'),
|
||||
plt.Line2D([], [], marker='o', color='w', markerfacecolor='#e8a8a8',
|
||||
markersize=11, label='$B_{\\mathrm{in}}$ vertex (tire)'),
|
||||
plt.Line2D([], [], marker='s', color='w', markerfacecolor=DUAL_COLOR,
|
||||
markersize=12, label='$d_f$ (annular face dual vertex)'),
|
||||
plt.Line2D([], [], marker='h', color='w', markerfacecolor=OUT_COLOR,
|
||||
markersize=14,
|
||||
label='$v_{\\mathrm{out}}$ (outer-face vertex, deg ${%d}$)' % m),
|
||||
plt.Line2D([], [], marker='h', color='w', markerfacecolor=IN_COLOR,
|
||||
markersize=13,
|
||||
label='$v_{\\mathrm{in}}$ (inner-face vertex, deg ${%d}$)' % k),
|
||||
plt.Line2D([], [], color=DUAL_COLOR, linewidth=2.0,
|
||||
label='interior dual edge ($d_f$–$d_{f^\\prime}$)'),
|
||||
plt.Line2D([], [], color=OUT_COLOR, linewidth=1.6, linestyle='--',
|
||||
label='dual edge to $v_{\\mathrm{out}}$'),
|
||||
plt.Line2D([], [], color=IN_COLOR, linewidth=1.6, linestyle='--',
|
||||
label='dual edge to $v_{\\mathrm{in}}$'),
|
||||
]
|
||||
ax.legend(handles=legend_items, loc='upper left',
|
||||
bbox_to_anchor=(1.02, 1.0), fontsize=9, frameon=False)
|
||||
|
||||
ax.set_xlim(-1.35, 2.05)
|
||||
ax.set_ylim(-1.35, 1.35)
|
||||
ax.set_aspect('equal')
|
||||
ax.axis('off')
|
||||
ax.set_title(
|
||||
f'Complete tire dual $D^{{*}}(T)$ (m={m}, k={k}, spoke-only)\n'
|
||||
f'underlying tire faint; $|V| = {n_tri + 2}$, $|E| = {2*n_tri}$',
|
||||
fontsize=12)
|
||||
|
||||
plt.savefig(filename, dpi=160, bbox_inches='tight')
|
||||
plt.close()
|
||||
print(f"wrote {filename}")
|
||||
|
||||
|
||||
def main():
|
||||
tire = random_tire(m=6, k=4, n_chords=0, seed=3)
|
||||
out = os.path.join(HERE, 'complete_tire_dual_example.png')
|
||||
draw_complete_tire_dual(tire, out)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 151 KiB |
@@ -19,6 +19,11 @@
|
||||
\newlabel{rem:tire-no-extra-hypotheses}{{1.12}{7}}
|
||||
\newlabel{def:complete-tire-dual}{{1.13}{7}}
|
||||
\citation{Tait1880}
|
||||
\@writefile{lof}{\contentsline {figure}{\numberline {4}{\ignorespaces The complete tire dual $D^{\ast }(T)$ (purple squares + face hexagons) drawn on top of the same $m = 6$, $k = 4$ spoke-only tire graph as Figure\nonbreakingspace 3\hbox {}. The ten annular-face vertices $d_f$ form a $10$-cycle (solid purple); the $n$ outer leaves of $D(T)$ have been merged into a single outer-face vertex $v_{\mathrm {out}}$ (blue hexagon, drawn outside the tire) of degree $n = 6$, and the $m$ inner leaves into a single inner-face vertex $v_{\mathrm {in}}$ (red hexagon, at the centre of the inner cycle) of degree $m = 4$. Total $|V(D^{\ast }(T))| = 12$ and $|E(D^{\ast }(T))| = 20$.}}{8}{}\protected@file@percent }
|
||||
\newlabel{fig:complete-tire-dual-example}{{4}{8}}
|
||||
\newlabel{prop:tait-tire-complete}{{1.14}{8}}
|
||||
\newlabel{rem:tait-construction}{{1.15}{8}}
|
||||
\newlabel{rem:tait-octahedron}{{1.16}{8}}
|
||||
\bibcite{Tait1880}{1}
|
||||
\bibcite{bauerfeld-pds}{2}
|
||||
\newlabel{tocindent-1}{0pt}
|
||||
@@ -26,8 +31,5 @@
|
||||
\newlabel{tocindent1}{17.77782pt}
|
||||
\newlabel{tocindent2}{0pt}
|
||||
\newlabel{tocindent3}{0pt}
|
||||
\newlabel{prop:tait-tire-complete}{{1.14}{8}}
|
||||
\newlabel{rem:tait-construction}{{1.15}{8}}
|
||||
\newlabel{rem:tait-octahedron}{{1.16}{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}
|
||||
|
||||
@@ -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 18:59
|
||||
This is pdfTeX, Version 3.141592653-2.6-1.40.24 (TeX Live 2022) (preloaded format=pdflatex 2022.10.5) 25 MAY 2026 19:28
|
||||
entering extended mode
|
||||
restricted \write18 enabled.
|
||||
%&-line parsing enabled.
|
||||
@@ -213,37 +213,43 @@ File: fig_partial_tire_dual.png Graphic file (type png)
|
||||
<use fig_partial_tire_dual.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) )
|
||||
[4 <./fig_partial_tire_dual.png>] [5] [6] [7]
|
||||
<fig_complete_tire_dual.png, id=48, 701.47069pt x 448.074pt>
|
||||
File: fig_complete_tire_dual.png Graphic file (type png)
|
||||
<use fig_complete_tire_dual.png>
|
||||
Package pdftex.def Info: fig_complete_tire_dual.png used on input line 513.
|
||||
(pdftex.def) Requested size: 295.20264pt x 188.55899pt.
|
||||
[8 <./fig_complete_tire_dual.png>] [9] (./paper.aux) )
|
||||
Here is how much of TeX's memory you used:
|
||||
3023 strings out of 478268
|
||||
42435 string characters out of 5846347
|
||||
345254 words of memory out of 5000000
|
||||
21069 multiletter control sequences out of 15000+600000
|
||||
3031 strings out of 478268
|
||||
42680 string characters out of 5846347
|
||||
345262 words of memory out of 5000000
|
||||
21076 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
|
||||
</usr/local/t
|
||||
exlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmbx10.pfb></usr/local/te
|
||||
xlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmcsc10.pfb></usr/local/te
|
||||
xlive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmex10.pfb></usr/local/tex
|
||||
live/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmmi10.pfb></usr/local/texl
|
||||
ive/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmmi5.pfb></usr/local/texliv
|
||||
e/2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmmi7.pfb></usr/local/texlive/
|
||||
2022/texmf-dist/fonts/type1/public/amsfonts/cm/cmr10.pfb></usr/local/texlive/20
|
||||
22/texmf-dist/fonts/type1/public/amsfonts/cm/cmr5.pfb></usr/local/texlive/2022/
|
||||
texmf-dist/fonts/type1/public/amsfonts/cm/cmr7.pfb></usr/local/texlive/2022/tex
|
||||
mf-dist/fonts/type1/public/amsfonts/cm/cmr8.pfb></usr/local/texlive/2022/texmf-
|
||||
dist/fonts/type1/public/amsfonts/cm/cmsy10.pfb></usr/local/texlive/2022/texmf-d
|
||||
ist/fonts/type1/public/amsfonts/cm/cmsy5.pfb></usr/local/texlive/2022/texmf-dis
|
||||
t/fonts/type1/public/amsfonts/cm/cmsy7.pfb></usr/local/texlive/2022/texmf-dist/
|
||||
fonts/type1/public/amsfonts/cm/cmti10.pfb></usr/local/texlive/2022/texmf-dist/f
|
||||
onts/type1/public/amsfonts/cm/cmti8.pfb></usr/local/texlive/2022/texmf-dist/fon
|
||||
ts/type1/public/amsfonts/symbols/msam10.pfb></usr/local/texlive/2022/texmf-dist
|
||||
/fonts/type1/public/amsfonts/symbols/msbm10.pfb>
|
||||
Output written on paper.pdf (8 pages, 628165 bytes).
|
||||
69i,8n,76p,742b,316s stack positions out of 10000i,1000n,20000p,200000b,200000s
|
||||
</usr/local/texlive/2022
|
||||
/texmf-dist/fonts/type1/public/amsfonts/cm/cmbx10.pfb></usr/local/texlive/2022/
|
||||
texmf-dist/fonts/type1/public/amsfonts/cm/cmcsc10.pfb></usr/local/texlive/2022/
|
||||
texmf-dist/fonts/type1/public/amsfonts/cm/cmex10.pfb></usr/local/texlive/2022/t
|
||||
exmf-dist/fonts/type1/public/amsfonts/cm/cmmi10.pfb></usr/local/texlive/2022/te
|
||||
xmf-dist/fonts/type1/public/amsfonts/cm/cmmi5.pfb></usr/local/texlive/2022/texm
|
||||
f-dist/fonts/type1/public/amsfonts/cm/cmmi7.pfb></usr/local/texlive/2022/texmf-
|
||||
dist/fonts/type1/public/amsfonts/cm/cmr10.pfb></usr/local/texlive/2022/texmf-di
|
||||
st/fonts/type1/public/amsfonts/cm/cmr5.pfb></usr/local/texlive/2022/texmf-dist/
|
||||
fonts/type1/public/amsfonts/cm/cmr7.pfb></usr/local/texlive/2022/texmf-dist/fon
|
||||
ts/type1/public/amsfonts/cm/cmr8.pfb></usr/local/texlive/2022/texmf-dist/fonts/
|
||||
type1/public/amsfonts/cm/cmsy10.pfb></usr/local/texlive/2022/texmf-dist/fonts/t
|
||||
ype1/public/amsfonts/cm/cmsy5.pfb></usr/local/texlive/2022/texmf-dist/fonts/typ
|
||||
e1/public/amsfonts/cm/cmsy7.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1
|
||||
/public/amsfonts/cm/cmti10.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/
|
||||
public/amsfonts/cm/cmti8.pfb></usr/local/texlive/2022/texmf-dist/fonts/type1/pu
|
||||
blic/amsfonts/symbols/msam10.pfb></usr/local/texlive/2022/texmf-dist/fonts/type
|
||||
1/public/amsfonts/symbols/msbm10.pfb>
|
||||
Output written on paper.pdf (9 pages, 748601 bytes).
|
||||
PDF statistics:
|
||||
123 PDF objects out of 1000 (max. 8388607)
|
||||
72 compressed objects within 1 object stream
|
||||
128 PDF objects out of 1000 (max. 8388607)
|
||||
74 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)
|
||||
|
||||
|
||||
Binary file not shown.
@@ -508,6 +508,22 @@ vertex per face of $T$ (annular triangle, outer face, or bounded
|
||||
interior face of $O$), one dual edge per edge of $T$.
|
||||
\end{definition}
|
||||
|
||||
\begin{figure}[h]
|
||||
\centering
|
||||
\includegraphics[width=0.82\textwidth]{fig_complete_tire_dual.png}
|
||||
\caption{The complete tire dual $D^{\ast}(T)$ (purple squares + face
|
||||
hexagons) drawn on top of the same $m = 6$, $k = 4$ spoke-only tire
|
||||
graph as Figure~\ref{fig:partial-tire-dual-example}. The ten
|
||||
annular-face vertices $d_f$ form a $10$-cycle (solid purple); the
|
||||
$n$ outer leaves of $D(T)$ have been merged into a single outer-face
|
||||
vertex $v_{\mathrm{out}}$ (blue hexagon, drawn outside the tire) of
|
||||
degree $n = 6$, and the $m$ inner leaves into a single inner-face
|
||||
vertex $v_{\mathrm{in}}$ (red hexagon, at the centre of the inner
|
||||
cycle) of degree $m = 4$. Total $|V(D^{\ast}(T))| = 12$ and
|
||||
$|E(D^{\ast}(T))| = 20$.}
|
||||
\label{fig:complete-tire-dual-example}
|
||||
\end{figure}
|
||||
|
||||
\begin{proposition}[Tait correspondence on the complete tire dual]
|
||||
\label{prop:tait-tire-complete}
|
||||
Let $T$ be a tire graph. Then the number of non-equivalent proper
|
||||
|
||||
Reference in New Issue
Block a user