kiwi/scripts/logo/generate_disc.py
pyr0ball c18bfec8f5
Some checks are pending
CI / Backend (Python) (push) Waiting to run
CI / Frontend (Vue) (push) Waiting to run
Mirror / mirror (push) Waiting to run
fix(lint): add ruff config, fix all lint errors for GitHub CI
- pyproject.toml: add [tool.ruff] config suppressing E402/W293 globally,
  F841/E741/E702 in tests, E741 in scripts
- inventory.py: split semicolon import (E702)
- recipes.py: fix logger -> log (F821 undefined name)
- shopping.py: rename l -> lnk in list comprehension (E741)
- format_conversion.py: noqa F841 on CUDA flag (used as future hook)
- backfill_keywords.py: rename done -> _done (F841)
- ingest_purplecarrot.py: drop == True comparison (E712)
- Auto-fix: I001 import sorting, F401 unused imports across all files
2026-07-06 02:49:02 -07:00

114 lines
4.8 KiB
Python

#!/usr/bin/env python3
"""Generate a kiwifruit cross-section disc as SVG."""
import math
cx, cy, r = 200, 200, 190 # center and total radius
# Color palette — kiwifruit cross section
SKIN_OUTER = "#5C3D1E" # dark brown outer skin
SKIN_INNER = "#7A5230" # lighter brown inner skin edge
FLESH = "#7DC242" # bright kiwi green flesh
FLESH_DARK = "#5A9A2A" # deeper green for radial segment lines
PITH = "#F2EDD7" # cream/white center pith
PITH_SHADOW = "#D9D0B0" # slight shadow on pith edge
SEED_COLOR = "#2C1A0E" # very dark brown seeds
SEED_HILITE = "#5C3820" # seed highlight
def polar(cx, cy, radius, angle_deg):
a = math.radians(angle_deg)
return cx + radius * math.cos(a), cy + radius * math.sin(a)
lines = ['<?xml version="1.0" encoding="UTF-8"?>']
lines.append('<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 400" width="512" height="512">')
lines.append(' <defs>')
# Radial gradient for flesh (slightly darker at edges)
lines.append(' <radialGradient id="fleshGrad" cx="50%" cy="50%" r="50%">')
lines.append(f' <stop offset="0%" stop-color="{FLESH}" stop-opacity="1"/>')
lines.append(f' <stop offset="75%" stop-color="{FLESH}" stop-opacity="1"/>')
lines.append(f' <stop offset="100%" stop-color="{FLESH_DARK}" stop-opacity="1"/>')
lines.append(' </radialGradient>')
# Radial gradient for pith
lines.append(' <radialGradient id="pithGrad" cx="50%" cy="50%" r="50%">')
lines.append(' <stop offset="0%" stop-color="#FFFFFF" stop-opacity="1"/>')
lines.append(f' <stop offset="70%" stop-color="{PITH}" stop-opacity="1"/>')
lines.append(f' <stop offset="100%" stop-color="{PITH_SHADOW}" stop-opacity="1"/>')
lines.append(' </radialGradient>')
lines.append(' </defs>')
# 1. Outer skin (full circle, darkest brown)
lines.append(f' <circle cx="{cx}" cy="{cy}" r="{r}" fill="{SKIN_OUTER}"/>')
# 2. Inner skin ring (slightly lighter, slightly smaller)
lines.append(f' <circle cx="{cx}" cy="{cy}" r="{r - 12}" fill="{SKIN_INNER}"/>')
# 3. Green flesh
flesh_r = r - 22
lines.append(f' <circle cx="{cx}" cy="{cy}" r="{flesh_r}" fill="url(#fleshGrad)"/>')
# 4. Radial segment lines (subtle darker green spokes)
num_segments = 24
pith_r = 42
seed_ring_r = flesh_r * 0.52 # seeds sit about halfway between pith and skin
for i in range(num_segments):
angle = (360 / num_segments) * i
x1, y1 = polar(cx, cy, pith_r + 8, angle)
x2, y2 = polar(cx, cy, flesh_r - 4, angle)
lines.append(f' <line x1="{x1:.1f}" y1="{y1:.1f}" x2="{x2:.1f}" y2="{y2:.1f}" '
f'stroke="{FLESH_DARK}" stroke-width="1.2" stroke-opacity="0.5"/>')
# 5. Seeds — teardrop shapes arranged in a ring
num_seeds = 22
seed_major = 9 # half-length along radial axis
seed_minor = 5.5 # half-width
for i in range(num_seeds):
angle_deg = (360 / num_seeds) * i - 90 # start from top
angle_rad = math.radians(angle_deg)
# Seed center position
sx = cx + seed_ring_r * math.cos(angle_rad)
sy = cy + seed_ring_r * math.sin(angle_rad)
# Seed is an ellipse rotated to point toward center
rotate_angle = angle_deg + 90 # perpendicular to radial = tangent orientation
# Actually seeds point radially (like a pie slice tip toward center)
rotate_angle = angle_deg # point toward center
lines.append(f' <ellipse cx="{sx:.1f}" cy="{sy:.1f}" '
f'rx="{seed_minor}" ry="{seed_major}" '
f'fill="{SEED_COLOR}" '
f'transform="rotate({rotate_angle:.1f},{sx:.1f},{sy:.1f})"/>')
# Seed highlight (small inner ellipse, slightly offset)
hx = sx - seed_minor * 0.25 * math.cos(angle_rad + math.pi/2)
hy = sy - seed_minor * 0.25 * math.sin(angle_rad + math.pi/2)
lines.append(f' <ellipse cx="{hx:.1f}" cy="{hy:.1f}" '
f'rx="{seed_minor * 0.35:.1f}" ry="{seed_major * 0.35:.1f}" '
f'fill="{SEED_HILITE}" opacity="0.6" '
f'transform="rotate({rotate_angle:.1f},{hx:.1f},{hy:.1f})"/>')
# 6. Pith center (cream/white, slightly star-shaped via polygon)
# Use a slightly irregular star for the pith boundary — more organic
num_pith_points = 12
pith_points = []
for i in range(num_pith_points):
angle = (360 / num_pith_points) * i - 90
# Alternate between outer and inner radius for star effect
pr = pith_r if i % 2 == 0 else pith_r * 0.80
px, py = polar(cx, cy, pr, angle)
pith_points.append(f"{px:.1f},{py:.1f}")
lines.append(f' <polygon points="{" ".join(pith_points)}" fill="url(#pithGrad)"/>')
# 7. Tiny dot at absolute center
lines.append(f' <circle cx="{cx}" cy="{cy}" r="5" fill="{PITH_SHADOW}"/>')
lines.append('</svg>')
svg_content = '\n'.join(lines)
output_path = '/tmp/kiwi_disc.svg'
with open(output_path, 'w') as f:
f.write(svg_content)
print(f"Written to {output_path}")
print(f"Lines: {len(lines)}, Size: {len(svg_content)} bytes")