about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorelioat <hi@eli.li>2024-03-13 10:22:15 -0400
committerelioat <hi@eli.li>2024-03-13 10:22:15 -0400
commit9e3d80a7dcb9530fefaee76643e3943570ac0d2d (patch)
tree4941b17f8c2d6b1c56f667e10f7ccfc6a6674717
parent2cf613dd027eccbfd5cb9cf0daabd6b6e2fa67f9 (diff)
downloadtour-9e3d80a7dcb9530fefaee76643e3943570ac0d2d.tar.gz
*
-rw-r--r--js/mandelbrot/index.html12
-rw-r--r--js/mandelbrot/mb.js65
2 files changed, 77 insertions, 0 deletions
diff --git a/js/mandelbrot/index.html b/js/mandelbrot/index.html
new file mode 100644
index 0000000..23ad2cb
--- /dev/null
+++ b/js/mandelbrot/index.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>Mandelbrot</title>
+</head>
+<body>
+    <canvas id="mandelbrot" width="800" height="800"></canvas>
+    <script src="mb.js"></script>
+</body>
+</html>
\ No newline at end of file
diff --git a/js/mandelbrot/mb.js b/js/mandelbrot/mb.js
new file mode 100644
index 0000000..27a19ea
--- /dev/null
+++ b/js/mandelbrot/mb.js
@@ -0,0 +1,65 @@
+function mandelIter(cx, cy, maxIter) {
+    let x = 0.0;
+    let y = 0.0;
+    let xx = 0;
+    let yy = 0;
+    let xy = 0;
+
+    let i = maxIter;
+    while (i-- && xx + yy <= 4) {
+        xy = x * y;
+        xx = x * x;
+        yy = y * y;
+        x = xx - yy + cx;
+        y = xy + xy + cy;
+    }
+    return maxIter - i;
+}
+
+function mandelbrot(canvas, xmin, xmax, ymin, ymax, iterations) {
+    const width = canvas.width;
+    const height = canvas.height;
+    const ctx = canvas.getContext('2d');
+    const img = ctx.getImageData(0, 0, width, height);
+    const pix = img.data;
+
+    const pixels = Array.from({ length: width * height }, (_, index) => {
+        const ix = index % width;
+        const iy = Math.floor(index / width);
+        const x = xmin + (xmax - xmin) * ix / (width - 1);
+        const y = ymin + (ymax - ymin) * iy / (height - 1);
+        const i = mandelIter(x, y, iterations);
+
+        if (i > iterations) {
+            return [0, 0, 0, 255];
+        } else {
+            const c = 3 * Math.log(i) / Math.log(iterations - 1.0);
+            if (c < 1) {
+                const shade = Math.floor(255 * c);
+                return [shade, shade, shade, 255];
+            } else if (c < 2) {
+                const shade = Math.floor(255 * (c - 1));
+                return [shade, shade, shade, 255];
+            } else {
+                const shade = Math.floor(255 * (c - 2));
+                return [shade, shade, shade, 255];
+            }
+        }
+    });
+
+    pixels.forEach(([r, g, b, a], index) => {
+        const ppos = 4 * index;
+        pix[ppos] = r;
+        pix[ppos + 1] = g;
+        pix[ppos + 2] = b;
+        pix[ppos + 3] = a;
+    });
+
+    ctx.putImageData(img, 0, 0);
+}
+
+const canvas = document.getElementById('mandelbrot');
+canvas.width = 900;
+canvas.height = 600;
+
+mandelbrot(canvas, -2, 1, -1, 1, 1000);