#!/usr/bin/env python3
"""Generate the modular bougainvillea laser-cut SVG (real mm coordinates).

Module = 1 centre circle (pistil/joint) + 3 equilateral triangles (bracts)
         + 3 assembly holes at the outer vertices.
Unit circumradius 30mm -> tessellation pitch 60mm. 4x4 array on 300x300mm.
"""
import math

R_PISTIL = 15.0      # centre circle radius
R_UNIT = 30.0        # distance centre -> outer vertex
R_HOLE = 3.0         # assembly hole radius
PITCH = 60.0         # tessellation pitch
N = 4                # 4x4 array
CANVAS = 300.0       # mm

SQ3 = math.sqrt(3.0)

def unit(cx, cy):
    """Return SVG elements for one module centred at (cx, cy), all in mm."""
    # Base points on the pistil circle, 120 deg apart
    p0 = (cx + R_PISTIL, cy)
    p1 = (cx - R_PISTIL / 2, cy + R_PISTIL * SQ3 / 2)
    p2 = (cx - R_PISTIL / 2, cy - R_PISTIL * SQ3 / 2)
    # Outer vertices (at 60/180/300 deg, distance R_UNIT)
    v1 = (cx + R_UNIT / 2, cy + R_UNIT * SQ3 / 2)
    v2 = (cx - R_UNIT, cy)
    v3 = (cx + R_UNIT / 2, cy - R_UNIT * SQ3 / 2)

    els = []
    els.append(f'    <circle cx="{cx:.2f}" cy="{cy:.2f}" r="{R_PISTIL:.2f}"/>')
    els.append(f'    <polygon points="{p0[0]:.2f},{p0[1]:.2f} {p1[0]:.2f},{p1[1]:.2f} {v1[0]:.2f},{v1[1]:.2f}"/>')
    els.append(f'    <polygon points="{p1[0]:.2f},{p1[1]:.2f} {p2[0]:.2f},{p2[1]:.2f} {v2[0]:.2f},{v2[1]:.2f}"/>')
    els.append(f'    <polygon points="{p2[0]:.2f},{p2[1]:.2f} {p0[0]:.2f},{p0[1]:.2f} {v3[0]:.2f},{v3[1]:.2f}"/>')
    for (hx, hy) in (v1, v2, v3):
        els.append(f'    <circle cx="{hx:.2f}" cy="{hy:.2f}" r="{R_HOLE:.2f}"/>')
    return els

svg = ['<?xml version="1.0" encoding="UTF-8"?>',
       '<svg xmlns="http://www.w3.org/2000/svg"',
       f'     width="{CANVAS}mm" height="{CANVAS}mm" viewBox="0 0 {CANVAS:.0f} {CANVAS:.0f}">',
       '',
       '  <title>Modular Bougainvillea — Laser Cut Pattern</title>',
       '  <desc>One module = 1 pistil circle (r15) + 3 equilateral bract triangles',
       '        (unit circumradius 30mm) + 3 assembly holes (r3) at outer vertices.',
       '        Pitch 60mm, 4x4 tessellation on 300x300mm sheet.',
       '        Red hairline strokes = cut lines, no kerf compensation.</desc>',
       '',
       '  <g fill="none" stroke="#ff0000" stroke-width="0.2" stroke-linejoin="miter">']

for cy in range(N):
    for cx in range(N):
        x = PITCH * (cx + 1)
        y = PITCH * (cy + 1)
        svg.append(f'    <!-- module at ({x:.0f},{y:.0f}) -->')
        svg.extend(unit(x, y))

svg += ['  </g>', '</svg>', '']

out = "/Users/kathy/WorkBuddy/2026-10-10-13-30-00/bougainvillea_modular.svg"
with open(out, "w", encoding="utf-8") as f:
    f.write("\n".join(svg))
print(f"OK: {N*N} modules -> {out}")
