# Textures for a friend's truck: wheel rim (cylinder caps), trailer side livery, trailer rear doors. # Run with local/hear-venv python. Small sizes on purpose (big textures lag everyone). # Claude Opus 5.5 (Tessel), 2026-10-11. import math from pathlib import Path from PIL import Image, ImageDraw, ImageFont HERE = Path(__file__).parent F = "C:/Windows/Fonts/" def rim(): S = 256 * 4 im = Image.new("RGB", (S, S), (18, 18, 20)) d = ImageDraw.Draw(im) c = S / 2 def disc(r, col): d.ellipse([c - r, c - r, c + r, c + r], fill=col) disc(S * 0.5, (22, 22, 24)) # tread edge disc(S * 0.47, (38, 38, 42)) # sidewall disc(S * 0.31, (200, 203, 210)) # chrome rim disc(S * 0.28, (150, 154, 162)) # five dark windows so the spin reads for k in range(5): a = k * 2 * math.pi / 5 x, y = c + math.cos(a) * S * 0.19, c + math.sin(a) * S * 0.19 r = S * 0.055 d.ellipse([x - r, y - r, x + r, y + r], fill=(40, 40, 46)) disc(S * 0.11, (215, 218, 224)) # hub for k in range(6): a = k * 2 * math.pi / 6 + 0.3 x, y = c + math.cos(a) * S * 0.075, c + math.sin(a) * S * 0.075 r = S * 0.014 d.ellipse([x - r, y - r, x + r, y + r], fill=(90, 90, 96)) # a red stripe on the sidewall: one more cue for the eye d.arc([c - S * 0.4, c - S * 0.4, c + S * 0.4, c + S * 0.4], 200, 260, fill=(190, 40, 40), width=int(S * 0.025)) im.resize((256, 256), Image.LANCZOS).save(HERE / "rim.png") def fish(d, x, y, s, col, eye=(20, 30, 60)): # a leaping fish facing right, centred at x,y, length s body = [x - s * 0.35, y - s * 0.17, x + s * 0.35, y + s * 0.17] d.ellipse(body, fill=col) d.polygon([(x - s * 0.3, y), (x - s * 0.55, y - s * 0.2), (x - s * 0.5, y), (x - s * 0.55, y + s * 0.2)], fill=col) d.polygon([(x - s * 0.05, y - s * 0.15), (x + s * 0.12, y - s * 0.3), (x + s * 0.15, y - s * 0.12)], fill=col) r = s * 0.04 d.ellipse([x + s * 0.2 - r, y - s * 0.05 - r, x + s * 0.2 + r, y - s * 0.05 + r], fill=eye) def side(): W, H = 1024, 512 im = Image.new("RGB", (W, H), (246, 246, 242)) d = ImageDraw.Draw(im) d.rectangle([0, H * 0.78, W, H * 0.86], fill=(30, 70, 150)) d.rectangle([0, H * 0.88, W, H * 0.91], fill=(240, 150, 40)) # waves for i in range(0, W, 64): d.arc([i, H * 0.68, i + 64, H * 0.78], 200, 340, fill=(60, 120, 200), width=8) fish(d, W * 0.19, H * 0.42, 300, (245, 130, 30)) for k, (dx, dy) in enumerate([(-20, -60), (-45, -10), (-15, 40)]): r = 10 - k * 2 d.ellipse([W * 0.33 + dx - r, H * 0.25 + dy - r, W * 0.33 + dx + r, H * 0.25 + dy + r], outline=(60, 120, 200), width=4) big = ImageFont.truetype(F + "impact.ttf", 104) small = ImageFont.truetype(F + "segoeuib.ttf", 44) d.text((W * 0.37, H * 0.08), "(name left off this copy)", font=big, fill=(30, 70, 150)) d.text((W * 0.37, H * 0.31), "FREIGHT CO.", font=big, fill=(30, 70, 150)) d.text((W * 0.375, H * 0.555), "fresh from the sea", font=small, fill=(200, 100, 20)) im.resize((512, 256), Image.LANCZOS).save(HERE / "side.png") def rear(): W = H = 512 im = Image.new("RGB", (W, H), (226, 226, 222)) d = ImageDraw.Draw(im) d.rectangle([4, 4, W - 5, H - 5], outline=(150, 150, 150), width=10) d.line([W / 2, 0, W / 2, H], fill=(130, 130, 130), width=8) for x in (W * 0.3, W * 0.7): d.rectangle([x - 10, H * 0.1, x + 10, H * 0.9], fill=(170, 172, 176)) d.rectangle([x - 26, H * 0.45, x + 26, H * 0.55], fill=(120, 122, 128)) fish(d, W / 2, H * 0.22, 120, (245, 130, 30)) im.resize((256, 256), Image.LANCZOS).save(HERE / "rear.png") rim(); side(); rear() print("ok")