算法艺术创作
algorithmic-art
通过代码和可调参数创作生成艺术与交互式视觉效果。
create-glyph【设计与创意】Create R-based pictogram glyphs for skill, agent, or team icons in the visualization layer. Covers concept sketching, ggplot2 layer composition using the primitives library, color strategy, registration in the appropriate glyph mapping file and manifest, rendering via the build pipeline, and visual verification of the neon-glow output. Use when a new…
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
R pictogram glyphs → skill/agent/team icons in viz/. Pure-ggplot2 fn on 100x100 → neon glow → transparent WebP.
skill, agent, teamcreate-glyph, mystic, r-package-review) + domain (skills)--glow-sigma (def: 4)skills/<id>/SKILL.mdagents/<id>.mdteams/<id>.mdComplexity Tiers:
+----------+--------+-------------------------------------------+
| Tier | Layers | Examples |
+----------+--------+-------------------------------------------+
| Simple | 2 | glyph_flame, glyph_heartbeat |
| Moderate | 3-5 | glyph_document, glyph_experiment_flask |
| Complex | 6+ | glyph_ship_wheel, glyph_bridge_cpp |
+----------+--------+-------------------------------------------+
glyph_<descriptive_name> (snake_case, unique)Got: Mental sketch, 2-6 planned layers.
If err: Too abstract → concrete related. Check existing in same domain.
Write R fn → ggplot2 layers.
Signature (immutable):
glyph_<name> <- function(cx, cy, s, col, bright) {
# cx, cy = center coordinates (50, 50 on 100x100 canvas)
# s = scale factor (1.0 = fill ~70% of canvas)
# col = domain color hex (e.g., "#ff88dd" for design)
# bright = brightened variant of col (auto-computed by renderer)
# Returns: list() of ggplot2 layers
}
Apply * s to ALL dims:
r <- 20 * s # radius
hw <- 15 * s # half-width
lw <- .lw(s) # line width (default base 2.5)
lw_thin <- .lw(s, 1.2) # thinner line width
Geometry primitives:
| Geometry | Usage |
|---|---|
ggplot2::geom_polygon(data, .aes(x, y), ...) | Filled shapes |
ggplot2::geom_path(data, .aes(x, y), ...) | Open lines/curves |
ggplot2::geom_segment(data, .aes(x, xend, y, yend), ...) | Segments, arrows |
ggplot2::geom_rect(data, .aes(xmin, xmax, ymin, ymax), ...) | Rects |
ggforce::geom_circle(data, .aes(x0, y0, r), ...) | Circles |
Color strategy:
Alpha Guide:
+----------------------+------------+--------------------------+
| Purpose | Alpha | Example |
+----------------------+------------+--------------------------+
| Large fill (body) | 0.08-0.15 | hex_with_alpha(col, 0.1) |
| Medium fill (accent) | 0.15-0.25 | hex_with_alpha(col, 0.2) |
| Small fill (detail) | 0.25-0.35 | hex_with_alpha(bright, 0.3) |
| Outline stroke | 1.0 | color = bright |
| Secondary stroke | 1.0 | color = col |
| No fill | --- | fill = NA |
+----------------------+------------+--------------------------+
Return flat list() → renderer wraps each w/ glow
Place fn in right primitives file:
primitives.R — bushcraft, compliance, containerization, data-serialization, defensiveprimitives_2.R — devops, general, git, mcp-integrationprimitives_3.R — mlops, observability, PM, r-packages, reporting, review, web-dev, esoteric, designprimitives_4.R through primitives_19.R for newerviz/R/agent_primitives.Rviz/R/team_primitives.RGot: Working R fn → list of 2-6 layers.
If err: ggforce::geom_circle err → install ggforce. Coords off → canvas 100x100, (0,0) bottom-left. Test:
source("viz/R/utils.R"); source("viz/R/primitives.R") # etc.
layers <- glyph_<name>(50, 50, 1.0, "#ff88dd", "#ffa8f0")
p <- ggplot2::ggplot() + ggplot2::coord_fixed(xlim=c(0,100), ylim=c(0,100)) +
ggplot2::theme_void()
for (l in layers) p <- p + l
print(p)
Map entity → glyph.
Skills:
viz/R/glyphs.R# -- design (3))"skill-id" = "glyph_function_name",
Agents:
viz/R/agent_glyphs.RAGENT_GLYPHS:
"agent-id" = "glyph_function_name",
Teams:
Open viz/R/team_glyphs.R
Alphabetical in TEAM_GLYPHS:
"team-id" = "glyph_function_name",
Verify no dup ID
Got: *_GLYPHS list has new mapping.
If err: "No glyph mapped" → check ID exact match vs manifest + registry.
Register icon.
Skills: viz/data/icon-manifest.json
{
"skillId": "skill-id",
"domain": "domain-name",
"prompt": "<domain basePrompt>, <descriptors>, dark background, vector art",
"seed": <next_seed>,
"path": "public/icons/cyberpunk/<domain>/<skill-id>.webp",
"status": "pending"
}
Agents: viz/data/agent-icon-manifest.json
{
"agentId": "agent-id",
"prompt": "<agent-specific descriptors>, dark background, vector art",
"seed": <next_seed>,
"path": "public/icons/cyberpunk/agents/<agent-id>.webp",
"status": "pending"
}
Teams: viz/data/team-icon-manifest.json
{
"teamId": "team-id",
"prompt": "<team-specific descriptors>, dark background, vector art",
"seed": <next_seed>,
"path": "public/icons/cyberpunk/teams/<team-id>.webp",
"status": "pending"
}
Got: Valid JSON, entry among type siblings.
If err: Validate syntax. Common: trailing comma after last elem, missing quotes.
Run pipeline. Always build.sh → platform detect + R binary. See render-icon-pipeline.
# From project root — renders all palettes, standard + HD, skips existing icons
bash viz/build.sh --only <domain> --skip-existing # skills
bash viz/build.sh --type agent --only <id> --skip-existing # agents
bash viz/build.sh --type team --only <id> --skip-existing # teams
# Dry run first:
bash viz/build.sh --only <domain> --dry-run
build.sh = full pipeline (palette → data → manifest → render → terminal glyphs). Non-render steps +~10s but ensure current.
Out:
viz/public/icons/<palette>/<domain>/<skill-id>.webpviz/public/icons/<palette>/agents/<agent-id>.webpviz/public/icons/<palette>/teams/<team-id>.webpGot: Log OK: <entity> (seed=XXXXX, XX.XKB), WebP exists.
If err:
"No glyph mapped" — Step 3 missing / typo"Unknown domain" — Not in get_palette_colors() in palettes.Rinstall.packages(c("ggplot2", "ggforce", "ggfx", "ragg", "magick"))Check file + size:
ls -la viz/public/icons/cyberpunk/<type-path>/<entity-id>.webp
# Expected: 15-80 KB typical range
Open WebP → check:
Small sizes (~40-160px in graph):
Got: Clear pictogram + even glow + transparent BG.
If err:
--glow-sigma 2--glow-sigma 8.lw(s, base) higher)Common adjustments:
.lw(s, base) → base = 3.0 / 3.5s multipliers (20 * s → 24 * s)Re-render:
# Delete the existing icon first, then re-render
rm viz/public/icons/cyberpunk/<type-path>/<entity-id>.webp
# Use the appropriate build command from Step 5
When done → manifest status = "done" (auto on success)
Got: Icon passes Step 6.
If err: 3+ iter fail → try diff metaphor (→ Step 1).
All domain colors (skills) in viz/R/palettes.R (single truth). Agent/team colors same. Cyberpunk (hand-tuned neon) in get_cyberpunk_colors(). Viridis auto via viridisLite.
Lookup:
source("viz/R/palettes.R")
get_palette_colors("cyberpunk")$domains[["design"]] # skill domain
get_palette_colors("cyberpunk")$agents[["mystic"]] # agent
get_palette_colors("cyberpunk")$teams[["tending"]] # team
New domain → 3 places in palettes.R:
PALETTE_DOMAIN_ORDER (alphabetical)get_cyberpunk_colors() domains listbash viz/build.sh → regen palettes + data + manifestsFull catalog in primitives source:
viz/R/primitives.R → viz/R/primitives_19.R (domain-grouped)viz/R/agent_primitives.Rviz/R/team_primitives.R| Fn | Sig | Purpose |
|---|---|---|
.lw(s, base) | (scale, base=2.5) | Scale-aware line width |
.aes(...) | alias for ggplot2::aes | Shorthand aes map |
hex_with_alpha(hex, alpha) | (string, 0-1) | Alpha on hex |
brighten_hex(hex, factor) | (string, factor=1.3) | Brighten |
dim_hex(hex, factor) | (string, factor=0.4) | Dim |
glyph_<name>(cx, cy, s, col, bright) -> list()* scol fills, bright outlines, hex_with_alpha() transparency*_glyphs.R"status": "pending""done" post-render* s: Hard-coded px breaks on scale. Multiply by s always.y = UP.ggfx::with_outer_glow(). Do NOT add in fn.get_cyberpunk_colors() → render err. Add color first.primitives*.R, agents → agent_primitives.R, teams → team_primitives.R.