Base for the algo of
fxhash.xyz/generative/2881
DISK has been published December, 2021
Log in to post a comment.
// Forked from "Circle grid 🌕" by markknol // https://turtletoy.net/turtle/b7ad210a56 const turtle = new Turtle(); function fxrand() { return Math.random(); } function range(a,b) { return a + (b-a)*fxrand() } function pick(arr) { return arr[arr.length*fxrand()|0] } const dotFillRatio = range(2/3, 1.0); // min=0 max=1, step=0.001 const dotSize = 3; const dotGrid = pick([10,15,20,25]); const drawSize = 90; const discSizes = [drawSize/6, drawSize/5, drawSize/4]; const discInnerRatio = [1/3, 2/3] const discPositionType = 0 // min=0 max=1, step=1 (radial, grid) let discPositionRange = drawSize*2/3; const startAngle = pick([0,Math.PI * 0.5,Math.PI * 0.25]); const discs = []; let totalDiscs = discPositionType == 0 ? pick([2,3,4,5,6,7,8,9]) : pick([4,9]); // min=1 max=25, step=1 if (discPositionType == 0 && totalDiscs > 2 && fxrand() > 0.85) { // append disc to center totalDiscs --; discs.push([0, 0, pick(discSizes),pick(discInnerRatio)]); } let excluded = 0; for(let i=0;i<totalDiscs;i++) { if (discPositionType == 1 && excluded <= 2 && fxrand() > 2/3) { excluded ++; continue; } let disc; switch (discPositionType) { case 0: let t = i / totalDiscs; disc = [Math.sin(startAngle+t*Math.PI*2) * discPositionRange, Math.cos(startAngle+t*Math.PI*2) * discPositionRange]; break; case 1: let discGrid = totalDiscs == 4 ? 2 : 3; let discGridOffset = discGrid == 3 ? -0.5 : 0; if (discGrid == 2) discPositionRange = drawSize; disc = [-discPositionRange * 0.5 + (i%discGrid + discGridOffset) * discPositionRange, -discPositionRange * 0.5 + ((i/discGrid|0) + discGridOffset) * discPositionRange]; break; } disc[2] = pick(discSizes) disc[3] = pick(discInnerRatio); discs.push(disc); } function hits(pos) { for(let disc of discs) { if (dist(disc, pos) < disc[2]) { return true; } } return false; } function walk(i) { const gridX = (i % dotGrid) + 0.5; const gridY = (i / dotGrid | 0) + 0.5; const gridOffset = (drawSize * 2 / dotGrid); if (i === 0) { for (let disc of discs) { let decrease = pick([2,4,6,8]) // outer disk let dotDrawRadius = disc[2] - (dotSize * disc[3]); turtle.jump(disc[0], disc[1] - dotDrawRadius); turtle.circle(dotDrawRadius); // inner disc dotDrawRadius = disc[2] * disc[3]; turtle.jump(disc[0], disc[1] - dotDrawRadius); turtle.circle(dotDrawRadius); } } if (i != 0 && i != dotGrid - 1 && i != dotGrid * dotGrid - dotGrid && i != dotGrid * dotGrid - 1) { // "rounded corner" let closest = {disc: null, dist: 999999}; const dotPos = [-drawSize + gridX * gridOffset, -drawSize + gridY * gridOffset]; for (let disc of discs) { const d = dist(disc, dotPos); if (d < closest.dist) { closest.disc=disc; closest.dist=d; } } const closestDisc = closest.disc; const closestRadius = closestDisc[2]; const randomPosInDisc = add2(dotPos, [(fxrand() - closestDisc[3]) * closestRadius, (fxrand() - closestDisc[3]) * closestRadius]); const len = dist(randomPosInDisc, closestDisc); const posInInnerDisc = add2(closestDisc, scl2(sub2(randomPosInDisc, closestDisc), 1 / len * closestRadius)); if (!hits(dotPos)) { const shouldDraw = fxrand() < dotFillRatio; if (fxrand() < dotFillRatio) { const dotDrawRadius = closestDisc[3] * dotSize; turtle.jump(dotPos[0] , dotPos[1] - dotDrawRadius); turtle.circle(dotDrawRadius); turtle.jump(dotPos[0], dotPos[1]); turtle.goto(posInInnerDisc[0], posInInnerDisc[1]); } } } return i < dotGrid * dotGrid - 1; } // vec2 functions const scl2=(a,b)=>[a[0]*b,a[1]*b]; const add2=(a,b)=>[a[0]+b[0],a[1]+b[1]]; const sub2=(a,b)=>[a[0]-b[0],a[1]-b[1]]; const dist_sqr2=(a,b)=>(a[0]-b[0])*(a[0]-b[0])+(a[1]-b[1])*(a[1]-b[1]); const dist=(a,b)=>Math.sqrt(dist_sqr2(a,b));