Doku-Konsistenz 3/4: Board-Layout auf Pucks, veraltete Diagramme entfernt
- gen_board_layout.py zeichnet jetzt runde Pucks (Aussenring + 7 Figurenmulden + zentrales Etikett, Gate-Puck rot) statt eckiger Steck-Tiles; board-layout.svg neu generiert (40 Pucks, well-formed XML). - Entfernt (veraltet, nirgends referenziert, hier nicht verifizierbar neu zeichenbar): board-layout.png (alte Tiles), bauteile-masse.svg, 00_Konzept/raci-aktiv-feld.svg, raci-tile-variante.svg. Massgeblich bleiben materialliste.md + die OpenSCAD-Modelle (echte Renderings). - README_3d-druck Inhaltstabelle nachgezogen. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
300dc17740
commit
ab61222cf2
7 changed files with 555 additions and 703 deletions
|
|
@ -1,10 +1,12 @@
|
|||
#!/usr/bin/env python3
|
||||
"""Generiert die Board-Layout-Skizze (SVG) fuer den SLC-Workshop.
|
||||
Lineares Phasen-Swimlane-Layout: jede Phase eine Zeile, Tiles links->rechts.
|
||||
Exakt 40 Tiles (37 Aktivitaeten + 3 Gates). Reproduzierbar: bei Aenderungen
|
||||
Lineares Phasen-Swimlane-Layout: jede Phase eine Zeile, Pucks links->rechts.
|
||||
Exakt 40 Pucks (37 Aktivitaeten + 3 Gate-Pucks). Reproduzierbar: bei Aenderungen
|
||||
einfach erneut ausfuehren -> board-layout.svg.
|
||||
"""
|
||||
|
||||
import math
|
||||
|
||||
# (id, kurzname, is_gate)
|
||||
PHASES = [
|
||||
("DESIGN", "#2F80C9", [
|
||||
|
|
@ -60,15 +62,16 @@ PHASES = [
|
|||
]
|
||||
|
||||
# Layout-Parameter
|
||||
TILE_W, TILE_H = 112, 74
|
||||
GAP_X, GAP_Y = 16, 46
|
||||
TILE_W, TILE_H = 86, 86 # Zelle je Puck (rund, inscribed)
|
||||
GAP_X, GAP_Y = 12, 40
|
||||
PUCK_R = 35 # Puck-Radius in px (= Ø100 mm)
|
||||
LABEL_W = 150
|
||||
X0 = 30 + LABEL_W + 20
|
||||
Y0 = 96
|
||||
MAX_TILES = max(len(t) for _, _, t in PHASES)
|
||||
WIDTH = X0 + MAX_TILES * (TILE_W + GAP_X) + 200
|
||||
HEIGHT = Y0 + len(PHASES) * (TILE_H + GAP_Y) + 120
|
||||
TILE_MM = 100 # ein Tile = 100x100 mm
|
||||
TILE_MM = 100 # ein Puck = Ø100 mm
|
||||
|
||||
|
||||
def esc(s):
|
||||
|
|
@ -85,32 +88,33 @@ def lighten(hexcol, f=0.85):
|
|||
|
||||
|
||||
def tile_svg(x, y, tid, name, color, is_gate):
|
||||
fill = color if is_gate else lighten(color, 0.88)
|
||||
"""Zeichnet einen runden Puck: Aussenring, 7 Figurenmulden, zentrales Etikett."""
|
||||
cx, cy = x + TILE_W / 2.0, y + TILE_H / 2.0
|
||||
fill = color if is_gate else lighten(color, 0.90)
|
||||
stroke = color
|
||||
sw = 3 if is_gate else 2
|
||||
txtcol = "#ffffff" if is_gate else "#1a1a1a"
|
||||
parts = []
|
||||
# Puzzle-Notch links (Hintergrundfarbe), Bump rechts (Randfarbe)
|
||||
parts.append(f'<circle cx="{x}" cy="{y+TILE_H/2}" r="9" fill="#f7f7f5"/>')
|
||||
parts.append(f'<rect x="{x}" y="{y}" width="{TILE_W}" height="{TILE_H}" rx="9" '
|
||||
# Puck-Koerper
|
||||
parts.append(f'<circle cx="{cx}" cy="{cy}" r="{PUCK_R}" '
|
||||
f'fill="{fill}" stroke="{stroke}" stroke-width="{sw}"/>')
|
||||
parts.append(f'<circle cx="{x+TILE_W}" cy="{y+TILE_H/2}" r="8" fill="{stroke}"/>')
|
||||
# 7 Figurenmulden im Ring
|
||||
for k in range(7):
|
||||
a = math.radians(360.0 / 7 * k - 90)
|
||||
wx = cx + (PUCK_R - 8) * math.cos(a)
|
||||
wy = cy + (PUCK_R - 8) * math.sin(a)
|
||||
parts.append(f'<circle cx="{wx:.1f}" cy="{wy:.1f}" r="3" fill="none" '
|
||||
f'stroke="{stroke}" stroke-width="1.1" opacity="0.6"/>')
|
||||
# zentrales Etikett-Feld
|
||||
parts.append(f'<circle cx="{cx}" cy="{cy}" r="16" fill="#ffffff" '
|
||||
f'opacity="0.92" stroke="{stroke}" stroke-width="0.8"/>')
|
||||
parts.append(f'<text x="{cx}" y="{cy+0.5}" text-anchor="middle" '
|
||||
f'font-size="11.5" font-weight="700" fill="#1a1a1a">{esc(tid)}</text>')
|
||||
# Name unter dem Puck
|
||||
parts.append(f'<text x="{cx}" y="{cy+PUCK_R+12}" text-anchor="middle" '
|
||||
f'font-size="9.5" fill="#333">{esc(name)}</text>')
|
||||
if is_gate:
|
||||
# kleiner Torbogen + GATE-Label
|
||||
ax, ay = x + TILE_W/2, y + 14
|
||||
parts.append(f'<path d="M {ax-12} {ay+18} V {ay+4} A 12 12 0 0 1 {ax+12} {ay+4} '
|
||||
f'V {ay+18}" fill="none" stroke="#ffffff" stroke-width="3"/>')
|
||||
parts.append(f'<text x="{x+TILE_W/2}" y="{y+TILE_H-22}" text-anchor="middle" '
|
||||
f'font-size="14" font-weight="700" fill="{txtcol}">{esc(tid)}</text>')
|
||||
parts.append(f'<text x="{x+TILE_W/2}" y="{y+TILE_H-7}" text-anchor="middle" '
|
||||
f'font-size="10.5" fill="{txtcol}">{esc(name)}</text>')
|
||||
else:
|
||||
parts.append(f'<circle cx="{x+18}" cy="{y+18}" r="7" fill="none" '
|
||||
f'stroke="{stroke}" stroke-width="1.5"/>') # Verankerung
|
||||
parts.append(f'<text x="{x+TILE_W/2}" y="{y+30}" text-anchor="middle" '
|
||||
f'font-size="15" font-weight="700" fill="{txtcol}">{esc(tid)}</text>')
|
||||
parts.append(f'<text x="{x+TILE_W/2}" y="{y+52}" text-anchor="middle" '
|
||||
f'font-size="10" fill="#333">{esc(name)}</text>')
|
||||
parts.append(f'<text x="{cx}" y="{cy-PUCK_R-5}" text-anchor="middle" '
|
||||
f'font-size="10" font-weight="700" fill="{stroke}">GATE</text>')
|
||||
return "\n".join(parts)
|
||||
|
||||
|
||||
|
|
@ -128,10 +132,10 @@ svg.append('<defs><marker id="ah" markerWidth="9" markerHeight="9" refX="7" refY
|
|||
'<path d="M0,0 L7,3 L0,6 Z" fill="#666"/></marker></defs>')
|
||||
# Titel
|
||||
svg.append(f'<text x="30" y="44" font-size="26" font-weight="800" fill="#1a1a1a">'
|
||||
f'Service-Lifecycle — Board-Layout (40 Tiles)</text>')
|
||||
f'Service-Lifecycle — Board-Layout (40 Pucks)</text>')
|
||||
svg.append(f'<text x="30" y="68" font-size="14" fill="#555">'
|
||||
f'37 Aktivitaeten + 3 Gates · 1 Tile = {TILE_MM}x{TILE_MM} mm · '
|
||||
f'lineare Bahn, Sequenz links nach rechts</text>')
|
||||
f'37 Aktivitaeten + 3 Gate-Pucks · 1 Puck = Ø{TILE_MM} mm · '
|
||||
f'lose Bahn, Sequenz links nach rechts</text>')
|
||||
|
||||
row_y = {}
|
||||
for ri, (pname, color, tiles) in enumerate(PHASES):
|
||||
|
|
@ -143,7 +147,7 @@ for ri, (pname, color, tiles) in enumerate(PHASES):
|
|||
svg.append(f'<text x="{30+LABEL_W/2}" y="{y+TILE_H/2-2}" text-anchor="middle" '
|
||||
f'font-size="17" font-weight="800" fill="#fff">{esc(pname)}</text>')
|
||||
svg.append(f'<text x="{30+LABEL_W/2}" y="{y+TILE_H/2+18}" text-anchor="middle" '
|
||||
f'font-size="12" fill="#fff">{len(tiles)} Tiles</text>')
|
||||
f'font-size="12" fill="#fff">{len(tiles)} Pucks</text>')
|
||||
# Tiles
|
||||
prev = None
|
||||
for ti, (tid, name, is_gate) in enumerate(tiles):
|
||||
|
|
@ -179,16 +183,16 @@ svg.append(f'<text x="{rx+78}" y="{ry+12}" font-size="11" fill="#666">'
|
|||
|
||||
# Legende / Massstab
|
||||
ly = HEIGHT - 64
|
||||
svg.append(f'<rect x="30" y="{ly}" width="26" height="18" rx="4" fill="#E8893B"/>')
|
||||
svg.append(f'<text x="64" y="{ly+14}" font-size="12.5" fill="#333">Gate-Tile (Tor mit Rollen-Steckplaetzen)</text>')
|
||||
svg.append(f'<rect x="360" y="{ly}" width="26" height="18" rx="4" fill="{lighten("#2F80C9",0.88)}" stroke="#2F80C9" stroke-width="2"/>')
|
||||
svg.append(f'<text x="394" y="{ly+14}" font-size="12.5" fill="#333">Aktivitaets-Tile (mit Verankerung fuer einseitiges Plaettchen)</text>')
|
||||
svg.append(f'<circle cx="43" cy="{ly+9}" r="10" fill="#d23"/>')
|
||||
svg.append(f'<text x="60" y="{ly+14}" font-size="12.5" fill="#333">Gate-Puck (rot, Etikett G1/G2/G3 + Icon)</text>')
|
||||
svg.append(f'<circle cx="373" cy="{ly+9}" r="10" fill="{lighten("#2F80C9",0.90)}" stroke="#2F80C9" stroke-width="2"/>')
|
||||
svg.append(f'<text x="390" y="{ly+14}" font-size="12.5" fill="#333">Station-Puck (Ø100, 7 Figurenmulden + Etikett)</text>')
|
||||
|
||||
# Gesamtbreite-Hinweis
|
||||
total_mm = MAX_TILES * (TILE_MM + 12)
|
||||
total_mm = MAX_TILES * (TILE_MM + 10)
|
||||
svg.append(f'<text x="30" y="{HEIGHT-28}" font-size="12.5" fill="#555">'
|
||||
f'Breiteste Phase: {MAX_TILES} Tiles ~ {total_mm/10:.0f} cm '
|
||||
f'(bei {TILE_MM} mm Tiles + 12 mm Verbinder). Bahn bei Platzmangel maeandrierend faltbar.</text>')
|
||||
f'Breiteste Phase: {MAX_TILES} Pucks ~ {total_mm/10:.0f} cm '
|
||||
f'(bei Ø{TILE_MM} mm Pucks + ~10 mm Abstand). Bahn bei Platzmangel maeandrierend.</text>')
|
||||
|
||||
svg.append('</svg>')
|
||||
|
||||
|
|
@ -199,4 +203,4 @@ with open(out, "w", encoding="utf-8") as f:
|
|||
total = sum(len(t) for _, _, t in PHASES)
|
||||
gates = sum(1 for _, _, t in PHASES for _, _, g in t if g)
|
||||
print(f"geschrieben: {out}")
|
||||
print(f"Tiles gesamt: {total} (Aktivitaeten: {total-gates}, Gates: {gates})")
|
||||
print(f"Pucks gesamt: {total} (Aktivitaeten: {total-gates}, Gate-Pucks: {gates})")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue