FractalRain
Fractal ripples
Log in to post a comment.
// 1. Grid Resolution
const gridRes = 30; // min=10, max=60, step=1
// 2. Base Shape Size (How much of the cell to fill)
const baseSize = 0.9; // min=0.1, max=1.2, step=0.05
// 3. Polygon Sides (3=Triangle, 6=Hexagon, 20+=Circle)
const sides = 6; // min=3, max=10, step=1
// 4. Influence Radius (How far the "bloom" reaches)
const radiusScale = 75; // min=20, max=150, step=1
const turtle = new Turtle();
const depth = 3;
// Hand-placed spots: [x, y, weight]
// (0,0) is the big main center. The others are "scattered"
const centers = [
[0, 0, 1.2], // Main Center (Strongest)
[-45, 60, 0.7], // Upper Left-ish
[70, 20, 0.8], // Right-ish
[-20, -75, 0.6], // Bottom-ish
[55, -55, 0.7] // Bottom Right-ish
];
function walk(i) {
const col = i % gridRes;
const row = Math.floor(i / gridRes);
const cellSize = 200 / gridRes;
const x = (col * cellSize) - 100 + (cellSize / 2);
const y = (row * cellSize) - 100 + (cellSize / 2);
let maxInfluence = 0.05; // The "floor" (small dots in empty space)
centers.forEach(([cx, cy, weight]) => {
const d = Math.sqrt((x - cx)**2 + (y - cy)**2);
// Falloff logic
const influence = Math.max(0, (1 - d / radiusScale) * weight);
if (influence > maxInfluence) maxInfluence = influence;
});
// Final radius calculation using the baseSize slider
const radius = (cellSize / 2) * baseSize * maxInfluence;
if (radius > 0.2) {
drawFractal(x, y, radius, sides, depth);
}
return i < (gridRes * gridRes) - 1;
}
function drawFractal(x, y, radius, s, d) {
if (d <= 0 || radius < 0.5) return;
drawPolygon(x, y, radius, s);
drawFractal(x, y, radius * 0.6, s, d - 1); // 0.6 is the "shrink" factor
}
function drawPolygon(x, y, r, s) {
const res = s > 20 ? 30 : s;
turtle.penup();
for (let j = 0; j <= res; j++) {
const a = (j / res) * Math.PI * 2 - Math.PI / 2;
turtle.goto(x + Math.cos(a) * r, y + Math.sin(a) * r);
if (j === 0) turtle.pendown();
}
}