Sampling 2D distance field with union via smooth min (logsumexp)
Log in to post a comment.
const R = 45; const r1 = 11; const r2 = 4.5; const max_d = r1; const step = 0.2; const alpha = 0.2; Canvas.setpenopacity(-0.2); const t = new Turtle(); function minus(v1, v2) { return [v1[0] - v2[0], v1[1] - v2[1]]; } function length(v) { return Math.sqrt(v[0] * v[0] + v[1] * v[1]); } function df_circ(v, c, r) { return length(minus(v, c)) - r; } function smooth_max(a, b, alpha) { return Math.log(Math.exp(alpha * a) + Math.exp(alpha * b)) / alpha; } function smooth_min(a, b, alpha) { return -smooth_max(-a, -b, alpha) } const circles = []; const N = 6; for (let i = 0; i < N; i++) { let phi = Math.PI / 6 + 2 * Math.PI / N * i; let c1 = [[R * Math.cos(phi), R * Math.sin(phi)], r1]; let c2 = [[(R + r1 + 6 * r2) * Math.cos(phi), (R + r1 + 6 * r2) * Math.sin(phi)], r2]; circles.push(c1); circles.push(c2); } let x = -100; let y = -100; function walk(frame) { let p = [x, y]; let d = 400; for (let c of circles) { let dc = df_circ(p, c[0], c[1]); d = smooth_min(d, dc, alpha); } if (Math.abs(d) < max_d) { let s = step * (1 - d / max_d); t.seth(360 * Math.random()); for (let i = 0; i < 4; i++) { t.jump(x, y); t.forward(s); t.right(90); } } x += step; if (x > 100) { x = -100; y += step; } return y <= 100; }