Prompt utilisé pour régénérer cette page :
Page: Image Evolution - Hill Climbing Polygon Evolution
Title: "Image Evolution"
Description: "Recreate images through genetic polygon evolution"
Icon: "image-filter-hdr"
Tags: ["genetic", "image"]
Status: ["validated"]
Category: artificial-intelligence
=== STRUCTURE ===
index.md front matter:
title: "Image Evolution"
description: "Recreate images through genetic polygon evolution"
icon: "image-filter-hdr"
tags: ["genetic", "image"]
status: ["validated"]
index.md body:
<section class="canvas-pair">
<figure class="canvas-wrapper">
<canvas id="target-canvas" width="300" height="300"></canvas>
<figcaption>Target</figcaption>
</figure>
<figure class="canvas-wrapper">
<canvas id="evolved-canvas" width="300" height="300"></canvas>
<figcaption>Evolved</figcaption>
</figure>
</section>
=== WIDGET FILES ===
_stats.right.md (weight: 10, title: "Statistics"):
<dl> with 3 stat items:
- Generation (id="stat-generation", init "0")
- Similarity (id="stat-similarity", init "0%")
- Polygons (id="stat-polygons", init "50")
Then: <progress id="fitness-bar" value="0" max="100"></progress>
_controls.right.md (weight: 20, title: "Controls"):
<h5>Settings</h5> then <dl> with 6 options:
- Target select (id="target-select"): Circle, Shapes (selected), Gradient, Mondrian, Circles, Face
- Size select (id="size-select"): 100px, 200px, 300px (selected), 400px
- Polygons number (id="polygon-count"): min=10, max=200, value=50
- Speed range (id="speed"): min=1, max=50, value=10
- Triangles checkbox (id="use-triangles"): unchecked
- Annealing checkbox (id="use-annealing"): unchecked
Then <div class="image-controls"> with 4 icon buttons:
- {{< button id="btn-start" icon="play" aria="Start" class="is-start" >}}
- {{< button id="btn-pause" icon="pause" aria="Pause" class="is-pause" >}}
- {{< button id="btn-reset" icon="refresh" aria="Reset" >}}
- {{< button id="btn-export" icon="download" aria="Export PNG" >}}
_source.after.md (weight: 90, title: "Algorithm"):
H3 "Hill Climbing" + explanation:
- How It Works: 5 steps (Initialize, Mutate, Evaluate, Accept/Reject, Repeat)
- Mutation Types: Color 30% (RGBA +-25 or alpha +-0.1), Vertex 40% (+-10px), Translation 30% (+-10px)
- Why It Works: Greedy, Simple, Limitation (local optima)
=== JAVASCRIPT (default.js) ===
Import: panic from '/_lib/panic_v3.js'
Pattern: IIFE, strict mode.
Constants: VERTICES_POLYGON = 6, VERTICES_TRIANGLE = 3
Target image generators (TARGETS object with draw(ctx, size) methods):
circle: dark bg (#1a1a2e) + red circle (#e94560, 30% radius)
shapes: dark bg + red circle + blue rect (#0f3460) + dark triangle (#16213e), all scaled by size/200
gradient: diagonal linearGradient from #e94560 through #0f3460 to #16213e
mondrian: white bg (#f5f5f5) + red (#e41a1c), blue (#377eb8), yellow (#ffff33) blocks
circles: dark bg + 5 random colored circles with shadow blur
face: dark bg + skin circle + white eyes with black pupils + red mouth arc
State: targetCanvas, targetCtx, evolvedCanvas, evolvedCtx, testCanvas (offscreen createElement),
polygons[], generation, bestFitness, currentSize=300, isRunning, animationId,
useTriangles=false, useAnnealing=false, temperature=1.0, speed=10, cachedColors
Polygon: {vertices: [{x,y}, ...], color: {r, g, b, a}}
Number of vertices: 3 (triangle mode) or 6 (polygon mode)
Hill climbing algorithm:
createRandomPolygon(size): random vertices in [0, size], random r/g/b [0-255], alpha [0.05-0.95]
mutatePolygon(polygon, size): deep clone, then one random mutation:
30% probability -> color mutation: pick random channel, gaussian noise +-25 (+-0.1 for alpha), clamp
40% probability -> vertex mutation: pick random vertex, add +-10px, clamp [0, size]
30% probability -> translation: add +-10px to ALL vertices, clamp
renderPolygons(ctx, polygons, size): clear canvas, draw each polygon as filled path (globalAlpha from color.a)
calculateFitness(canvas1, canvas2, size): getImageData on both, sum absolute pixel-by-pixel difference
across all 4 channels (RGBA), normalize: 1 - (totalDiff / (size*size*4*255))
evolveStep(): pick random polygon index, create mutant, render test, compare fitness:
- Normal: keep if fitness improved
- Annealing: keep if improved OR random < exp(-delta/temperature), temperature *= 0.999
Functions:
init(): get target-canvas + evolved-canvas, create offscreen testCanvas (same size),
bind all controls, generate initial target, reset
generateTarget(targetId): call TARGETS[targetId].draw(targetCtx, currentSize)
reset(): stop if running, generate target, create polygon-count random polygons,
render initial evolved, calculate bestFitness, update stats, reset temperature
toggleRun(): toggle isRunning, toggle .is-running on .image-controls container
run(): call evolveStep() `speed` times per frame, increment generation, updateStats, requestAnimationFrame
updateStats(): stat-generation, stat-similarity (bestFitness*100 toFixed(1) + "%"),
stat-polygons, fitness-bar.value = Math.round(bestFitness*100)
exportPNG(): create download link with evolvedCanvas.toDataURL('image/png')
Event bindings:
btn-start/btn-pause -> toggleRun, btn-reset -> reset, btn-export -> exportPNG
target-select -> generateTarget + reset
size-select -> resize all canvases + reset
polygon-count -> reset
speed -> update speed value
use-triangles -> toggle + reset (changes vertex count)
use-annealing -> toggle useAnnealing + reset temperature
Also exists: default-worker.js.disabled (Web Worker variant, not used)
=== SCSS (default.scss) ===
.canvas-pair: flex, gap 2rem, flex-wrap, justify-content center
.canvas-wrapper: flex column center, gap 0.5rem, margin 0
canvas: border 1px solid --draw-color-surface, border-radius 4px, bg --background-color-ground
figcaption: 0.875rem, color --text-color-surface
.image-controls: flex row, gap 0.5rem, margin-top 1rem
.is-start: display block; .is-pause: display none
&.is-running: .is-start none, .is-pause block
#fitness-bar: width 100%, height 0.5rem, margin-top 0.5rem
appearance none, border none, border-radius 0.25rem, bg --draw-color-surface
::-webkit-progress-bar: bg --draw-color-surface, radius
::-webkit-progress-value: bg --draw-color-primary, radius, transition width 100ms
::-moz-progress-bar: bg --draw-color-primary, radius
=== STATE MANAGEMENT ===
No localStorage. All state in JS variables.
Keyboard: None. Mouse: None on canvas.
Export: PNG download via canvas.toDataURL().
Page entièrement générée et maintenue par IA, sans intervention humaine.