Original code by: turtletoy.net/user/projectgrantwood
Packed in for a Good Wander
Log in to post a comment.
// Forked from "Fork:Packed in for a Good Wander" by rupertxrussell // https://turtletoy.net/turtle/f64f293b73 // Forked from "Packed in for a Good Wander" by ProjectGrantwood // https://turtletoy.net/turtle/04187a129d // Forked from "Beadpackpathwander" by ProjectGrantwood // https://turtletoy.net/turtle/5f76422d98 Canvas.setpenopacity(1); let Shrink = 0; //min=0, max=50, step=1 let ShrAdj = 0.03 //min=0, max=1, step=0.01 let A = -172 // min=-180, max=180, step=1 let AAdj = 0 //min=0, max=1, step=0.01 let B = 77 // min=-180, max=180, step=1 let BAdj = 0.36 //min=0, max=1, step=0.01 let Min = 0.23 // min=0.05, max=4, step=0.01 let Init = 31 // min=1, max=34, step=1 let Max = 0 //min=0, max=200, step=1 let n = 90000 //min=100, max=90000, step=100 Shrink = (100 - (Shrink + ShrAdj)) / 1000; Init = Min > Init ? Min : Init; const angleIncrement1 = (A + AAdj) * Math.PI / 180; const angleIncrement2 = (B + BAdj) * Math.PI / 180 const t = new Turtle(); const circleArray = [createCircle(0, 0, Init, -Math.PI * 2)]; let ratio = 0.9; let ratio2 = 0.999; const initialRatio = ratio; let currentCircle = circleArray[0]; let failures = 0; t.pd(); t.radians(); function walk(i){ for (let j = 0; j < 12; j++){ currentCircle = getAndCheck(currentCircle, circleArray); } return i < n; } function createCircle(x, y, rad, heading){ return [x, y, rad, heading]; } function checkCircles(c1, c2){ const xd = (c2[0] - c1[0]) ** 2; const yd = (c2[1] - c1[1]) ** 2; const dsq = xd + yd; return dsq >= (c1[2] + c2[2]) ** 2; } function draw(c, turtle, flags = '01'){ turtle.jmp(c[0], c[1] - c[2]); if (flags[0] === '1'){ turtle.circle(c[2]) } if (flags[1] === '1') { turtle.jmp(c[0], c[1]); turtle.seth(c[3] - Math.PI) let travelDistance = c[2]; travelDistance = c[2] === Min ? c[2] + c[2] + Min : c[2] + c[2] / ratio + Min turtle.forward(travelDistance) } } function getNextCircle(c){ let radiusOld = c[2]; let radiusNew = radiusOld * ratio radiusNew = radiusNew < Min ? Min : radiusNew let headingNew = c[3] += angleIncrement1 //* [-1, 1][Math.floor(Math.random() * 2)]; c[3] = headingNew; let d = ((radiusOld + radiusNew) + Min); let xOld = c[0]; let yOld = c[1]; let xNew = xOld + d * Math.cos(headingNew); let yNew = yOld + d * Math.sin(headingNew); return createCircle(xNew, yNew, radiusNew, headingNew); } function checkBounds(c){ let add = 1; add *= c[0] < 100 - c[2]; add *= c[0] > -100 + c[2]; add *= c[1] < 100 - c[2]; add *= c[1] > -100 + c[2]; return add; } function getAndCheck(c1, circleArray){ let c2 = getNextCircle(currentCircle); let add = 1; add *= checkBounds(c2); let newC; for (let c of circleArray){ if (!add){ break; } add *= checkCircles(c, c2); if (!add){ newC = c2; break; } } if (!add){ c1[3] += angleIncrement2 failures++; if (failures > Max){ failures = 0; c1[3] += angleIncrement2 //* [-1, 1][Math.floor(Math.random() * 2)]; ratio *= initialRatio + Shrink; radius = Init; let index = circleArray.indexOf(c1) - 1; index = index < 0 ? circleArray.length - 1 : index; //return circleArray[index]; return circleArray[Math.floor(Math.random() * circleArray.length)] } return currentCircle; } else { ratio /= initialRatio + Shrink; draw(c2, t); circleArray.push(c2); return c2; } }