← back to Penrose Designs
penrose: add Photoshop Penrose Tiling Generator (recolorable component-layer PSD)
1715b9b2fd715cb8a6b721234abb3c5fca0eea9a · 2026-07-23 09:27:54 -0700 · Steve
Files touched
Diff
commit 1715b9b2fd715cb8a6b721234abb3c5fca0eea9a
Author: Steve <steve@designerwallcoverings.com>
Date: Thu Jul 23 09:27:54 2026 -0700
penrose: add Photoshop Penrose Tiling Generator (recolorable component-layer PSD)
---
generator.py | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 48 insertions(+)
diff --git a/generator.py b/generator.py
new file mode 100644
index 0000000..786e243
--- /dev/null
+++ b/generator.py
@@ -0,0 +1,48 @@
+#!/usr/bin/env python3
+# Penrose Tiling GENERATOR for Photoshop — decompose ONE tiling into recolorable component layers.
+# Layers: Background / Thin rhombi / Fat rhombi / Seams -> edit each layer's color to "generate" a colorway.
+import cmath, math
+from PIL import Image, ImageDraw
+PHI=(1+5**0.5)/2
+def subdivide(t):
+ o=[]
+ for c,A,B,C in t:
+ if c==0:
+ P=A+(B-A)/PHI; o+=[(0,C,P,B),(1,P,C,A)]
+ else:
+ Q=B+(A-B)/PHI; R=B+(C-B)/PHI; o+=[(1,R,C,A),(1,Q,R,B),(0,R,Q,A)]
+ return o
+def wheel():
+ t=[]
+ for i in range(10):
+ B=cmath.rect(1,(2*i-1)*math.pi/10); C=cmath.rect(1,(2*i+1)*math.pi/10)
+ if i%2==0: B,C=C,B
+ t.append((0,0j,B,C))
+ return t
+def build(d):
+ t=wheel()
+ for _ in range(d): t=subdivide(t)
+ return t
+def hx(h): h=h.lstrip('#'); return tuple(int(h[i:i+2],16) for i in (0,2,4))
+
+SIZE=3000; DEPTH=7; ROT=0.0
+FAT=hx("#C9A24B"); THIN=hx("#D8CCB4"); SEAM=hx("#2B2622"); BG=hx("#EDE7DA") # default "Oatmeal & Brass" colorway
+tris=build(DEPTH)
+r=cmath.rect(1,ROT); R=max(abs(z) for _,A,B,C in tris for z in (A,B,C))
+sc=SIZE*0.82/R; cx=cy=SIZE/2
+def P(z):
+ z=z*r; return (cx+z.real*sc, cy+z.imag*sc)
+ew=max(2,int(SIZE/700))
+
+def blank(): return Image.new("RGBA",(SIZE,SIZE),(0,0,0,0))
+fat=blank(); thin=blank(); seam=blank()
+df=ImageDraw.Draw(fat); dt=ImageDraw.Draw(thin); ds=ImageDraw.Draw(seam)
+for c,A,B,C in tris:
+ poly=[P(A),P(B),P(C)]
+ (df if c==1 else dt).polygon(poly, fill=(FAT+(255,) if c==1 else THIN+(255,)))
+for c,A,B,C in tris:
+ ds.line([P(A),P(B)], fill=SEAM+(255,), width=ew); ds.line([P(A),P(C)], fill=SEAM+(255,), width=ew)
+bg=Image.new("RGBA",(SIZE,SIZE),BG+(255,))
+for name,im in [("bg",bg),("thin",thin),("fat",fat),("seam",seam)]:
+ im.save(f"out/gen_{name}.png")
+print(f"generator layers rendered @ {SIZE}px depth{DEPTH} tris={len(tris)}")
← 67552e3 penrose tiling: 20-design generator + layered PSD build
·
back to Penrose Designs
·
(newest)