# The rule behind the top image of "The rule is the work. A prompt is a wish." (JAEV Editorial, Oct 2026).
# Renders the 72-pass walk, a thumbnail and the annotated first pass. Needs Python 3 and Pillow. JAEV, CC BY 4.0.
import math
from PIL import Image, ImageDraw, ImageFont
TEXT="The rule is the work. A prompt is a wish."
turn=lambda c: 60 if c.lower() in "aeiou" else (-25 if c.isalpha() else 0)
def walk(reps):
    x=y=0.0; h=-90.0; pts=[(0,0)]; chars=[]
    for _ in range(reps):
        for c in TEXT:
            x+=math.cos(math.radians(h)); y+=math.sin(math.radians(h)); pts.append((x,y)); chars.append(c); h+=turn(c)
    return pts,chars
OUT="./"  # images are written to the current folder
pts,_=walk(72); print("closes:", round(pts[-1][0],6), round(pts[-1][1],6))
def fit(pts,W,H,pad):
    xs=[p[0] for p in pts]; ys=[p[1] for p in pts]
    s=min(W*(1-2*pad)/(max(xs)-min(xs)), H*(1-2*pad)/(max(ys)-min(ys)))
    ox=W/2-(max(xs)+min(xs))/2*s; oy=H/2-(max(ys)+min(ys))/2*s
    return lambda p:(ox+p[0]*s, oy+p[1]*s)
S=3; W=H=1600
im=Image.new("RGB",(W*S,H*S),(246,244,239)); d=ImageDraw.Draw(im); f=fit(pts,W*S,H*S,0.07)
d.line([f(p) for p in pts], fill=(22,22,22), width=2*S, joint="curve")
im=im.resize((W,H),Image.LANCZOS); im.save(OUT+"rule-sentence-walk-jaev.jpg",quality=90)
im.crop((300,0,1500,1600)).resize((600,800),Image.LANCZOS).save(OUT+"rule-prompt-thumb.jpg",quality=86)
# first pass, annotated
p1,ch=walk(1); W,H=1600,1000
im=Image.new("RGB",(W*S,H*S),(246,244,239)); d=ImageDraw.Draw(im); f=fit(p1,W*S,H*S,0.12)
d.line([f(p) for p in p1], fill=(22,22,22), width=3*S, joint="curve")
try: font=ImageFont.truetype("/System/Library/Fonts/Supplemental/Courier New.ttf", 26*S)
except OSError: font=ImageFont.load_default()
for p,c in zip(p1[1:],ch):
    x,y=f(p); col=(200,40,30) if c.lower() in "aeiou" else ((22,22,22) if c.isalpha() else (150,150,150))
    d.ellipse((x-5*S,y-5*S,x+5*S,y+5*S), fill=col)
    if c.strip(): d.text((x+9*S,y-30*S), c, fill=col, font=font)
x,y=f(p1[0]); d.rectangle((x-8*S,y-8*S,x+8*S,y+8*S), outline=(22,22,22), width=2*S)
im.resize((W,H),Image.LANCZOS).save(OUT+"rule-sentence-first-pass-jaev.jpg",quality=90)
