From 1eb458a6b66f9f199324464e141868cffd7a5074 Mon Sep 17 00:00:00 2001 From: TobiasMue91 Date: Sun, 1 Sep 2024 17:57:11 +0200 Subject: [PATCH] - add more color schemes and fractal types --- tools/fractal_viewer.html | 227 +++++++++++++++++++++++++++++++------- 1 file changed, 190 insertions(+), 37 deletions(-) diff --git a/tools/fractal_viewer.html b/tools/fractal_viewer.html index ca61497..be5e057 100644 --- a/tools/fractal_viewer.html +++ b/tools/fractal_viewer.html @@ -17,25 +17,37 @@
+ Type: + +
+ + + + + + +
4) return i; + x2 = x1; + y2 = y1; + x1 = xx; + y1 = yy; + } + return maxIter; + } + + function mandelbox3DSlice(x, y, maxIter) { + const scale = 2; + let zx = x, zy = y, zz = 0; + let c = 0; + for (let i = 0; i < maxIter; i++) { + zx = clamp(zx, -1, 1) * 2 - zx; + zy = clamp(zy, -1, 1) * 2 - zy; + zz = clamp(zz, -1, 1) * 2 - zz; + + const r = Math.sqrt(zx*zx + zy*zy + zz*zz); + if (r < 0.5) { + zx *= 4; zy *= 4; zz *= 4; + } else if (r < 1) { + zx /= r*r; zy /= r*r; zz /= r*r; + } + + zx = zx * scale + x; + zy = zy * scale + y; + zz = zz * scale; + + if (zx*zx + zy*zy + zz*zz > 4) return i; + c++; + } + return c; + } + + function clamp(x, min, max) { + return Math.min(Math.max(x, min), max); + } + + function newtonFractal(x, y, maxIter) { + let zx = x, zy = y; + for (let i = 0; i < maxIter; i++) { + const zx2 = zx * zx, zy2 = zy * zy; + const zx3 = zx2 * zx - 3 * zx * zy2; + const zy3 = 3 * zx2 * zy - zy2 * zy; + const mag = zx3 * zx3 + zy3 * zy3; + if (mag < 1e-6) return i; + const denom = 3 * (zx2 + zy2); + zx -= (zx3 + 1) / denom; + zy -= zy3 / denom; + } + return maxIter; + } + + function getColor(value, maxIter, scheme, type) { + if (type === 'lyapunov') { + // Lyapunov fractal uses a different coloring scheme + const hue = (value + 5) / 10; // Adjust this range as needed + return hsvToRgb(hue, 1, 1); + } + + if (value === maxIter) return [0, 0, 0]; + + const t = value / maxIter; switch (scheme) { - case'rainbow': + case 'rainbow': return hsvToRgb(t, 1, 1); - case'fire': + case 'fire': return hsvToRgb(t / 3, 1, Math.min(1, t * 2)); - case'ocean': + case 'ocean': return hsvToRgb(0.6 + t / 3, 1, Math.min(1, t * 2)); - case'psychedelic': + case 'psychedelic': return hsvToRgb(Math.sin(t * Math.PI), 1, 1); + case 'pastel': + return hsvToRgb(t, 0.5, 1); + case 'neon': + return hsvToRgb(t, 1, t < 0.5 ? 0.5 + t : 1); + case 'grayscale': + const gray = Math.floor(t * 255); + return [gray, gray, gray]; + case 'autumn': + return [ + Math.floor(255 * t), + Math.floor(128 * Math.sin(Math.PI * t)), + Math.floor(64 * (1 - t)) + ]; + case 'electric': + return hsvToRgb(0.6 + 0.4 * t, 1, t < 0.5 ? 2 * t : 1); + case 'cosmic': + return [ + Math.floor(128 * (1 + Math.sin(2 * Math.PI * t))), + Math.floor(128 * (1 + Math.sin(2 * Math.PI * t + 2 * Math.PI / 3))), + Math.floor(128 * (1 + Math.sin(2 * Math.PI * t + 4 * Math.PI / 3))) + ]; + case 'vintage': + return [ + Math.floor(255 * (0.5 + 0.5 * Math.sin(Math.PI * t))), + Math.floor(255 * (0.5 + 0.5 * Math.sin(Math.PI * t + Math.PI / 2))), + Math.floor(255 * (0.5 + 0.5 * Math.sin(Math.PI * t + Math.PI))) + ]; default: return hsvToRgb(t, 1, Math.sqrt(t)); } @@ -210,24 +375,12 @@ const q = v * (1 - f * s); const t = v * (1 - (1 - f) * s); switch (i % 6) { - case 0: - r = v, g = t, b = p; - break; - case 1: - r = q, g = v, b = p; - break; - case 2: - r = p, g = v, b = t; - break; - case 3: - r = p, g = q, b = v; - break; - case 4: - r = t, g = p, b = v; - break; - case 5: - r = v, g = p, b = q; - break; + case 0: r = v, g = t, b = p; break; + case 1: r = q, g = v, b = p; break; + case 2: r = p, g = v, b = t; break; + case 3: r = p, g = q, b = v; break; + case 4: r = t, g = p, b = v; break; + case 5: r = v, g = p, b = q; break; } return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)]; }