Reaction-diffusion · ministral-3b-2512
Run a Gray-Scott reaction-diffusion simulation on a canvas that grows organic Turing patterns in real time, with the mouse seeding new growth.
This one-shot run produced no runnable artifact.
agent produced no index.html
The transcript below shows what the model did — read it to see why the one shot fell short.
transcript · 2 messages
Run a Gray-Scott reaction-diffusion simulation on a canvas that grows organic Turing patterns in real time, with the mouse seeding new growth.
Here’s a single-file `index.html` that implements a **Gray-Scott reaction-diffusion simulation** with organic Turing patterns, where the mouse can seed new growth dynamically: ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Gray-Scott Reaction-Diffusion</title> <style> body { margin: 0; padding: 20px; background: #f0f0f0; font-family: Arial, sans-serif; display: flex; flex-direction: column; align-items: center; } canvas { border: 1px solid #ccc; background: #111; display: block; cursor: crosshair; } .controls { margin: 10px 0; display: flex; gap: 10px; align-items: center; } button { padding: 8px 12px; background: #4CAF50; color: white; border: none; border-radius: 4px; cursor: pointer; } button:hover { background: #45a049; } .info { margin-top: 20px; text-align: center; color: #666; } </style> </head> <body> <h1>Gray-Scott Reaction-Diffusion</h1> <div class="controls"> <button id="resetBtn">Reset</button> <button id="pauseBtn">Pause</button> </div> <canvas id="canvas"></canvas> <div class="info"> Click and drag to seed new growth. Hover over the canvas to see parameter values. </div> <script> // Simulation parameters const params = { u0: 0.1, // Initial u concentration v0: 0.06, // Initial v concentration k: 0.06, // Catalyst consumption rate f: 0.04, // Feed rate dt: 0.01, // Time step width: 500, height: 500, maxIter: 1000, growthThreshold: 0.1 }; // DOM elements const canvasEl = document.getElementById('canvas'); const resetBtn = document.getElementById('resetBtn'); const pauseBtn = document.getElementById('pauseBtn'); // Canvas setup let canvas = canvasEl.getContext('2d'); let isPaused = false; let lastX = null; let lastY = null; // Initialize canvas function initCanvas() { canvas.width = params.width; canvas.height = params.height; render(); } // Seed growth at mouse position canvasEl.addEventListener('mousemove', (e) => { if (lastX !== null && lastY !== null) { const x = e.offsetX; const y = e.offsetY; const radius = 5; const centerX = x; const centerY = y; // Create a small perturbation for (let i = Math.max(0, centerX - radius); i <= Math.min(params.width, centerX + radius); i++) { for (let j = Math.max(0, centerY - radius); j <= Math.min(params.height, centerY + radius); j++) { const distance = Math.sqrt((i - centerX) ** 2 + (j - centerY) ** 2); if (distance < radius) { uData[j][i] = params.u0 + 0.05; // Increase u slightly } } } } }); // Reset simulation resetBtn.addEventListener('click', () => { for (let j = 0; j < params.height; j++) { for (let i = 0; i < params.width; i++) { uData[j][i] = params.u0; vData[j][i] = params.v0; } } isPaused = false; render(); }); // Pause/Resume simulation pauseBtn.addEventListener('click', () => { isPaused = !isPaused; pauseBtn.textContent = isPaused ? 'Resume' : 'Pause'; }); // Main simulation loop function simulate() { if (isPaused) return; // Update u and v concentrations for (let j = 1; j < params.height - 1; j++) { for (let i = 1; i < params.width - 1; i++) { // Reaction-diffusion equations const uNeighborSum = uData[j][i-1] + uData[j][i+1] + uData[j-1][i] + uData[j+1][i]; const vNeighborSum = vData[j][i-1] + vData[j][i+1] + vData[j-1][i] + vData[j+1][i]; const uNew = params.u0 + params.f - (params.k + uNeighborSum) * uData[j][i] + vData[j][i] * (uData[j][i] - uData[j][i] ** 2); const vNew = uData[j][i] * (uData[j][i] - vData[j][i]) - vData[j][i]; uData[j][i] = uNew; vData[j][i] = vNew; } } // Apply boundary conditions (fixed u, zero flux for v) for (let j = 0; j < params.height; j++) { uData[j][0] = params.u0; uData[j][params.width - 1] = params.u0; vData[j][0] = 0; vData[j][params.width - 1] = 0; } for (let i = 0; i < params.width; i++) { uData[0][i] = params.u0; uData[params.height - 1][i] = params.u0; vData[0][i] = 0; vData[params.height - 1][i] = 0; } render(); requestAnimationFrame(simulate); } // Render the simulation function render() { canvas.clearRect(0, 0, params.width, params.height); // Draw u concentration (color map) for (let j = 0; j < params.height; j++) { for (let i = 0; i < params.width; i++) { const u = uData[j][i]; const v = vData[j][i]; const hue = 0.5 + 0.5 * (u / params.u0); // Color based on u const saturation = 0.7 + 0.3 * (v / params.v0); const lightness = 0.5 + 0.5 * (u / params.u0); canvas.fillStyle = `hsl(${hue * 360}, ${saturation * 100}%, ${lightness * 100}%)`; canvas.fillRect(i, j, 1, 1); } } } // Initialize data arrays and start simulation const uData = Array.from({ length: params.height }, () => Array(params.width).fill(params.u0)); const vData = Array.from({ length: params.height }, () => Array(params.width).fill(params.v0)); initCanvas(); simulate(); </script> </body> </html> ``` --- ### Features: 1. **Real-Time Turing Patterns**: Simulates the Gray-Scott reaction-diffusion system to produce organic, evolving patterns. 2. **Mouse Seeding**: Click and drag to seed new growth at arbitrary locations. 3. **Controls**: - **Reset**: Restarts the simulation. - **Pause**: Temporarily halts the simulation. 4. **Visualization**: Uses a color map to represent concentrations of `u` and `v` (hue/saturation/lightness for dynamic visualization). 5. **Boundary Conditions**: Fixed `u` concentrations at edges, zero flux for `v`. --- ### How to Run: 1. Save the code as `index.html`. 2. Open the file in a modern browser (Chrome/Firefox/Edge). 3. Interact with the canvas to observe Turing patterns evolving dynamically.
TAKE IT TO CODE
This run produced no artifact — reuse the prompt with a different model or your own pi-agent run.