Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <!DOCTYPE html>
- <html>
- <head>
- <title>Gray-Scott Reaction-Diffusion Automaton</title>
- <style>
- body {
- margin: 0;
- padding: 0;
- }
- canvas {
- width: 100%;
- height: 100%;
- }
- </style>
- </head>
- <body>
- <canvas id="canvas"></canvas>
- <div id="controls">
- <label for="f-slider">f:</label>
- <input type="range" min="0" max="1" step="0.01" value="0.025" id="f-slider">
- <label for="k-slider">k:</label>
- <input type="range" min="0" max="1" step="0.01" value="0.06" id="k-slider">
- <button id="reset-button">Reset</button>
- </div>
- <script>
- const canvas = document.getElementById('canvas');
- const ctx = canvas.getContext('2d');
- const width = canvas.width;
- const height = canvas.height;
- const fSlider = document.getElementById('f-slider');
- const kSlider = document.getElementById('k-slider');
- const resetButton = document.getElementById('reset-button');
- let f = 0.025;
- let k = 0.06;
- let u = new Float32Array(width * height);
- let v = new Float32Array(width * height);
- for (let i = 0; i < width; i++) {
- for (let j = 0; j < height; j++) {
- const index = i + j * width;
- u[index] = 1;
- v[index] = 0;
- }
- }
- function update() {
- for (let i = 1; i < width - 1; i++) {
- for (let j = 1; j < height - 1; j++) {
- const index = i + j * width;
- const uc = u[index];
- const vc = v[index];
- const uNorth = u[index - width];
- const uSouth = u[index + width];
- const uEast = u[index + 1];
- const uWest = u[index - 1];
- const vNorth = v[index - width];
- const vSouth = v[index + width];
- const vEast = v[index + 1];
- const vWest = v[index - 1];
- const uDiff = uEast + uWest + uNorth + uSouth - 4 * uc;
- const vDiff = vEast + vWest + vNorth + vSouth - 4 * vc;
- u[index] += f * (uc - uc * uc - vc * uc) + uDiff;
- v[index] += f * (vc - uc * vc - vc * vc) + vDiff;
- }
- }
- function render() {
- for (let i = 0; i < width; i++) {
- for (let j = 0; j < height; j++) {
- const index = i + j * width;
- const uValue = u[index];
- const vValue = v[index];
- const r = Math.floor((uValue - vValue + 1) * 255 / 2);
- const g = Math.floor((uValue + vValue) * 255 / 2);
- const b = Math.floor((uValue + vValue + 1) * 255 / 2);
- ctx.fillStyle = `rgb(${r}, ${g}, ${b})`;
- ctx.fillRect(i, j, 1, 1);
- }
- }
- }
- function loop() {
- update();
- render();
- requestAnimationFrame(loop);
- }
- canvas.addEventListener('mousemove', (event) => {
- const x = event.offsetX;
- const y = event.offsetY;
- const index = x + y * width;
- u[index] = 1;
- v[index] = 0;
- });
- fSlider.addEventListener('input', (event) => {
- f = event.target.value;
- });
- kSlider.addEventListener('input', (event) => {
- k = event.target.value;
- });
- resetButton.addEventListener('click', () => {
- for (let i = 0; i < width; i++) {
- for (let j = 0; j < height; j++) {
- const index = i + j * width;
- u[index] = 1;
- v[index] = 0;
- }
- }
- });
- loop();
- </script>
- </body>
- </html>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement