"""Generate paper-20-drums.png in the caller's CWD with declared root dependencies.""" from pathlib import Path import numpy as np import matplotlib.pyplot as plt from matplotlib.patches import Polygon from matplotlib.lines import Line2D def permutations(dual=False): vectors=np.array([[(i>>j)&1 for j in range(3)] for i in range(1,8)],int) result=[] for i,j in [(0,1),(1,2),(2,0)]: matrix=np.eye(3,dtype=int);matrix[i,j]=1 if dual:matrix=matrix.T result.append([next(k for k,w in enumerate(vectors) if np.array_equal(matrix@v%2,w)) for v in vectors]) return result def reflect(points,a,b): direction=(b-a)/np.linalg.norm(b-a) matrix=2*np.outer(direction,direction)-np.eye(2) return (points-a)@matrix+a def assemble(actions): triangle=np.array([[0.,0.],[1.,0.],[.45,.82]]) tiles={7:triangle};queue=[7] while queue: label=queue.pop(0) for side,p in enumerate(actions): target=p[label-1]+1 if target!=label and target not in tiles: endpoints=[i for i in range(3) if i!=side] tiles[target]=reflect(tiles[label],*tiles[label][endpoints]);queue.append(target) assert len(tiles)==7 return tiles def main(): fig,axes=plt.subplots(1,2,figsize=(12,6),dpi=96,facecolor='white') colors=['#bc3a31','#2c7a52','#3266a8'] for ax,dual,title in zip(axes,[False,True],['Point action','Line action']): actions=permutations(dual);tiles=assemble(actions) for label,t in tiles.items(): ax.add_patch(Polygon(t,facecolor='#fff1b3' if label==7 else '#edf1f6',edgecolor='none')) center=t.mean(axis=0);ax.text(*center,str(label),ha='center',va='center',fontsize=12) for side,p in enumerate(actions): endpoints=[i for i in range(3) if i!=side];edge=t[endpoints] if p[label-1]==label-1:ax.plot(*edge.T,color='#17232f',lw=2.4) elif label