#!/usr/bin/env python3 """Render the alby-automation icon. Composes one canonical bolt shape three times: a large vertical main bolt + two smaller branches rotated outward, so all three read as the same primitive.""" import math from PIL import Image, ImageDraw SIZE = 1024 AMBER = (245, 166, 35, 255) DARK_BG = (24, 28, 36, 255) LIGHT_BG = (245, 247, 250, 255) # Canonical bolt polygon, top tip at origin, descending in +y direction. # Designed once; transforms compose the icon. BOLT = [ (50, 0), # top vertex (slightly right of axis for the classic tilt) (-110, 175), # outer-left shoulder (-30, 175), # inner-left (after the horizontal cut) (-50, 350), # bottom tip (110, 100), # outer-right shoulder (rebound side) (-10, 100), # inner-right (after the cut) ] def transform(points, scale=1.0, rotate_deg=0, translate=(0, 0)): a = math.radians(rotate_deg) cos_a, sin_a = math.cos(a), math.sin(a) tx, ty = translate out = [] for x, y in points: x *= scale y *= scale rx = x * cos_a - y * sin_a ry = x * sin_a + y * cos_a out.append((rx + tx, ry + ty)) return out def mirror_x(points): return [(-x, y) for (x, y) in points] def compose_bolts(): # Main bolt: vertical, top portion of canvas, scale 1.5 main = transform(BOLT, scale=1.5, rotate_deg=0, translate=(515, 100)) # Left branch: scale 1.0, rotate +28° (leans down-left), top tip lands at (450, 590) # so it appears to emerge from the main bolt's lower body left = transform(BOLT, scale=1.0, rotate_deg=28, translate=(405.9, 566.5)) # Right branch: mirrored bolt, rotated -28°, top tip lands at (575, 590) right = transform(mirror_x(BOLT), scale=1.0, rotate_deg=-28, translate=(619.1, 566.5)) return main, left, right def draw_bolts(draw): for poly in compose_bolts(): draw.polygon(poly, fill=AMBER) def make_transparent(): img = Image.new("RGBA", (SIZE, SIZE), (0, 0, 0, 0)) draw_bolts(ImageDraw.Draw(img)) return img def make_with_bg(bg_color, radius_fraction=0.22): img = Image.new("RGBA", (SIZE, SIZE), (0, 0, 0, 0)) radius = int(SIZE * radius_fraction) bg = Image.new("RGBA", (SIZE, SIZE), (0, 0, 0, 0)) ImageDraw.Draw(bg).rounded_rectangle((0, 0, SIZE - 1, SIZE - 1), radius=radius, fill=bg_color) img = Image.alpha_composite(img, bg) draw_bolts(ImageDraw.Draw(img)) return img def export_svg(path): polys = compose_bolts() parts = ['', ''] for poly in polys: points = " ".join(f"{x:.1f},{y:.1f}" for x, y in poly) parts.append(f' ') parts.append('') with open(path, "w") as f: f.write("\n".join(parts) + "\n") def main(): out = "." transparent = make_transparent() transparent.save(f"{out}/icon-transparent-1024.png") transparent.resize((256, 256), Image.LANCZOS).save(f"{out}/icon-transparent-256.png") transparent.resize((64, 64), Image.LANCZOS).save(f"{out}/icon-transparent-64.png") make_with_bg(DARK_BG).save(f"{out}/icon-dark-bg-1024.png") make_with_bg(LIGHT_BG).save(f"{out}/icon-light-bg-1024.png") export_svg(f"{out}/icon.svg") print("rendered 5 PNG variants + SVG") if __name__ == "__main__": main()